diff --git a/.github/labeler.yml b/.github/labeler.yml index 866600b1d1a..b58bc4a81db 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -23,6 +23,10 @@ infrastructure: - 'packaging/**' - 'pyproject.toml' +datamodel: + - changed-files: + - any-glob-to-any-file: ['DataModel/**', '*/DataModel/**'] + dpg: - changed-files: - any-glob-to-any-file: ['DPG/**'] diff --git a/CODEOWNERS b/CODEOWNERS index ab99fb8e954..253fbdc4690 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -15,7 +15,7 @@ /Common/CCDB @alibuild @jgrosseo @iarsene @ekryshen @ddobrigk /Common/Tools/Multiplicity @alibuild @ddobrigk @victor-gonzalez /ALICE3 @alibuild @njacazio @hscheid -/DPG @alibuild @chiarazampolli @noferini +/DPG @alibuild @chiarazampolli @alcaliva @catalinristea /DPG/Tasks/AOTEvent @alibuild @ekryshen @strogolo @altsybee /DPG/Tasks/AOTTrack @alibuild @mfaggin @iouribelikov @njacazio /DPG/Tasks/TOF @alibuild @noferini @njacazio diff --git a/Common/Core/RecoDecay.h b/Common/Core/RecoDecay.h index ce2469e66e7..a8e4de1216f 100644 --- a/Common/Core/RecoDecay.h +++ b/Common/Core/RecoDecay.h @@ -1035,6 +1035,119 @@ struct RecoDecay { } return OriginType::None; } + + /// based on getCharmHardronOrigin in order to extend general particle + /// Finding the origin (from charm hadronisation or beauty-hadron decay) of paritcle (b, c and others) + /// \param particlesMC table with MC particles + /// \param particle MC particle + /// \param searchUpToQuark if true tag origin based on charm/beauty quark otherwise on the presence of a b-hadron or c-hadron + /// \param idxBhadMothers optional vector of b-hadron indices (might be more than one in case of searchUpToQuark in case of beauty resonances) + /// \return an integer corresponding to the origin (0: none(others), 1: charm, 2: beauty) as in OriginType + template + static int getParticleOrigin(const T& particlesMC, + const typename T::iterator& particle, + const bool searchUpToQuark = false, + std::vector* idxBhadMothers = nullptr) + { + int stage = 0; // mother tree level (just for debugging) + + // vector of vectors with mother indices; each line corresponds to a "stage" + std::vector> arrayIds{}; + std::vector initVec{particle.globalIndex()}; + arrayIds.push_back(initVec); // the first vector contains the index of the original particle + auto PDGParticle = std::abs(particle.pdgCode()); + bool couldBeCharm = false; + if (PDGParticle / 100 == 4 || PDGParticle / 1000 == 4) { + couldBeCharm = true; + } + while (arrayIds[-stage].size() > 0) { + // vector of mother indices for the current stage + std::vector arrayIdsStage{}; + for (auto& iPart : arrayIds[-stage]) { // check all the particles that were the mothers at the previous stage + auto particleMother = particlesMC.rawIteratorAt(iPart - particlesMC.offset()); + if (particleMother.has_mothers()) { + + // we break immediately if searchUpToQuark is false and the first mother is a parton (an hadron should never be the mother of a parton) + if (!searchUpToQuark) { + auto mother = particlesMC.rawIteratorAt(particleMother.mothersIds().front() - particlesMC.offset()); + auto PDGParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother + if (PDGParticleIMother < 9 || (PDGParticleIMother > 20 && PDGParticleIMother < 38)) { + auto PDGPaticle = std::abs(particleMother.pdgCode()); + if ( + (PDGParticleIMother / 100 == 5 || // b mesons + PDGParticleIMother / 1000 == 5) // b baryons + ) { + return OriginType::NonPrompt; // beauty + } + if ( + (PDGParticleIMother / 100 == 4 || // c mesons + PDGParticleIMother / 1000 == 4) // c baryons + ) { + return OriginType::Prompt; // charm + } + break; + } + } + + for (auto iMother = particleMother.mothersIds().front(); iMother <= particleMother.mothersIds().back(); ++iMother) { // loop over the mother particles of the analysed particle + if (std::find(arrayIdsStage.begin(), arrayIdsStage.end(), iMother) != arrayIdsStage.end()) { // if a mother is still present in the vector, do not check it again + continue; + } + auto mother = particlesMC.rawIteratorAt(iMother - particlesMC.offset()); + // Check status code + auto motherStatusCode = std::abs(mother.getGenStatusCode()); + auto PDGParticleIMother = std::abs(mother.pdgCode()); // PDG code of the mother + // Check mother's PDG code. + // printf("getMother: "); + // for (int i = stage; i < 0; i++) // Indent to make the tree look nice. + // printf(" "); + // printf("Stage %d: Mother PDG: %d, status: %d, Index: %d\n", stage, PDGParticleIMother, motherStatusCode, iMother); + + if (searchUpToQuark) { + if (idxBhadMothers) { + if (PDGParticleIMother / 100 == 5 || // b mesons + PDGParticleIMother / 1000 == 5) // b baryons + { + idxBhadMothers->push_back(iMother); + } + } + if (PDGParticleIMother == 5) { // b quark + return OriginType::NonPrompt; // beauty + } + if (PDGParticleIMother == 4) { // c quark + return OriginType::Prompt; // charm + } + } else { + if ( + (PDGParticleIMother / 100 == 5 || // b mesons + PDGParticleIMother / 1000 == 5) // b baryons + ) { + if (idxBhadMothers) { + idxBhadMothers->push_back(iMother); + } + return OriginType::NonPrompt; // beauty + } + if ( + (PDGParticleIMother / 100 == 4 || // c mesons + PDGParticleIMother / 1000 == 4) // c baryons + ) { + couldBeCharm = true; + } + } + // add mother index in the vector for the current stage + arrayIdsStage.push_back(iMother); + } + } + } + // add vector of mother indices for the current stage + arrayIds.push_back(arrayIdsStage); + stage--; + } + if (couldBeCharm) { + return OriginType::Prompt; // charm + } + return OriginType::None; + } }; /// Calculations using (pT, η, φ) coordinates, aka (transverse momentum, pseudorapidity, azimuth) diff --git a/Common/DataModel/PIDResponseITS.h b/Common/DataModel/PIDResponseITS.h index ab95018c708..44c029fcb75 100644 --- a/Common/DataModel/PIDResponseITS.h +++ b/Common/DataModel/PIDResponseITS.h @@ -14,6 +14,7 @@ /// \since 2024-11-12 /// \author Nicolò Jacazio nicolo.jacazio@cern.ch /// \author Francesco Mazzaschi francesco.mazzaschi@cern.ch +/// \author Giorgio Alberto Lucia giorgio.alberto.lucia@cern.ch /// \brief Set of tables, tasks and utilities to provide the interface between /// the analysis data model and the PID response of the ITS /// @@ -54,19 +55,33 @@ struct ITSResponse { static constexpr float inverseMass = 1. / o2::track::pid_constants::sMasses[id]; static constexpr float charge = static_cast(o2::track::pid_constants::sCharges[id]); const float bg = momentum * inverseMass; - return (mITSRespParams[0] / (std::pow(bg, mITSRespParams[1])) + mITSRespParams[2]) * std::pow(charge, mChargeFactor); + if (id == o2::track::PID::Helium3 || id == o2::track::PID::Alpha) { + return (mITSRespParamsZ2[0] / (std::pow(bg, mITSRespParamsZ2[1])) + mITSRespParamsZ2[2]); + } + return (mITSRespParams[0] / (std::pow(bg, mITSRespParams[1])) + mITSRespParams[2]); + } + + template + static float expResolution(const float momentum) + { + static constexpr float inverseMass = 1. / o2::track::pid_constants::sMasses[id]; + static constexpr float charge = static_cast(o2::track::pid_constants::sCharges[id]); + const float bg = momentum * inverseMass; + float relRes = mResolutionParams[0] * std::erf((bg - mResolutionParams[1]) / mResolutionParams[2]); + return relRes; } template - static float nSigmaITS(uint32_t itsClusterSizes, float momentum) + static float nSigmaITS(uint32_t itsClusterSizes, float momentum, float eta) { const float exp = expSignal(momentum); const float average = averageClusterSize(itsClusterSizes); - const float resolution = mResolution * exp; - return (average - exp) / resolution; + const float coslInv = 1. / std::cosh(eta); + const float resolution = expResolution(momentum) * exp; + return (average * coslInv - exp) / resolution; }; - static void setParameters(float p0, float p1, float p2, float chargeFactor, float resolution) + static void setParameters(float p0, float p1, float p2, float p0_Z2, float p1_Z2, float p2_Z2, float p0_res, float p1_res, float p2_res) { if (mIsInitialized) { LOG(fatal) << "ITSResponse parameters already initialized"; @@ -75,79 +90,84 @@ struct ITSResponse { mITSRespParams[0] = p0; mITSRespParams[1] = p1; mITSRespParams[2] = p2; - mChargeFactor = chargeFactor; - mResolution = resolution; + mITSRespParamsZ2[0] = p0_Z2; + mITSRespParamsZ2[1] = p1_Z2; + mITSRespParamsZ2[2] = p2_Z2; + mResolutionParams[0] = p0_res; + mResolutionParams[1] = p1_res; + mResolutionParams[2] = p2_res; } private: static std::array mITSRespParams; - static float mChargeFactor; - static float mResolution; + static std::array mITSRespParamsZ2; + static std::array mResolutionParams; static bool mIsInitialized; }; -std::array ITSResponse::mITSRespParams = {0.903, 2.014, 2.440}; -float ITSResponse::mChargeFactor = 2.299999952316284f; -float ITSResponse::mResolution = 0.15f; +std::array ITSResponse::mITSRespParams = {1.1576, 1.684, 1.9453}; +std::array ITSResponse::mITSRespParamsZ2 = {2.8752, 1.1246, 5.0259}; +// relative resolution is modelled with an erf function: [0]*TMath::Erf((x-[1])/[2]) +std::array ITSResponse::mResolutionParams = {0.2431, -0.3293, 1.533}; bool ITSResponse::mIsInitialized = false; namespace pidits { DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaElImp, itsNSigmaEl, //! Nsigma separation with the ITS detector for electrons - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaMuImp, itsNSigmaMu, //! Nsigma separation with the ITS detector for muons - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaPiImp, itsNSigmaPi, //! Nsigma separation with the ITS detector for pions - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaKaImp, itsNSigmaKa, //! Nsigma separation with the ITS detector for kaons - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaPrImp, itsNSigmaPr, //! Nsigma separation with the ITS detector for protons - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaDeImp, itsNSigmaDe, //! Nsigma separation with the ITS detector for deuterons - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaTrImp, itsNSigmaTr, //! Nsigma separation with the ITS detector for tritons - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaHeImp, itsNSigmaHe, //! Nsigma separation with the ITS detector for helium3 - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); DECLARE_SOA_DYNAMIC_COLUMN(ITSNSigmaAlImp, itsNSigmaAl, //! Nsigma separation with the ITS detector for alphas - [](uint32_t itsClusterSizes, float momentum) -> float { - return ITSResponse::nSigmaITS(itsClusterSizes, momentum); + [](uint32_t itsClusterSizes, float momentum, float eta) -> float { + return ITSResponse::nSigmaITS(itsClusterSizes, momentum, eta); }); // Define user friendly names for the columns to join with the tracks -using ITSNSigmaEl = ITSNSigmaElImp; -using ITSNSigmaMu = ITSNSigmaMuImp; -using ITSNSigmaPi = ITSNSigmaPiImp; -using ITSNSigmaKa = ITSNSigmaKaImp; -using ITSNSigmaPr = ITSNSigmaPrImp; -using ITSNSigmaDe = ITSNSigmaDeImp; -using ITSNSigmaTr = ITSNSigmaTrImp; -using ITSNSigmaHe = ITSNSigmaHeImp; -using ITSNSigmaAl = ITSNSigmaAlImp; +using ITSNSigmaEl = ITSNSigmaElImp; +using ITSNSigmaMu = ITSNSigmaMuImp; +using ITSNSigmaPi = ITSNSigmaPiImp; +using ITSNSigmaKa = ITSNSigmaKaImp; +using ITSNSigmaPr = ITSNSigmaPrImp; +using ITSNSigmaDe = ITSNSigmaDeImp; +using ITSNSigmaTr = ITSNSigmaTrImp; +using ITSNSigmaHe = ITSNSigmaHeImp; +using ITSNSigmaAl = ITSNSigmaAlImp; } // namespace pidits } // namespace o2::aod diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt index 7e9ca8dea40..91513029f73 100644 --- a/Common/TableProducer/CMakeLists.txt +++ b/Common/TableProducer/CMakeLists.txt @@ -129,3 +129,8 @@ o2physics_add_dpl_workflow(ese-table-producer SOURCES eseTableProducer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(mftmch-matching-data + SOURCES match-mft-mch-data.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) diff --git a/Common/TableProducer/PID/pidITS.cxx b/Common/TableProducer/PID/pidITS.cxx index 225108528bf..58ac57984fe 100644 --- a/Common/TableProducer/PID/pidITS.cxx +++ b/Common/TableProducer/PID/pidITS.cxx @@ -14,6 +14,7 @@ /// \since 2024-11-12 /// \author Nicolò Jacazio nicolo.jacazio@cern.ch /// \author Francesco Mazzaschi francesco.mazzaschi@cern.ch +/// \author Giorgio Alberto Lucia giorgio.alberto.lucia@cern.ch /// \brief Task to produce PID tables for ITS split for each particle. /// Only the tables for the mass hypotheses requested are filled, the others are sent empty. /// @@ -42,14 +43,21 @@ using namespace o2::track; MetadataHelper metadataInfo; static constexpr int nCases = 2; -static constexpr int nParameters = 5; +static constexpr int nParameters = 9; static const std::vector casesNames{"Data", "MC"}; -static const std::vector parameterNames{"bb1", "bb2", "bb3", "Charge exponent", "Resolution"}; -static constexpr float defaultParameters[nCases][nParameters]{{0.903, 2.014, 2.440, 2.299999952316284f, 0.15f}, - {0.903, 2.014, 2.440, 2.299999952316284f, 0.15f}}; +static const std::vector parameterNames{"RespITSPar1", "RespITSPar2", "RespITSPar3", + "RespITSPar1_Z2", "RespITSPar2_Z2", "RespITSPar3_Z2", + "ResolutionPar1", "ResolutionPar2", "ResolutionPar3"}; +static constexpr float defaultParameters[nCases][nParameters]{{0.903, 2.014, 2.440, + 2.8752, 1.1246, 5.0259, + 0.2431, -0.3293, 1.533}, + {0.903, 2.014, 2.440, + 2.8752, 1.1246, 5.0259, + 0.2431, -0.3293, 1.533}}; /// Task to produce the ITS PID information for each particle species -/// The parametrization is: [p0/(bg)**p1 + p2] * pow(q, p3), being bg = p/m and q the charge +/// The parametrization is: [p0/(bg)**p1 + p2] being bg = p/m. Different parametrizations are used for He3 and Alpha particles. +/// The resolution depends on the bg and is modelled with an erf function: p0*TMath::Erf((bg-p1)/p2) struct itsPid { Configurable> itsParams{"itsParams", @@ -74,11 +82,15 @@ struct itsPid { LOG(fatal) << "Not implemented yet"; } else { const char* key = metadataInfo.isMC() ? "MC" : "Data"; - o2::aod::ITSResponse::setParameters(itsParams->get(key, "bb1"), - itsParams->get(key, "bb2"), - itsParams->get(key, "bb3"), - itsParams->get(key, "Charge exponent"), - itsParams->get(key, "Resolution")); + o2::aod::ITSResponse::setParameters(itsParams->get(key, "RespITSPar1"), + itsParams->get(key, "RespITSPar2"), + itsParams->get(key, "RespITSPar3"), + itsParams->get(key, "RespITSPar1_Z2"), + itsParams->get(key, "RespITSPar2_Z2"), + itsParams->get(key, "RespITSPar3_Z2"), + itsParams->get(key, "ResolutionPar1"), + itsParams->get(key, "ResolutionPar2"), + itsParams->get(key, "ResolutionPar3")); } } diff --git a/Common/TableProducer/match-mft-mch-data.cxx b/Common/TableProducer/match-mft-mch-data.cxx new file mode 100644 index 00000000000..affa18f325d --- /dev/null +++ b/Common/TableProducer/match-mft-mch-data.cxx @@ -0,0 +1,886 @@ +// 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 +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" +#include "CCDB/BasicCCDBManager.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/MftmchMatchingML.h" +#include "Common/Core/trackUtilities.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "DetectorsVertexing/VertexTrackMatcher.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" +#include "ReconstructionDataFormats/VtxTrackIndex.h" +#include "ReconstructionDataFormats/VtxTrackRef.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "CommonDataFormat/InteractionRecord.h" +#include "DetectorsVertexing/PVertexerParams.h" +#include "MathUtils/Primitive2D.h" +#include "DataFormatsGlobalTracking/RecoContainer.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/MatchMFTFT0.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Field/MagneticField.h" +#include "TGeoGlobalMagField.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "EventFiltering/Zorro.h" +#include "ReconstructionDataFormats/TrackFwd.h" +#include "Math/MatrixFunctions.h" +#include "Math/SMatrix.h" +#include "MFTTracking/Tracker.h" +#include "MCHTracking/TrackParam.h" +#include "MCHTracking/TrackExtrap.h" +#include "GlobalTracking/MatchGlobalFwd.h" +#include +#include +#include "TDatabasePDG.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using SMatrix55 = ROOT::Math::SMatrix>; +using SMatrix5 = ROOT::Math::SVector; + +// using MyEvents = soa::Join; +// using MyEventsWithMults = soa::Join; +// using MyEventsWithFilter = soa::Join; +// using MyEventsWithMultsAndFilter = soa::Join; +// using MyEventsWithCent = soa::Join; +// using MyEventsWithCentAndMults = soa::Join; +using MyMuons = soa::Join; +using MyMFTs = aod::MFTTracks; +// using MyMuonsWithCov = soa::Join; +// using MyMuonsColl = soa::Join; +// using MyMuonsCollWithCov = soa::Join; +using MyBCs = soa::Join; +using ExtBCs = soa::Join; + +float mMu = TDatabasePDG::Instance()->GetParticle(13)->Mass(); + +TRandom* rnd = new TRandom(); + +TLorentzVector muon1LV; +TLorentzVector muon2LV; +TLorentzVector dimuonLV; + +TVector3 V1; +TVector3 V2; + +namespace o2::aod +{ + +namespace muon_params +{ +DECLARE_SOA_COLUMN(TRACKCHI2, trackChi2, float); +DECLARE_SOA_COLUMN(RABS, rabs, float); +DECLARE_SOA_COLUMN(Q, q, int16_t); + +DECLARE_SOA_COLUMN(PT, pt, float); +DECLARE_SOA_COLUMN(ETA, eta, float); +DECLARE_SOA_COLUMN(PHI, phi, float); + +DECLARE_SOA_COLUMN(PT_AT_PV, pt_pv, float); +DECLARE_SOA_COLUMN(ETA_AT_PV, eta_pv, float); +DECLARE_SOA_COLUMN(PHI_AT_PV, phi_pv, float); + +DECLARE_SOA_COLUMN(PT_AT_DCA, pt_dca, float); +DECLARE_SOA_COLUMN(ETA_AT_DCA, eta_dca, float); +DECLARE_SOA_COLUMN(PHI_AT_DCA, phi_dca, float); +DECLARE_SOA_COLUMN(DCA, dca, float); + +DECLARE_SOA_COLUMN(HASMFT, has_mft, bool); +} // namespace muon_params + +DECLARE_SOA_TABLE(MUONParams, "AOD", "MUON", + muon_params::TRACKCHI2, + muon_params::RABS, + muon_params::Q, + muon_params::PT, + muon_params::ETA, + muon_params::PHI, + muon_params::PT_AT_PV, + muon_params::ETA_AT_PV, + muon_params::PHI_AT_PV, + muon_params::PT_AT_DCA, + muon_params::ETA_AT_DCA, + muon_params::PHI_AT_DCA, + muon_params::DCA, + muon_params::HASMFT); + +namespace mft_params +{ +DECLARE_SOA_COLUMN(NCLUST, nclust, int); +DECLARE_SOA_COLUMN(ISCA, isCA, bool); +DECLARE_SOA_COLUMN(TRACKCHI2, trackChi2, float); +DECLARE_SOA_COLUMN(Q, q, int16_t); +DECLARE_SOA_COLUMN(PT, pt, float); +DECLARE_SOA_COLUMN(ETA, eta, float); +DECLARE_SOA_COLUMN(PHI, phi, float); +DECLARE_SOA_COLUMN(PT_AT_DCA, pt_dca, float); +DECLARE_SOA_COLUMN(ETA_AT_DCA, eta_dca, float); +DECLARE_SOA_COLUMN(PHI_AT_DCA, phi_dca, float); +DECLARE_SOA_COLUMN(DCA, dca, float); +DECLARE_SOA_COLUMN(DCAx, dcax, float); +DECLARE_SOA_COLUMN(DCAy, dcay, float); +} // namespace mft_params + +DECLARE_SOA_TABLE(MFTParams, "AOD", "MFT", + mft_params::NCLUST, + mft_params::ISCA, + mft_params::TRACKCHI2, + mft_params::Q, + mft_params::PT, + mft_params::ETA, + mft_params::PHI, + mft_params::PT_AT_DCA, + mft_params::ETA_AT_DCA, + mft_params::PHI_AT_DCA, + mft_params::DCAx, + mft_params::DCAy, + mft_params::DCA); + +namespace matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); +DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); + +DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); +DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); +DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); +DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); + +DECLARE_SOA_COLUMN(MchPt, mchpt, float); +DECLARE_SOA_COLUMN(MchEta, mcheta, float); +DECLARE_SOA_COLUMN(MchPhi, mchphi, float); +DECLARE_SOA_COLUMN(MchQ, mchq, float); + +DECLARE_SOA_COLUMN(MftPt, mftpt, float); +DECLARE_SOA_COLUMN(MftEta, mfteta, float); +DECLARE_SOA_COLUMN(MftPhi, mftphi, float); +DECLARE_SOA_COLUMN(MftQ, mftq, float); + +DECLARE_SOA_COLUMN(MftDCA, mftdca, float); + +} // namespace matching_params + +DECLARE_SOA_TABLE(MatchParams, "AOD", "MATCHING", + matching_params::NClustMFTTracks, + matching_params::Chi2MFTTracks, + matching_params::DeltaP, + matching_params::DeltaPt, + matching_params::DeltaEta, + matching_params::DeltaPhi, + matching_params::DeltaX, + matching_params::DeltaY, + matching_params::MchPt, + matching_params::MchEta, + matching_params::MchPhi, + matching_params::MchQ, + matching_params::MftPt, + matching_params::MftEta, + matching_params::MftPhi, + matching_params::MftQ, + matching_params::MftDCA); + +namespace mix_matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); +DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); + +DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); +DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); +DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); +DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); + +DECLARE_SOA_COLUMN(MchPt, mchpt, float); +DECLARE_SOA_COLUMN(MchEta, mcheta, float); +DECLARE_SOA_COLUMN(MchPhi, mchphi, float); +DECLARE_SOA_COLUMN(MchQ, mchq, float); + +DECLARE_SOA_COLUMN(MftPt, mftpt, float); +DECLARE_SOA_COLUMN(MftEta, mfteta, float); +DECLARE_SOA_COLUMN(MftPhi, mftphi, float); +DECLARE_SOA_COLUMN(MftQ, mftq, float); +DECLARE_SOA_COLUMN(MftDCA, mftdca, float); +} // namespace mix_matching_params + +namespace tag_matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); +DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); + +DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); +DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); +DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); +DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); + +DECLARE_SOA_COLUMN(MchPt, mchpt, float); +DECLARE_SOA_COLUMN(MchEta, mcheta, float); +DECLARE_SOA_COLUMN(MchPhi, mchphi, float); +DECLARE_SOA_COLUMN(MchQ, mchq, float); + +DECLARE_SOA_COLUMN(MftPt, mftpt, float); +DECLARE_SOA_COLUMN(MftEta, mfteta, float); +DECLARE_SOA_COLUMN(MftPhi, mftphi, float); +DECLARE_SOA_COLUMN(MftQ, mftq, float); +DECLARE_SOA_COLUMN(MftDCA, mftdca, float); + +DECLARE_SOA_COLUMN(IsTaged, isTaged, bool); +} // namespace tag_matching_params + +DECLARE_SOA_TABLE(TagMatchParams, "AOD", "TAGMATCHING", + tag_matching_params::NClustMFTTracks, + tag_matching_params::Chi2MFTTracks, + tag_matching_params::DeltaP, + tag_matching_params::DeltaPt, + tag_matching_params::DeltaEta, + tag_matching_params::DeltaPhi, + tag_matching_params::DeltaX, + tag_matching_params::DeltaY, + tag_matching_params::MchPt, + tag_matching_params::MchEta, + tag_matching_params::MchPhi, + tag_matching_params::MchQ, + tag_matching_params::MftPt, + tag_matching_params::MftEta, + tag_matching_params::MftPhi, + tag_matching_params::MftQ, + tag_matching_params::MftDCA, + tag_matching_params::IsTaged); + +namespace probe_matching_params +{ +// matching parameters +DECLARE_SOA_COLUMN(NMFTCandTagMuon, nTagMFT, int); +DECLARE_SOA_COLUMN(TagMuonP, tagmuonp, float); + +DECLARE_SOA_COLUMN(NClustMFTTracks, nClustMFT, int); +DECLARE_SOA_COLUMN(Chi2MFTTracks, chi2MFT, float); + +DECLARE_SOA_COLUMN(DeltaP, dp_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPt, dpt_mchplane, float); +DECLARE_SOA_COLUMN(DeltaEta, deta_mchplane, float); +DECLARE_SOA_COLUMN(DeltaPhi, dphi_mchplane, float); +DECLARE_SOA_COLUMN(DeltaX, dx_mchplane, float); +DECLARE_SOA_COLUMN(DeltaY, dy_mchplane, float); + +DECLARE_SOA_COLUMN(MchPt, mchpt, float); +DECLARE_SOA_COLUMN(MchEta, mcheta, float); +DECLARE_SOA_COLUMN(MchPhi, mchphi, float); +DECLARE_SOA_COLUMN(MchQ, mchq, float); + +DECLARE_SOA_COLUMN(MftPt, mftpt, float); +DECLARE_SOA_COLUMN(MftEta, mfteta, float); +DECLARE_SOA_COLUMN(MftPhi, mftphi, float); +DECLARE_SOA_COLUMN(MftQ, mftq, float); +DECLARE_SOA_COLUMN(MftDCA, mftdca, float); +} // namespace probe_matching_params + +DECLARE_SOA_TABLE(ProbeMatchParams, "AOD", "PROBEMATCHING", + probe_matching_params::NMFTCandTagMuon, + probe_matching_params::TagMuonP, + probe_matching_params::NClustMFTTracks, + probe_matching_params::Chi2MFTTracks, + probe_matching_params::DeltaP, + probe_matching_params::DeltaPt, + probe_matching_params::DeltaEta, + probe_matching_params::DeltaPhi, + probe_matching_params::DeltaX, + probe_matching_params::DeltaY, + probe_matching_params::MchPt, + probe_matching_params::MchEta, + probe_matching_params::MchPhi, + probe_matching_params::MchQ, + probe_matching_params::MftPt, + probe_matching_params::MftEta, + probe_matching_params::MftPhi, + probe_matching_params::MftQ, + probe_matching_params::MftDCA); + +DECLARE_SOA_TABLE(MixMatchParams, "AOD", "MIXMATCHING", + mix_matching_params::NClustMFTTracks, + mix_matching_params::Chi2MFTTracks, + mix_matching_params::DeltaP, + mix_matching_params::DeltaPt, + mix_matching_params::DeltaEta, + mix_matching_params::DeltaPhi, + mix_matching_params::DeltaX, + mix_matching_params::DeltaY, + mix_matching_params::MchPt, + mix_matching_params::MchEta, + mix_matching_params::MchPhi, + mix_matching_params::MchQ, + mix_matching_params::MftPt, + mix_matching_params::MftEta, + mix_matching_params::MftPhi, + mix_matching_params::MftQ, + mix_matching_params::MftDCA); + +namespace muon_pair +{ +DECLARE_SOA_COLUMN(NMFT, nMft, int); +DECLARE_SOA_COLUMN(Q, q, int16_t); +DECLARE_SOA_COLUMN(M, m, float); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Rap, rap, float); +} // namespace muon_pair + +DECLARE_SOA_TABLE(MuonPair, "AOD", "DIMUON", muon_pair::NMFT, muon_pair::Q, muon_pair::M, muon_pair::Pt, muon_pair::Rap); + +namespace tag_muon_pair +{ +DECLARE_SOA_COLUMN(NMFT, nMft, int); +DECLARE_SOA_COLUMN(Q, q, int16_t); +DECLARE_SOA_COLUMN(M, m, float); +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Rap, rap, float); +} // namespace tag_muon_pair + +DECLARE_SOA_TABLE(TagMuonPair, "AOD", "TAGDIMUON", tag_muon_pair::NMFT, tag_muon_pair::Q, tag_muon_pair::M, tag_muon_pair::Pt, tag_muon_pair::Rap); + +} // namespace o2::aod + +struct match_mft_mch_data { + + Produces matchingParams; + Produces tagmatchingParams; + Produces probematchingParams; + Produces mixmatchingParams; + Produces muonPairs; + Produces tagmuonPairs; + Produces muonParams; + Produces mftParams; + + HistogramRegistry registry{ + "registry", + {{"hMchP", "MCH track total momentum (at the first station); p [GeV/c]; Counts", {HistType::kTH1F, {{2000, 0, 200}}}}, + {"hMchCorrP", "MCH track total momentum (propagated to PV); p [GeV/c]; Counts", {HistType::kTH1F, {{2000, 0, 200}}}}, + {"hMassCorrMchPair", "Corrected MCH track pair mass (propagated to PV); m [GeV/c^{2}]; Counts", {HistType::kTH1F, {{1000, 0, 10}}}}}}; + + Configurable fEtaMchLow{"cfgEtaMchLow", -4.0f, ""}; + Configurable fEtaMchUp{"cfgEtaMchUp", -2.5f, ""}; + Configurable fEtaMftLow{"cfgEtaMftlow", -3.6f, ""}; + Configurable fEtaMftUp{"cfgEtaMftup", -2.5f, ""}; + // Filter etaMchFilter = (fEtaMchLow < aod::fwdtrack::eta) && (aod::fwdtrack::eta < fEtaMchUp); + + Configurable fRabsLow1{"cfgRabsLow1", 17.6f, ""}; + Configurable fRabsUp1{"cfgRabsUp1", 26.5f, ""}; + Configurable fRabsLow2{"cfgRabsLow2", 26.5f, ""}; + Configurable fRabsUp2{"cfgRabsUp2", 89.5f, ""}; + Configurable fPdcaUp1{"cfgPdcaUp1", 594.f, ""}; + Configurable fPdcaUp2{"cfgPdcaUp2", 324.f, ""}; + // Filter rAbsFilter = (fRabsLow1 < aod::fwdtrack::rAtAbsorberEnd && aod::fwdtrack::rAtAbsorberEnd < fRabsUp1 && aod::fwdtrack::pDca < fPdcaUp1) || (fRabsLow2 < aod::fwdtrack::rAtAbsorberEnd && aod::fwdtrack::rAtAbsorberEnd < fRabsUp2 && aod::fwdtrack::pDca < fPdcaUp2); + + Configurable fTrackChi2MchUp{"cfgTrackChi2MchUp", 5.f, ""}; + // Filter trackChi2MchFilter = aod::fwdtrack::chi2 < fTrackChi2MchUp; + + Configurable fMatchingChi2MchMidUp{"cfgMatchingChi2MchMidUp", 999.f, ""}; + // Filter matchingChi2MchMidFilter = aod::fwdtrack::chi2MatchMCHMID < fMatchingChi2MchMidUp; + + // Configurable fSaveMixedMatchingParamsRate{"cfgSaveMixedMatchingParamsRate", 0.002f, ""}; + + Configurable fPreselectMatchingX{"cfgPreselectMatchingX", 999.f, ""}; + Configurable fPreselectMatchingY{"cfgPreselectMatchingY", 999.f, ""}; + + Configurable fTagMassWindowMin{"cfgTagMassWindowMin", 2.8f, ""}; + Configurable fTagMassWindowMax{"cfgTagMassWindowMax", 3.3f, ""}; + + Configurable fEventMaxDeltaNMFT{"cfgEventMaxDeltaNMFT", 1, ""}; + Configurable fEventMaxDeltaVtxZ{"cfgEventMaxDeltaVtxZ", 1.f, ""}; + + Configurable fTagRWindow{"cfgTagRWindow", 3.f, ""}; + Configurable fTagPhiWindow{"cfgTagPhiWindow", 0.1f, ""}; + Configurable fTagEtaWindow{"cfgTagEtaWindow", 0.1f, ""}; + + Service ccdb; + 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 geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + + // o2::parameters::GRPMagField* grpmag = nullptr; + o2::globaltracking::MatchGlobalFwd mMatching; + o2::field::MagneticField* fieldB; + + o2::ccdb::CcdbApi ccdbApi; + int mRunNumber; + + void init(o2::framework::InitContext&) + { + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + ccdbApi.init(ccdburl); + mRunNumber = 0; + } + + void initCCDB(ExtBCs::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + mRunNumber = bc.runNumber(); + std::map metadata; + auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, mRunNumber); + auto ts = soreor.first; + auto grpmag = ccdbApi.retrieveFromTFileAny(grpmagPath, metadata, ts); + o2::base::Propagator::initFieldFromGRP(grpmag); + if (!o2::base::GeometryManager::isGeometryLoaded()) { + ccdb->get(geoPath); + } + o2::mch::TrackExtrap::setField(); + fieldB = static_cast(TGeoGlobalMagField::Instance()->GetField()); + } + + enum ProagationPoint { ToVtx, + ToDCA }; + + template + o2::dataformats::GlobalFwdTrack PropagateMuon(T const& muon, int PropType) + { + + auto collision = muon.collision(); + + o2::dataformats::GlobalFwdTrack propmuon; + + 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()}; + if (isGoodFwdTrack(muon)) { + SMatrix55 tcovs(v1.begin(), v1.end()); + o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; + + o2::dataformats::GlobalFwdTrack track; + track.setParameters(tpars); + track.setZ(fwdtrack.getZ()); + track.setCovariances(tcovs); + auto mchTrack = mMatching.FwdtoMCH(track); + if (PropType == ProagationPoint::ToVtx) + o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); + else if (PropType == ProagationPoint::ToDCA) + o2::mch::TrackExtrap::extrapToVertexWithoutBranson(mchTrack, collision.posZ()); + + auto proptrack = mMatching.MCHtoFwd(mchTrack); + propmuon.setParameters(proptrack.getParameters()); + propmuon.setZ(proptrack.getZ()); + propmuon.setCovariances(proptrack.getCovariances()); + } + + v1.clear(); + v1.shrink_to_fit(); + + return propmuon; + } + + template + o2::track::TrackParCovFwd PropagateMFT(T const& mfttrack, int PropType) + { + std::vector mftv1; + SMatrix55 mftcovs{mftv1.begin(), mftv1.end()}; + SMatrix5 mftpars = {mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()}; + o2::track::TrackParCovFwd mftpartrack = {mfttrack.z(), mftpars, mftcovs, mfttrack.chi2()}; + if (PropType == ProagationPoint::ToDCA) { + auto collision = mfttrack.collision(); + double propVec[3] = {fabs(mfttrack.x() - collision.posX()), fabs(mfttrack.y() - collision.posY()), fabs(mfttrack.z() - collision.posZ())}; + double centerZ[3] = {mfttrack.x() - propVec[0] / 2., mfttrack.y() - propVec[1] / 2., mfttrack.z() - propVec[2] / 2.}; + float Bz = fieldB->getBz(centerZ); + mftpartrack.propagateToZ(collision.posZ(), Bz); + } + return mftpartrack; + } + + template + o2::track::TrackParCovFwd PropagateMFTtoMatchingPlane(MFT const& mfttrack, FWD const& fwdtrack) + { + std::vector v1; // Temporary null vector for the computation of the covariance matrix + double propVec[3] = {fwdtrack.x() - mfttrack.x(), fwdtrack.y() - mfttrack.y(), fwdtrack.z() - mfttrack.z()}; + double centerZ[3] = {mfttrack.x() + propVec[0] / 2., mfttrack.y() + propVec[1] / 2., mfttrack.z() + propVec[2] / 2.}; + float Bz = fieldB->getBz(centerZ); // gives error if the propagator is not initFielded + SMatrix55 tmftcovs(v1.begin(), v1.end()); + SMatrix5 tmftpars(mfttrack.x(), mfttrack.y(), mfttrack.phi(), mfttrack.tgl(), mfttrack.signed1Pt()); + o2::track::TrackParCovFwd extrap_mfttrack{mfttrack.z(), tmftpars, tmftcovs, mfttrack.chi2()}; + extrap_mfttrack.propagateToZ(fwdtrack.z(), Bz); // z in cm + return extrap_mfttrack; + } + + template + bool isGoodFwdTrack(T track) + { + if (!track.has_collision()) + return false; + if (track.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) + return false; + if (track.chi2() > fTrackChi2MchUp) + return false; + if (17.6 > track.rAtAbsorberEnd() || track.rAtAbsorberEnd() > 89.5) + return false; + if (track.rAtAbsorberEnd() < 26.5 && 594. < track.pDca()) + return false; + if (track.rAtAbsorberEnd() > 26.5 && 324. < track.pDca()) + return false; + return true; + } + + template + int selectTagMuon(T track1, T track2) + { + if (track1.pt() > track2.pt()) { + return track1.globalIndex(); + } else { + return track2.globalIndex(); + } + } + + template + int selectProbeMuon(T track1, T track2) + { + if (track1.pt() < track2.pt()) { + return track1.globalIndex(); + } else { + return track2.globalIndex(); + } + } + + bool isGoodKenematicTrack(o2::dataformats::GlobalFwdTrack track) + { + if (fEtaMchLow > track.getEta() || track.getEta() > fEtaMchUp) + return false; + return true; + } + + void process(aod::Collisions const& collisions, ExtBCs const& ebcs, + MyMuons const& fwdtracks, MyMFTs const& mfttracks) + { + initCCDB(ebcs.begin()); + + std::unordered_set bcs_mfttrack; + std::unordered_map map_vtxZ; + std::unordered_map nmfttracks; + std::unordered_map> map_mfttraks; + + for (const auto& mfttrack : mfttracks) { + + if (!mfttrack.has_collision()) + continue; + bcs_mfttrack.insert(mfttrack.collisionId()); + std::vector& tracks = map_mfttraks[mfttrack.collisionId()]; + tracks.push_back(mfttrack.globalIndex()); + + o2::track::TrackParCovFwd mftpartrack = PropagateMFT(mfttrack, ProagationPoint::ToDCA); + + auto collision = mfttrack.collision(); + + map_vtxZ[mfttrack.collisionId()] = collision.posZ(); + + float dx = mftpartrack.getX() - collision.posX(); + float dy = mftpartrack.getY() - collision.posY(); + float dca = sqrt(dx * dx + dy * dy); + + mftParams(mfttrack.nClusters(), mfttrack.isCA(), + mfttrack.chi2(), mfttrack.sign(), + mfttrack.pt(), mfttrack.eta(), mfttrack.phi(), + mftpartrack.getPt(), mftpartrack.getEta(), mftpartrack.getPhi(), + dx, dy, dca); + + nmfttracks[mfttrack.collisionId()]++; + } + + std::unordered_map nfwdtracks; + std::unordered_map> map_fwdtraks; + + for (auto fwdtrack : fwdtracks) { + + if (!isGoodFwdTrack(fwdtrack)) + continue; + + o2::dataformats::GlobalFwdTrack propmuonAtPV = PropagateMuon(fwdtrack, ProagationPoint::ToVtx); + o2::dataformats::GlobalFwdTrack propmuonAtDCA = PropagateMuon(fwdtrack, ProagationPoint::ToDCA); + if (!isGoodKenematicTrack(propmuonAtPV)) + continue; + std::vector& tracks = map_fwdtraks[fwdtrack.collisionId()]; + tracks.push_back(fwdtrack.globalIndex()); + + auto collision = fwdtrack.collision(); + + float dx = propmuonAtDCA.getX() - collision.posX(); + float dy = propmuonAtDCA.getY() - collision.posY(); + float DCA = sqrt(dx * dx + dy * dy); + + bool hasMFT = false; + + std::vector& mfttracks = map_mfttraks[fwdtrack.collisionId()]; + + if (mfttracks.size() > 0) + hasMFT = true; + + muonParams(fwdtrack.chi2(), fwdtrack.rAtAbsorberEnd(), fwdtrack.sign(), fwdtrack.pt(), fwdtrack.eta(), fwdtrack.phi(), + propmuonAtPV.getPt(), propmuonAtPV.getEta(), propmuonAtPV.getPhi(), + propmuonAtDCA.getPt(), propmuonAtDCA.getEta(), propmuonAtDCA.getPhi(), + DCA, hasMFT); + + nfwdtracks[fwdtrack.collisionId()]++; + } + + for (auto fwdtrack1 : fwdtracks) { + + if (!isGoodFwdTrack(fwdtrack1)) + continue; + + int ibc = fwdtrack1.collisionId(); + auto collision = fwdtrack1.collision(); + + o2::dataformats::GlobalFwdTrack fwdtrackAtPV1 = PropagateMuon(fwdtrack1, ProagationPoint::ToVtx); + if (!isGoodKenematicTrack(fwdtrackAtPV1)) + continue; + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////// MIXED EVENT /////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + for (auto bc_mfttrack : bcs_mfttrack) { + + if (ibc == bc_mfttrack) + continue; + if (fabs(nmfttracks[ibc] - nmfttracks[bc_mfttrack]) > fEventMaxDeltaNMFT) + continue; + if (fabs(map_vtxZ[bc_mfttrack] - collision.posZ()) > fEventMaxDeltaVtxZ) + continue; + + std::vector& mfttrackGlobalIndex = map_mfttraks[bc_mfttrack]; + + for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { + + auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); + o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, fwdtrack1); + + V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); + V2.SetPtEtaPhi(fwdtrack1.pt(), fwdtrack1.eta(), fwdtrack1.phi()); + + double deltaP = mfttrack_at_matching.getP() - fwdtrack1.p(); + double deltaPt = mfttrack_at_matching.getPt() - fwdtrack1.pt(); + double deltaX = mfttrack_at_matching.getX() - fwdtrack1.x(); + double deltaY = mfttrack_at_matching.getY() - fwdtrack1.y(); + double deltaPhi = V1.DeltaPhi(V2); + double deltaEta = mfttrack_at_matching.getEta() - fwdtrack1.eta(); + + if (fabs(deltaX) > fPreselectMatchingX) + continue; + if (fabs(deltaY) > fPreselectMatchingY) + continue; + + o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); + float dx = mfttrack_at_dca.getX() - collision.posX(); + float dy = mfttrack_at_dca.getY() - collision.posY(); + float DCA = sqrt(dx * dx + dy * dy); + + mixmatchingParams(mfttrack1.nClusters(), mfttrack1.chi2(), + deltaP, deltaPt, deltaEta, deltaPhi, deltaX, deltaY, + fwdtrackAtPV1.getPt(), fwdtrackAtPV1.getEta(), fwdtrackAtPV1.getPhi(), fwdtrack1.sign(), + mfttrack_at_dca.getPt(), mfttrack_at_dca.getEta(), mfttrack_at_dca.getPhi(), mfttrack1.sign(), DCA); + } + } // end of loop bc_mfttrack + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////// SAME EVENT /////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + std::vector& mfttrackGlobalIndex = map_mfttraks[ibc]; + + for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { + + auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); + o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, fwdtrack1); + V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); + V2.SetPtEtaPhi(fwdtrack1.pt(), fwdtrack1.eta(), fwdtrack1.phi()); + + double deltaP = mfttrack_at_matching.getP() - fwdtrack1.p(); + double deltaPt = mfttrack_at_matching.getPt() - fwdtrack1.pt(); + double deltaX = mfttrack_at_matching.getX() - fwdtrack1.x(); + double deltaY = mfttrack_at_matching.getY() - fwdtrack1.y(); + double deltaPhi = V1.DeltaPhi(V2); + double deltaEta = mfttrack_at_matching.getEta() - fwdtrack1.eta(); + + if (fabs(deltaX) > fPreselectMatchingX) + continue; + if (fabs(deltaY) > fPreselectMatchingY) + continue; + + o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); + float dx = mfttrack_at_dca.getX() - collision.posX(); + float dy = mfttrack_at_dca.getY() - collision.posY(); + float DCA = sqrt(dx * dx + dy * dy); + + matchingParams(mfttrack1.nClusters(), mfttrack1.chi2(), + deltaP, deltaPt, deltaEta, deltaPhi, deltaX, deltaY, + fwdtrackAtPV1.getPt(), fwdtrackAtPV1.getEta(), fwdtrackAtPV1.getPhi(), fwdtrack1.sign(), + mfttrack_at_dca.getPt(), mfttrack_at_dca.getEta(), mfttrack_at_dca.getPhi(), mfttrack1.sign(), DCA); + } // end of loop idmfttrack1 + + std::vector& fwdtrackGlobalIndex = map_fwdtraks[ibc]; + + for (int idfwdtrack2 = 0; idfwdtrack2 < static_cast(fwdtrackGlobalIndex.size()); ++idfwdtrack2) { + + if (fwdtrack1.globalIndex() == fwdtrackGlobalIndex[idfwdtrack2]) + continue; + + auto fwdtrack2 = fwdtracks.rawIteratorAt(fwdtrackGlobalIndex[idfwdtrack2]); + + if (!isGoodFwdTrack(fwdtrack2)) + continue; + + o2::dataformats::GlobalFwdTrack fwdtrackAtPV2 = PropagateMuon(fwdtrack2, ProagationPoint::ToVtx); + if (!isGoodKenematicTrack(fwdtrackAtPV2)) + continue; + + muon1LV.SetPtEtaPhiM(fwdtrackAtPV1.getPt(), fwdtrackAtPV1.getEta(), fwdtrackAtPV1.getPhi(), mMu); + muon2LV.SetPtEtaPhiM(fwdtrackAtPV2.getPt(), fwdtrackAtPV2.getEta(), fwdtrackAtPV2.getPhi(), mMu); + dimuonLV = muon1LV + muon2LV; + + muonPairs(nmfttracks[ibc], fwdtrack1.sign() + fwdtrack2.sign(), dimuonLV.M(), dimuonLV.Pt(), dimuonLV.Rapidity()); + + if (fabs(fwdtrack1.sign() + fwdtrack2.sign()) > 0) + continue; + if (fTagMassWindowMin > dimuonLV.M() || dimuonLV.M() > fTagMassWindowMax) + continue; + if (nmfttracks[ibc] < 1) + continue; + + tagmuonPairs(nmfttracks[ibc], fwdtrack1.sign() + fwdtrack2.sign(), dimuonLV.M(), dimuonLV.Pt(), dimuonLV.Rapidity()); + + bool isGoodTag = false; + int nMFTCandsTagMuon = 0; + + auto tagfwdtrack = fwdtracks.rawIteratorAt(selectTagMuon(fwdtrack1, fwdtrack2)); + o2::dataformats::GlobalFwdTrack tagfwdtrackAtPV = PropagateMuon(tagfwdtrack, ProagationPoint::ToVtx); + + for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { + + auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); + o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, tagfwdtrack); + + V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); + V2.SetPtEtaPhi(tagfwdtrack.pt(), tagfwdtrack.eta(), tagfwdtrack.phi()); + + double deltaP = mfttrack_at_matching.getP() - tagfwdtrack.p(); + double deltaPt = mfttrack_at_matching.getPt() - tagfwdtrack.pt(); + double deltaX = mfttrack_at_matching.getX() - tagfwdtrack.x(); + double deltaY = mfttrack_at_matching.getY() - tagfwdtrack.y(); + double deltaPhi = V1.DeltaPhi(V2); + double deltaEta = mfttrack_at_matching.getEta() - tagfwdtrack.eta(); + + double deltaR = sqrt(deltaX * deltaX + deltaY * deltaY); + if (fabs(deltaX) > fPreselectMatchingX) + continue; + if (fabs(deltaY) > fPreselectMatchingY) + continue; + + o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); + float dx = mfttrack_at_dca.getX() - collision.posX(); + float dy = mfttrack_at_dca.getY() - collision.posY(); + float DCA = sqrt(dx * dx + dy * dy); + + bool dummyTag = false; + + if (fabs(deltaR) < fTagRWindow && fabs(deltaPhi) < fTagPhiWindow && fabs(deltaEta) < fTagEtaWindow) { + isGoodTag = true; + dummyTag = true; + nMFTCandsTagMuon++; + } + + tagmatchingParams(mfttrack1.nClusters(), mfttrack1.chi2(), + deltaP, deltaPt, deltaEta, deltaPhi, deltaX, deltaY, + tagfwdtrackAtPV.getPt(), tagfwdtrackAtPV.getEta(), tagfwdtrackAtPV.getPhi(), tagfwdtrack.sign(), + mfttrack_at_dca.getPt(), mfttrack_at_dca.getEta(), mfttrack_at_dca.getPhi(), mfttrack1.sign(), DCA, dummyTag); + } + + if (!isGoodTag) + continue; + + auto probefwdtrack = fwdtracks.rawIteratorAt(selectProbeMuon(fwdtrack1, fwdtrack2)); + o2::dataformats::GlobalFwdTrack probefwdtrackAtPV = PropagateMuon(probefwdtrack, ProagationPoint::ToVtx); + + for (int idmfttrack1 = 0; idmfttrack1 < static_cast(mfttrackGlobalIndex.size()); ++idmfttrack1) { + + auto mfttrack1 = mfttracks.rawIteratorAt(mfttrackGlobalIndex[idmfttrack1]); + o2::track::TrackParCovFwd mfttrack_at_matching = PropagateMFTtoMatchingPlane(mfttrack1, probefwdtrack); + + V1.SetPtEtaPhi(mfttrack_at_matching.getPt(), mfttrack_at_matching.getEta(), mfttrack_at_matching.getPhi()); + V2.SetPtEtaPhi(probefwdtrack.pt(), probefwdtrack.eta(), probefwdtrack.phi()); + + double deltaP = mfttrack_at_matching.getP() - probefwdtrack.p(); + double deltaPt = mfttrack_at_matching.getPt() - probefwdtrack.pt(); + double deltaX = mfttrack_at_matching.getX() - probefwdtrack.x(); + double deltaY = mfttrack_at_matching.getY() - probefwdtrack.y(); + double deltaPhi = V1.DeltaPhi(V2); + double deltaEta = mfttrack_at_matching.getEta() - probefwdtrack.eta(); + + if (fabs(deltaX) > fPreselectMatchingX) + continue; + if (fabs(deltaY) > fPreselectMatchingY) + continue; + + o2::track::TrackParCovFwd mfttrack_at_dca = PropagateMFT(mfttrack1, ProagationPoint::ToDCA); + float dx = mfttrack_at_dca.getX() - collision.posX(); + float dy = mfttrack_at_dca.getY() - collision.posY(); + float DCA = sqrt(dx * dx + dy * dy); + + probematchingParams(nMFTCandsTagMuon, tagfwdtrack.p(), mfttrack1.nClusters(), mfttrack1.chi2(), + deltaP, deltaPt, deltaEta, deltaPhi, deltaX, deltaY, + probefwdtrackAtPV.getPt(), probefwdtrackAtPV.getEta(), probefwdtrackAtPV.getPhi(), probefwdtrack.sign(), + mfttrack_at_dca.getPt(), mfttrack_at_dca.getEta(), mfttrack_at_dca.getPhi(), mfttrack1.sign(), DCA); + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx index 96f82b8d3a2..81bf34ae73c 100644 --- a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx +++ b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx @@ -361,9 +361,6 @@ struct DetectorOccupancyQaTask { int runNumber = bcs.iteratorAt(0).runNumber(); if (runNumber != lastRunNumber) { lastRunNumber = runNumber; // do it only once - int64_t tsSOR = 0; - int64_t tsEOR = 1; - uint32_t nOrbitsPerTF = 128; // 128 in 2022, 32 in 2023 if (runNumber >= 500000) { auto runInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::BasicCCDBManager::instance(), runNumber); diff --git a/DPG/Tasks/AOTEvent/eventSelectionQa.cxx b/DPG/Tasks/AOTEvent/eventSelectionQa.cxx index 9946e871840..82230b44d2c 100644 --- a/DPG/Tasks/AOTEvent/eventSelectionQa.cxx +++ b/DPG/Tasks/AOTEvent/eventSelectionQa.cxx @@ -336,14 +336,14 @@ struct EventSelectionQaTask { } // bc-based event selection qa - for (auto& bc : bcs) { + for (const auto& bc : bcs) { for (int iAlias = 0; iAlias < kNaliases; iAlias++) { histos.fill(HIST("hBcCounterAll"), iAlias, bc.alias_bit(iAlias)); } } // collision-based event selection qa - for (auto& col : cols) { + for (const auto& col : cols) { bool sel1 = col.selection_bit(kIsINT1) && col.selection_bit(kNoBGV0A) && col.selection_bit(kNoBGV0C) && col.selection_bit(kNoTPCLaserWarmUp) && col.selection_bit(kNoTPCHVdip); for (int iAlias = 0; iAlias < kNaliases; iAlias++) { @@ -367,7 +367,7 @@ struct EventSelectionQaTask { histos.fill(HIST("hSelCounter"), i, col.selection_bit(i)); } - auto bc = col.bc_as(); + const auto& bc = col.bc_as(); uint64_t globalBC = bc.globalBC(); // uint64_t orbit = globalBC / nBCsPerOrbit; int localBC = globalBC % nBCsPerOrbit; @@ -665,7 +665,7 @@ struct EventSelectionQaTask { std::vector vGlobalBCs(nBCs, 0); // bc-based event selection qa - for (auto& bc : bcs) { + for (const auto& bc : bcs) { if (!bc.has_ft0()) continue; float multT0A = bc.ft0().sumAmpA(); @@ -684,7 +684,7 @@ struct EventSelectionQaTask { } // bc-based event selection qa - for (auto& bc : bcs) { + for (const auto& bc : bcs) { for (int iAlias = 0; iAlias < kNaliases; iAlias++) { histos.fill(HIST("hBcCounterAll"), iAlias, bc.alias_bit(iAlias)); } @@ -810,7 +810,7 @@ struct EventSelectionQaTask { // map for pileup checks std::vector vCollisionsPerBc(bcs.size(), 0); - for (auto& col : cols) { + for (const auto& col : cols) { if (col.foundBCId() < 0 || col.foundBCId() >= bcs.size()) continue; vCollisionsPerBc[col.foundBCId()]++; @@ -826,7 +826,7 @@ struct EventSelectionQaTask { // to be used for closest TVX (FT0-OR) searches std::map mapGlobalBcWithTVX; std::map mapGlobalBcWithTOR; - for (auto& bc : bcs) { + for (const auto& bc : bcs) { int64_t globalBC = bc.globalBC(); // skip non-colliding bcs for data and anchored runs if (runNumber >= 500000 && bcPatternB[globalBC % o2::constants::lhc::LHCMaxBunches] == 0) { @@ -859,7 +859,7 @@ struct EventSelectionQaTask { } // collision-based event selection qa - for (auto& col : cols) { + for (const auto& col : cols) { for (int iAlias = 0; iAlias < kNaliases; iAlias++) { if (!col.alias_bit(iAlias)) { continue; @@ -893,7 +893,7 @@ struct EventSelectionQaTask { // count tracks of different types auto tracksGrouped = tracks.sliceBy(perCollision, col.globalIndex()); int nContributorsAfterEtaTPCCuts = 0; - for (auto& track : tracksGrouped) { + for (const auto& track : tracksGrouped) { int trackBcDiff = bcDiff + track.trackTime() / o2::constants::lhc::LHCBunchSpacingNS; if (!track.isPVContributor()) continue; @@ -1078,7 +1078,7 @@ struct EventSelectionQaTask { void processMCRun3(aod::McCollisions const& mcCols, soa::Join const& cols, BCsRun3 const&, aod::FT0s const&) { - for (auto& mcCol : mcCols) { + for (const auto& mcCol : mcCols) { auto bc = mcCol.bc_as(); uint64_t globalBC = bc.globalBC(); uint64_t orbit = globalBC / nBCsPerOrbit; @@ -1094,7 +1094,7 @@ struct EventSelectionQaTask { } // check fraction of collisions matched to wrong bcs - for (auto& col : cols) { + for (const auto& col : cols) { if (!col.has_mcCollision()) { continue; } diff --git a/DPG/Tasks/AOTEvent/rofOccupancyQa.cxx b/DPG/Tasks/AOTEvent/rofOccupancyQa.cxx index 9e82e498585..790174ef6c8 100644 --- a/DPG/Tasks/AOTEvent/rofOccupancyQa.cxx +++ b/DPG/Tasks/AOTEvent/rofOccupancyQa.cxx @@ -246,7 +246,7 @@ struct RofOccupancyQaTask { histos.add("afterNarrowDeltaTimeCut/hThisEvITSTr_vs_occupancyInPreviousROF_1collPerROF_XaxisWins", "", kTH2D, {{250, 0., 8000 * k}, {250, 0., 8000 * k}}); // 2,3,4 colls in ROF - histos.add("vZ_TF_ROF_border_cuts/hThisEvITSTr_vs_occupancyInROF_2coll_noVzCutOnOtherVertices", "", kTH2D, {{500, 0., 20000 * k}, {250, 0., 8000 * k}}); + histos.add("vZ_TF_ROF_border_cuts/hThisEvITSTr_vs_occupancyInROF_2coll_noVzCutOnOtherVertices", "", kTH2D, {{500, 0., 8000 * k}, {250, 0., 8000 * k}}); histos.add("vZ_TF_ROF_border_cuts/hThisEvITSTr_vs_occupancyInROF_3coll_noVzCutOnOtherVertices", "", kTH2D, {{500, 0., 20000 * k}, {250, 0., 8000 * k}}); histos.add("vZ_TF_ROF_border_cuts/hThisEvITSTr_vs_occupancyInROF_4coll_noVzCutOnOtherVertices", "", kTH2D, {{500, 0., 20000 * k}, {250, 0., 8000 * k}}); @@ -453,7 +453,7 @@ struct RofOccupancyQaTask { for (auto& track : colPvTracks) { if (track.itsNCls() >= 5) { vTracksITS567perColl[colIndex]++; - if (fabs(track.eta() < 0.8)) + if (fabs(track.eta()) < 0.8) vTracksITS567eta08perColl[colIndex]++; if (track.tpcNClsFound() > 70) vTracksITSTPCperColl[colIndex]++; @@ -754,7 +754,7 @@ struct RofOccupancyQaTask { vROFidThisColl[colIndex] = rofIdInTF; if (fabs(vZ) < 10) - vNumCollinROFinVz10[colIndex]++; + vNumCollinROFinVz10[colIndex] = 1; for (uint32_t iCol = 0; iCol < vAssocToSameROF.size(); iCol++) { int thisColIndex = vAssocToSameROF[iCol]; // int64_t thisRofId = (vFoundGlobalBC[thisColIndex] + 3564 - rofOffset) / rofLength; @@ -769,6 +769,8 @@ struct RofOccupancyQaTask { nITS567tracksForRofVetoStrict += vTracksITS567perColl[thisColIndex]; nSumAmplFT0CforRofVetoStrict += vAmpFT0CperColl[thisColIndex]; vNumCollinROF[colIndex]++; + if (fabs(vCollVz[thisColIndex]) < 10) + vNumCollinROFinVz10[colIndex]++; vInROFcollIndex[colIndex] = thisBcInITSROF > bcInITSROF ? 0 : 1; // if colIndex is for the first coll in ROF => inROFindex=0, otherwise =1 // if (vTracksITS567perColl[thisColIndex] > confNtracksCutVetoOnCollInROF) @@ -883,13 +885,13 @@ struct RofOccupancyQaTask { } else if (dt > -4.0 && dt <= -2.0) { // us, strict veto to suppress fake ITS-TPC matches more if (vTracksITS567perColl[thisColIndex] > confNtracksCutVetoOnCollInTimeRange / 5) nITS567tracksForVetoStandard += vTracksITS567perColl[thisColIndex]; - } else if (fabs(dt) < 10 + fabs(vZ) / driftV) { // loose veto, 8 us corresponds to maximum possible |vZ|, which is ~20 cm + } else if (fabs(dt) < 8 + fabs(vZ) / driftV) { // loose veto, 8 us corresponds to maximum possible |vZ|, which is ~20 cm // counting number of other collisions with mult above threshold if (vTracksITS567perColl[thisColIndex] > confNtracksCutVetoOnCollInTimeRange) nITS567tracksForVetoStandard += vTracksITS567perColl[thisColIndex]; } // vZ-dependent time cut to avoid collinear tracks from other collisions (experimental) - if (fabs(dt) < 10 + fabs(vZ) / driftV) { + if (fabs(dt) < 8 + fabs(vZ) / driftV) { if (dt < 0) { // check distance between given vZ and (moving in two directions) vZ of drifting tracks from past collisions if ((fabs(vCollVz[thisColIndex] - fabs(dt) * driftV - vZ) < confEpsilonDistanceForVzDependentVetoTPC) || diff --git a/DPG/Tasks/FV0/qaFV0.cxx b/DPG/Tasks/FV0/qaFV0.cxx index 29a5b763211..295f981b0b7 100644 --- a/DPG/Tasks/FV0/qaFV0.cxx +++ b/DPG/Tasks/FV0/qaFV0.cxx @@ -394,7 +394,7 @@ struct fv0Qa { FillConditionHistograms("FV0BC", localCollisionBCFV0); - for (int i = 0; i < fv0.amplitude().size(); i++) { + for (std::size_t i = 0; i < fv0.amplitude().size(); i++) { FillConditionHistograms("FV0ChannelAmplitude", fv0.amplitude()[i]); FillConditionHistograms("FV0AmplitudePerChannel", fv0.channel()[i], fv0.amplitude()[i]); sum(totalAmplitudes, fv0.amplitude()[i]); diff --git a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx index 031315055f0..67480f2c6d7 100644 --- a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx +++ b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx @@ -82,6 +82,8 @@ struct TreeWriterTpcV0 { const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; const int multTPC = collision.multTPC(); + auto trackocc = collision.trackOccupancyInTimeRange(); + auto ft0occ = collision.ft0cOccupancyInTimeRange(); const float alpha = v0.alpha(); const float qt = v0.qtarm(); @@ -113,7 +115,9 @@ struct TreeWriterTpcV0 { pT, v0radius, gammapsipair, - runnumber); + runnumber, + trackocc, + ft0occ); } }; @@ -324,6 +328,8 @@ struct TreeWriterTPCTOF { const double mass = o2::track::pid_constants::sMasses[id]; const double bg = p / mass; const int multTPC = collision.multTPC(); + auto trackocc = collision.trackOccupancyInTimeRange(); + auto ft0occ = collision.ft0cOccupancyInTimeRange(); const double pseudoRndm = track.pt() * 1000. - static_cast(track.pt() * 1000); if (pseudoRndm < dwnSmplFactor) { @@ -342,7 +348,9 @@ struct TreeWriterTPCTOF { id, nSigmaTPC, nSigmaTOF, - runnumber); + runnumber, + trackocc, + ft0occ); } }; diff --git a/DPG/Tasks/TPC/tpcSkimsTableCreator.h b/DPG/Tasks/TPC/tpcSkimsTableCreator.h index c8cce4750de..2f65dccc589 100644 --- a/DPG/Tasks/TPC/tpcSkimsTableCreator.h +++ b/DPG/Tasks/TPC/tpcSkimsTableCreator.h @@ -41,6 +41,8 @@ DECLARE_SOA_COLUMN(PtV0, ptV0, float); DECLARE_SOA_COLUMN(RadiusV0, radiusV0, float); DECLARE_SOA_COLUMN(GammaPsiPair, gammaPsiPair, float); DECLARE_SOA_COLUMN(RunNumber, runNumber, int); +DECLARE_SOA_COLUMN(TrackOcc, trackOcc, float); +DECLARE_SOA_COLUMN(Ft0Occ, ft0Occ, float); } // namespace tpcskims DECLARE_SOA_TABLE(SkimmedTPCV0Tree, "AOD", "TPCSKIMV0TREE", o2::aod::track::TPCSignal, @@ -64,7 +66,9 @@ DECLARE_SOA_TABLE(SkimmedTPCV0Tree, "AOD", "TPCSKIMV0TREE", tpcskims::PtV0, tpcskims::RadiusV0, tpcskims::GammaPsiPair, - tpcskims::RunNumber); + tpcskims::RunNumber, + tpcskims::TrackOcc, + tpcskims::Ft0Occ); DECLARE_SOA_TABLE(SkimmedTPCTOFTree, "AOD", "TPCTOFSKIMTREE", o2::aod::track::TPCSignal, @@ -82,6 +86,8 @@ DECLARE_SOA_TABLE(SkimmedTPCTOFTree, "AOD", "TPCTOFSKIMTREE", tpcskims::PidIndex, tpcskims::NSigTPC, tpcskims::NSigTOF, - tpcskims::RunNumber); + tpcskims::RunNumber, + tpcskims::TrackOcc, + tpcskims::Ft0Occ); } // namespace o2::aod #endif // DPG_TASKS_TPC_TPCSKIMSTABLECREATOR_H_ diff --git a/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx b/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx index 1ee50ada907..5e62416a75d 100644 --- a/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx +++ b/EventFiltering/PWGHF/HFFilterPrepareMLSamples.cxx @@ -162,7 +162,7 @@ struct HfFilterPrepareMlSamples { // Main struct auto trackFirst = cand3Prong.prong0_as(); // first daughter auto trackSecond = cand3Prong.prong1_as(); // second daughter auto trackThird = cand3Prong.prong2_as(); // third daughter - auto arrayDaughters = std::array{trackFirst, trackSecond, trackThird}; + // auto arrayDaughters = std::array{trackFirst, trackSecond, trackThird}; auto trackParFirst = getTrackPar(trackFirst); auto trackParSecond = getTrackPar(trackSecond); @@ -206,7 +206,7 @@ struct HfFilterPrepareMlSamples { // Main struct deltaMassKKFirst = std::abs(RecoDecay::m(std::array{pVecFirst, pVecSecond}, std::array{massKa, massKa}) - massPhi); deltaMassKKSecond = std::abs(RecoDecay::m(std::array{pVecThird, pVecSecond}, std::array{massKa, massKa}) - massPhi); } - int8_t sign = 0; + // int8_t sign = 0; auto flag = RecoDecay::OriginType::None; float pseudoRndm = trackFirst.pt() * 1000. - static_cast(trackFirst.pt() * 1000); diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx index 5d0ed29cc60..cda9e3ebd83 100644 --- a/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx @@ -53,8 +53,6 @@ struct meanPtFlucId { Configurable cfgCutDcaZ{"cfgCutDcaZ", 0.3, "DCAz cut"}; Configurable cfgCutPosZ{"cfgCutPosZ", 10.0, "cut for vertex Z"}; Configurable cfgGammaCut{"cfgGammaCut", 0.003, "Gamma inv Mass Cut for electron-positron rejection"}; - Configurable cfgCutNSigTpcEl{"cfgCutNSigTpcEl", 1.5, "TPC nSigma Electron veto cut"}; - Configurable cfgCutNSigTofEl{"cfgCutNSigTofEl", 1.5, "TOF nSigma Electron veto cut"}; Configurable cfgCutNSig2{"cfgCutNSig2", 2.0, "nSigma cut (2)"}; Configurable cfgCutNSig3{"cfgCutNSig3", 3.0, "nSigma cut (3)"}; Configurable cfgCutPiPtMin{"cfgCutPiPtMin", 0.2, "Minimum pion p_{T} cut"}; @@ -74,21 +72,20 @@ struct meanPtFlucId { Configurable cfgMcTpcShiftPi{"cfgMcTpcShiftPi", 0., "Pion Shift in TPC (MC data) "}; Configurable cfgMcTpcShiftKa{"cfgMcTpcShiftKa", 0., "Kaon Shift in TPC (MC data) "}; Configurable cfgMcTpcShiftPr{"cfgMcTpcShiftPr", 0., "Proton Shift in TPC (MC data) "}; + Configurable cfgMcTofShiftPi{"cfgMcTofShiftPi", 0., "Pion Shift in TOF (MC data) "}; + Configurable cfgMcTofShiftKa{"cfgMcTofShiftKa", 0., "Kaon Shift in TOF (MC data) "}; + Configurable cfgMcTofShiftPr{"cfgMcTofShiftPr", 0., "Proton Shift in TOF (MC data) "}; + Configurable cfgPosZ{"cfgPosZ", true, "Position Z"}; + Configurable cfgSel8{"cfgSel8", true, "Sel8 trigger"}; + Configurable cfgEvSel1{"cfgEvSel1", true, "kNoSameBunchPileup"}; + Configurable cfgEvSel2{"cfgEvSel2", true, "kIsGoodZvtxFT0vsPV"}; Configurable cfgInvMass{"cfgInvMass", true, "electron Inv Mass cut selection"}; - Configurable cfgSelORPi{"cfgSelORPi", true, "Low OR High momentum for Pions"}; - Configurable cfgSelORKa{"cfgSelORKa", true, "Low OR High momentum for Kaons"}; - Configurable cfgSelORPr{"cfgSelORPr", true, "Low OR High momentum for Protons"}; - Configurable cfgSelANDPi{"cfgSelANDPi", false, "Low AND High momentum for Pions"}; - Configurable cfgSelANDKa{"cfgSelANDKa", false, "Low AND High momentum for Kaons"}; - Configurable cfgSelANDPr{"cfgSelANDPr", false, "Low AND High momentum for Protons"}; - Configurable cfgSelLowPi{"cfgSelLowPi", true, "PID selection cut for Low momentum Pions"}; - Configurable cfgSelLowKa{"cfgSelLowKa", true, "PID selection cut for Low momentum Kaons"}; - Configurable cfgSelLowPr{"cfgSelLowPr", true, "PID selection cut for Low momentum Protons"}; - Configurable cfgSelHighPi{"cfgSelHighPi", true, "PID selection cut for High momentum Pions"}; - Configurable cfgSelHighKa{"cfgSelHighKa", true, "PID selection cut for High momentum Kaons"}; - Configurable cfgSelHighPr{"cfgSelHighPr", true, "PID selection cut for High momentum Protons"}; + Configurable cfgSelOR{"cfgSelOR", true, "Low OR High momentum "}; + Configurable cfgSelAND{"cfgSelAND", false, "Low AND High momentum"}; + Configurable cfgSelLow{"cfgSelLow", true, "PID selection cut for Low momentum"}; + Configurable cfgSelHigh{"cfgSelHigh", true, "PID selection cut for High momentum"}; ConfigurableAxis multTPCBins{"multTPCBins", {150, 0, 150}, "TPC Multiplicity bins"}; - ConfigurableAxis multFT0CBins{"multFT0CBins", {200, 0, 2000}, "Forward Multiplicity bins"}; + ConfigurableAxis multFT0CBins{"multFT0CBins", {400, 0, 4000}, "Forward Multiplicity bins"}; ConfigurableAxis multFT0CMCBins{"multFT0CMCBins", {250, 0, 250}, "Forward Multiplicity bins"}; ConfigurableAxis dcaXYBins{"dcaXYBins", {100, -0.15, 0.15}, "dcaXY bins"}; ConfigurableAxis dcaZBins{"dcaZBins", {100, -1.2, 1.2}, "dcaZ bins"}; @@ -276,7 +273,7 @@ struct meanPtFlucId { hist.add("Gen/Counts", "Counts", kTH1D, {axisEvents}); hist.add("Gen/vtxZ", "Vertex Z ", kTH1D, {axisVtxZ}); hist.add("Gen/NTPC", "Mid rapidity Multiplicity", kTH1D, {axisMultTPC}); - hist.add("Gen/NFT0C", "Forward Multiplicity", kTH1D, {axisMultFT0C}); + hist.add("Gen/NFT0C", "Forward Multiplicity", kTH1D, {axisMultFT0CMC}); hist.add("Gen/h2_NTPC_NFT0C", "N_{TPC} vs N_{FT0C}", kTH2D, {{axisMultFT0CMC}, {axisMultTPC}}); hist.add("Gen/Charged/h_Pt", "p_{T} ", kTH1D, {axisPt}); hist.add("Gen/Charged/h_PtPos", "p_{T} (Positive)", kTH1D, {axisPt}); @@ -343,26 +340,24 @@ struct meanPtFlucId { template bool selRun3Col(T const& col) { - if (std::abs(col.posZ()) > cfgCutPosZ) + hist.fill(HIST("QA/after/counts_evSelCuts"), 0); + + if (cfgPosZ && std::abs(col.posZ()) > cfgCutPosZ) return false; hist.fill(HIST("QA/after/counts_evSelCuts"), 1); - if (!col.sel8()) + if (cfgSel8 && !col.sel8()) return false; hist.fill(HIST("QA/after/counts_evSelCuts"), 2); - if (!col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + if (cfgEvSel1 && !col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) return false; hist.fill(HIST("QA/after/counts_evSelCuts"), 3); - if (!col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + if (cfgEvSel2 && !col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) return false; hist.fill(HIST("QA/after/counts_evSelCuts"), 4); - if (!col.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) - return false; - hist.fill(HIST("QA/after/counts_evSelCuts"), 5); - return true; } @@ -395,7 +390,11 @@ struct meanPtFlucId { template bool rejectTracks(T const& track) { - if ((track.tpcNSigmaEl() + cfgMcTpcShiftEl) > -3. && (track.tpcNSigmaEl() + cfgMcTpcShiftEl) < 5. && std::fabs(track.tpcNSigmaPi() + cfgMcTpcShiftPi) > 3 && std::fabs(track.tpcNSigmaKa() + cfgMcTpcShiftKa) > 3 && std::fabs(track.tpcNSigmaPr() + cfgMcTpcShiftPr) > 3) { + if (((track.tpcNSigmaEl() - cfgMcTpcShiftEl) > -3. && + (track.tpcNSigmaEl() - cfgMcTpcShiftEl) < 5.) && + (std::fabs(track.tpcNSigmaPi() - cfgMcTpcShiftPi) > 3 && + std::fabs(track.tpcNSigmaKa() - cfgMcTpcShiftKa) > 3 && + std::fabs(track.tpcNSigmaPr() - cfgMcTpcShiftPr) > 3)) { return true; } @@ -405,7 +404,7 @@ struct meanPtFlucId { template bool selElectrons(T const& track) { - if (std::fabs(track.tpcNSigmaEl() + cfgMcTpcShiftEl) < cfgCutNSig3) { + if (std::fabs(track.tpcNSigmaEl() - cfgMcTpcShiftEl) < cfgCutNSig3) { return true; } @@ -416,9 +415,15 @@ struct meanPtFlucId { template bool selLowPi(T const& track, double p) { - if (track.pt() >= cfgCutPiPtMin && std::fabs(track.tpcNSigmaKa() + cfgMcTpcShiftKa) > 3 && std::fabs(track.tpcNSigmaPr() + cfgMcTpcShiftPr) > 3 && track.p() <= cfgCutPiThrsldP && - ((std::fabs(track.tpcNSigmaPi() + cfgMcTpcShiftPi) < cfgCutNSig3 && p <= cfgCutPiP1) || - (std::fabs(track.tpcNSigmaPi() + cfgMcTpcShiftPi) < cfgCutNSig2 && p > cfgCutPiP1 && p <= cfgCutPiP2))) { + if (track.pt() >= cfgCutPiPtMin && + track.p() <= cfgCutPiThrsldP && + ((!track.hasTOF() && + ((std::fabs(track.tpcNSigmaPi() - cfgMcTpcShiftPi) < cfgCutNSig3 && p <= cfgCutPiP1) || + (std::fabs(track.tpcNSigmaPi() - cfgMcTpcShiftPi) < cfgCutNSig2 && p > cfgCutPiP1 && p <= cfgCutPiP2))) || + (track.hasTOF() && + std::fabs(track.tpcNSigmaPi() - cfgMcTpcShiftPi) < cfgCutNSig3 && + std::fabs(track.tofNSigmaPi() - cfgMcTofShiftPi) < cfgCutNSig3))) { + if (std::abs(track.rapidity(MassPiPlus)) < cfgCutRap) { return true; } @@ -430,9 +435,15 @@ struct meanPtFlucId { template bool selLowKa(T const& track, double p) { - if (track.pt() >= cfgCutKaPtMin && std::fabs(track.tpcNSigmaPi() + cfgMcTpcShiftPi) > 3 && std::fabs(track.tpcNSigmaPr() + cfgMcTpcShiftPr) > 3 && track.p() <= cfgCutKaThrsldP && - ((std::fabs(track.tpcNSigmaKa() + cfgMcTpcShiftKa) < cfgCutNSig3 && p <= cfgCutKaP1) || - (std::fabs(track.tpcNSigmaKa() + cfgMcTpcShiftKa) < cfgCutNSig2 && p > cfgCutKaP1 && p <= cfgCutKaP2))) { + if (track.pt() >= cfgCutKaPtMin && + track.p() <= cfgCutKaThrsldP && + ((!track.hasTOF() && + ((std::fabs(track.tpcNSigmaKa() - cfgMcTpcShiftKa) < cfgCutNSig3 && p <= cfgCutKaP1) || + (std::fabs(track.tpcNSigmaKa() - cfgMcTpcShiftKa) < cfgCutNSig2 && p > cfgCutKaP1 && p <= cfgCutKaP2))) || + (track.hasTOF() && + std::fabs(track.tpcNSigmaKa() - cfgMcTpcShiftKa) < cfgCutNSig3 && + std::fabs(track.tofNSigmaKa() - cfgMcTofShiftKa) < cfgCutNSig3))) { + if (std::abs(track.rapidity(MassKPlus)) < cfgCutRap) { return true; } @@ -445,9 +456,15 @@ struct meanPtFlucId { template bool selLowPr(T const& track, double p) { - if (track.pt() >= cfgCutPrPtMin && std::fabs(track.tpcNSigmaKa() + cfgMcTpcShiftKa) > 3 && std::fabs(track.tpcNSigmaPi() + cfgMcTpcShiftPi) > 3 && track.p() <= cfgCutPrThrsldP && - ((std::fabs(track.tpcNSigmaPr() + cfgMcTpcShiftPr) < cfgCutNSig3 && p <= cfgCutPrP1) || - (std::fabs(track.tpcNSigmaPr() + cfgMcTpcShiftPr) < cfgCutNSig2 && p > cfgCutPrP1 && p <= cfgCutPrP2))) { + if (track.pt() >= cfgCutPrPtMin && + track.p() <= cfgCutPrThrsldP && + ((!track.hasTOF() && + ((std::fabs(track.tpcNSigmaPr() - cfgMcTpcShiftPr) < cfgCutNSig3 && p <= cfgCutPrP1) || + (std::fabs(track.tpcNSigmaPr() - cfgMcTpcShiftPr) < cfgCutNSig2 && p > cfgCutPrP1 && p <= cfgCutPrP2))) || + (track.hasTOF() && + std::fabs(track.tpcNSigmaPr() - cfgMcTpcShiftPr) < cfgCutNSig3 && + std::fabs(track.tofNSigmaPr() - cfgMcTofShiftPr) < cfgCutNSig3))) { + if (std::abs(track.rapidity(MassProton)) < cfgCutRap) { return true; } @@ -460,7 +477,11 @@ struct meanPtFlucId { template bool selHighPi(T const& track) { - if (track.p() > cfgCutPiThrsldP && (track.hasTOF() && std::fabs(track.tpcNSigmaPi() + cfgMcTpcShiftPi) < cfgCutNSig3 && (std::fabs(track.tofNSigmaPi()) < cfgCutNSig3))) { + if (track.hasTOF() && + track.p() > cfgCutPiThrsldP && + std::fabs(track.tpcNSigmaPi() - cfgMcTpcShiftPi) < cfgCutNSig3 && + std::fabs(track.tofNSigmaPi() - cfgMcTofShiftPi) < cfgCutNSig3) { + if (std::abs(track.rapidity(MassPiPlus)) < cfgCutRap) { return true; } @@ -473,9 +494,12 @@ struct meanPtFlucId { template bool selHighKa(T const& track) { - if (track.p() > cfgCutKaThrsldP && (track.hasTOF() && std::fabs(track.tpcNSigmaKa() + cfgMcTpcShiftKa) < cfgCutNSig3 && - ((std::fabs(track.tofNSigmaKa()) < cfgCutNSig3 && track.p() <= cfgCutKaP3) || - (std::fabs(track.tofNSigmaKa()) < cfgCutNSig2 && track.p() > cfgCutKaP3)))) { + if (track.hasTOF() && + track.p() > cfgCutKaThrsldP && + std::fabs(track.tpcNSigmaKa() - cfgMcTpcShiftKa) < cfgCutNSig3 && + ((std::fabs(track.tofNSigmaKa() - cfgMcTofShiftKa) < cfgCutNSig3 && track.p() <= cfgCutKaP3) || + (std::fabs(track.tofNSigmaKa() - cfgMcTofShiftKa) < cfgCutNSig2 && track.p() > cfgCutKaP3))) { + if (std::abs(track.rapidity(MassKPlus)) < cfgCutRap) { return true; } @@ -488,7 +512,11 @@ struct meanPtFlucId { template bool selHighPr(T const& track) { - if (track.p() > cfgCutPrThrsldP && (track.hasTOF() && std::fabs(track.tpcNSigmaPr() + cfgMcTpcShiftPr) < cfgCutNSig3 && std::fabs(track.tofNSigmaPr()) < cfgCutNSig3)) { + if (track.hasTOF() && + track.p() > cfgCutPrThrsldP && + std::fabs(track.tpcNSigmaPr() - cfgMcTpcShiftPr) < cfgCutNSig3 && + std::fabs(track.tofNSigmaPr() - cfgMcTofShiftPr) < cfgCutNSig3) { + if (std::abs(track.rapidity(MassProton)) < cfgCutRap) { return true; } @@ -790,49 +818,55 @@ struct meanPtFlucId { continue; } - if (cfgSelORPi == true && cfgSelANDPi == false) { - if (selLowPi(track, innerParam) == cfgSelLowPi || selHighPi(track) == cfgSelHighPi) { + if (cfgSelOR == true && cfgSelAND == false) { + if (selLowPi(track, innerParam) == cfgSelLow || selHighPi(track) == cfgSelHigh) { N_Pi++; pt_Pi = track.pt(); + hist.fill(HIST("QA/Pion/h_Pt"), track.pt()); moments(pt_Pi, Q1_Pi, Q2_Pi, Q3_Pi, Q4_Pi); FillIdParticleQAHistos(track, rapPi, nSigmaTPCPi, nSigmaTOFPi); } - } else if (cfgSelORPi == false && cfgSelANDPi == true) { - if (selLowPi(track, innerParam) == cfgSelLowPi && selHighPi(track) == cfgSelHighPi) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if (selLowPi(track, innerParam) == cfgSelLow && selHighPi(track) == cfgSelHigh) { N_Pi++; pt_Pi = track.pt(); + hist.fill(HIST("QA/Pion/h_Pt"), track.pt()); moments(pt_Pi, Q1_Pi, Q2_Pi, Q3_Pi, Q4_Pi); FillIdParticleQAHistos(track, rapPi, nSigmaTPCPi, nSigmaTOFPi); } } - if (cfgSelORKa == true && cfgSelANDKa == false) { - if (selLowKa(track, innerParam) == cfgSelLowKa || selHighKa(track) == cfgSelHighKa) { + if (cfgSelOR == true && cfgSelAND == false) { + if (selLowKa(track, innerParam) == cfgSelLow || selHighKa(track) == cfgSelHigh) { N_Ka++; pt_Ka = track.pt(); + hist.fill(HIST("QA/Kaon/h_Pt"), track.pt()); moments(pt_Ka, Q1_Ka, Q2_Ka, Q3_Ka, Q4_Ka); FillIdParticleQAHistos(track, rapKa, nSigmaTPCKa, nSigmaTOFKa); } - } else if (cfgSelORKa == false && cfgSelANDKa == true) { - if (selLowKa(track, innerParam) == cfgSelLowKa && selHighKa(track) == cfgSelHighKa) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if (selLowKa(track, innerParam) == cfgSelLow && selHighKa(track) == cfgSelHigh) { N_Ka++; pt_Ka = track.pt(); + hist.fill(HIST("QA/Kaon/h_Pt"), track.pt()); moments(pt_Ka, Q1_Ka, Q2_Ka, Q3_Ka, Q4_Ka); FillIdParticleQAHistos(track, rapKa, nSigmaTPCKa, nSigmaTOFKa); } } - if (cfgSelORPr == true && cfgSelANDPr == false) { - if (selLowPr(track, innerParam) == cfgSelLowPr || selHighPr(track) == cfgSelHighPr) { + if (cfgSelOR == true && cfgSelAND == false) { + if (selLowPr(track, innerParam) == cfgSelLow || selHighPr(track) == cfgSelHigh) { N_Pr++; pt_Pr = track.pt(); + hist.fill(HIST("QA/Proton/h_Pt"), track.pt()); moments(pt_Pr, Q1_Pr, Q2_Pr, Q3_Pr, Q4_Pr); FillIdParticleQAHistos(track, rapPr, nSigmaTPCPr, nSigmaTOFPr); } - } else if (cfgSelORPr == false && cfgSelANDPr == true) { - if (selLowPr(track, innerParam) == cfgSelLowPr && selHighPr(track) == cfgSelHighPr) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if (selLowPr(track, innerParam) == cfgSelLow && selHighPr(track) == cfgSelHigh) { N_Pr++; pt_Pr = track.pt(); + hist.fill(HIST("QA/Proton/h_Pt"), track.pt()); moments(pt_Pr, Q1_Pr, Q2_Pr, Q3_Pr, Q4_Pr); FillIdParticleQAHistos(track, rapPr, nSigmaTPCPr, nSigmaTOFPr); } @@ -858,8 +892,8 @@ struct meanPtFlucId { int PID = track.mcParticle().pdgCode(); - if (cfgSelORPi == true && cfgSelANDPi == false) { - if (selLowPi(track, innerParam) == cfgSelLowPi || selHighPi(track) == cfgSelHighPi) { + if (cfgSelOR == true && cfgSelAND == false) { + if (selLowPi(track, innerParam) == cfgSelLow || selHighPi(track) == cfgSelHigh) { hist.fill(HIST("QA/Pion/h_allPt"), track.pt()); if (track.sign() > 0) hist.fill(HIST("QA/Pion/h_allPtPos"), track.pt()); @@ -872,8 +906,8 @@ struct meanPtFlucId { FillMCPIDHist(track, PID, kPiPlus, kPiMinus, N_Pi, Q1_Pi, Q2_Pi, Q3_Pi, Q4_Pi); } } - } else if (cfgSelORPi == false && cfgSelANDPi == true) { - if (selLowPi(track, innerParam) == cfgSelLowPi && selHighPi(track) == cfgSelHighPi) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if (selLowPi(track, innerParam) == cfgSelLow && selHighPi(track) == cfgSelHigh) { hist.fill(HIST("QA/Pion/h_allPt"), track.pt()); if (track.sign() > 0) hist.fill(HIST("QA/Pion/h_allPtPos"), track.pt()); @@ -889,8 +923,8 @@ struct meanPtFlucId { } } - if (cfgSelORKa == true && cfgSelANDKa == false) { - if (selLowKa(track, innerParam) == cfgSelLowKa || selHighKa(track) == cfgSelHighKa) { + if (cfgSelOR == true && cfgSelAND == false) { + if (selLowKa(track, innerParam) == cfgSelLow || selHighKa(track) == cfgSelHigh) { hist.fill(HIST("QA/Kaon/h_allPt"), track.pt()); if (track.sign() > 0) hist.fill(HIST("QA/Kaon/h_allPtPos"), track.pt()); @@ -903,8 +937,8 @@ struct meanPtFlucId { FillMCPIDHist(track, PID, kKPlus, kKMinus, N_Ka, Q1_Ka, Q2_Ka, Q3_Ka, Q4_Ka); } } - } else if (cfgSelORKa == false && cfgSelANDKa == true) { - if (selLowKa(track, innerParam) == cfgSelLowKa && selHighKa(track) == cfgSelHighKa) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if (selLowKa(track, innerParam) == cfgSelLow && selHighKa(track) == cfgSelHigh) { hist.fill(HIST("QA/Kaon/h_allPt"), track.pt()); if (track.sign() > 0) hist.fill(HIST("QA/Kaon/h_allPtPos"), track.pt()); @@ -919,8 +953,8 @@ struct meanPtFlucId { } } - if (cfgSelORPr == true && cfgSelANDPr == false) { - if (selLowPr(track, innerParam) == cfgSelLowPr && selHighPr(track) == cfgSelHighPr) { + if (cfgSelOR == true && cfgSelAND == false) { + if (selLowPr(track, innerParam) == cfgSelLow || selHighPr(track) == cfgSelHigh) { hist.fill(HIST("QA/Proton/h_allPt"), track.pt()); if (track.sign() > 0) hist.fill(HIST("QA/Proton/h_allPtPos"), track.pt()); @@ -933,8 +967,8 @@ struct meanPtFlucId { FillMCPIDHist(track, PID, kProton, kProtonBar, N_Pr, Q1_Pr, Q2_Pr, Q3_Pr, Q4_Pr); } } - } else if (cfgSelORPr == false && cfgSelANDPr == true) { - if (selLowPr(track, innerParam) == cfgSelLowPr && selHighPr(track) == cfgSelHighPr) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if (selLowPr(track, innerParam) == cfgSelLow && selHighPr(track) == cfgSelHigh) { hist.fill(HIST("QA/Proton/h_allPt"), track.pt()); if (track.sign() > 0) hist.fill(HIST("QA/Proton/h_allPtPos"), track.pt()); @@ -1025,36 +1059,36 @@ struct meanPtFlucId { hist.fill(HIST("Gen/Charged/h_Pt"), mcParticle.pt()); if (std::abs(PID) == kPiPlus && mcParticle.pt() >= cfgCutPiPtMin) { - if (cfgSelORPi == true && cfgSelANDPi == false) { + if (cfgSelOR == true && cfgSelAND == false) { if (mcParticle.p() <= cfgCutPiThrsldP || mcParticle.p() > cfgCutPiThrsldP) { FillMCPIDHist(mcParticle, PID, kPiPlus, kPiMinus, N_Pi, Q1_Pi, Q2_Pi, Q3_Pi, Q4_Pi); } - } else if (cfgSelORPi == false && cfgSelANDPi == true) { - if ((cfgSelLowPi == true && mcParticle.p() <= cfgCutPiThrsldP) && (cfgSelHighPi == true && mcParticle.p() > cfgCutPiThrsldP)) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if ((cfgSelLow == true && mcParticle.p() <= cfgCutPiThrsldP) && (cfgSelHigh == true && mcParticle.p() > cfgCutPiThrsldP)) { FillMCPIDHist(mcParticle, PID, kPiPlus, kPiMinus, N_Pi, Q1_Pi, Q2_Pi, Q3_Pi, Q4_Pi); } } } if (std::abs(PID) == kKPlus && mcParticle.pt() >= cfgCutKaPtMin) { - if (cfgSelORPi == true && cfgSelANDPi == false) { - if ((cfgSelLowKa == true && mcParticle.p() <= cfgCutPiThrsldP) || (cfgSelHighKa == true && mcParticle.p() > cfgCutPiThrsldP)) { + if (cfgSelOR == true && cfgSelAND == false) { + if ((cfgSelLow == true && mcParticle.p() <= cfgCutPiThrsldP) || (cfgSelHigh == true && mcParticle.p() > cfgCutPiThrsldP)) { FillMCPIDHist(mcParticle, PID, kKPlus, kKMinus, N_Ka, Q1_Ka, Q2_Ka, Q3_Ka, Q4_Ka); } - } else if (cfgSelORKa == false && cfgSelANDKa == true) { - if ((cfgSelLowKa == true && mcParticle.p() <= cfgCutKaThrsldP) && (cfgSelHighKa == true && mcParticle.p() > cfgCutKaThrsldP)) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if ((cfgSelLow == true && mcParticle.p() <= cfgCutKaThrsldP) && (cfgSelHigh == true && mcParticle.p() > cfgCutKaThrsldP)) { FillMCPIDHist(mcParticle, PID, kKPlus, kKMinus, N_Ka, Q1_Ka, Q2_Ka, Q3_Ka, Q4_Ka); } } } if (std::abs(PID) == kProton && mcParticle.pt() >= cfgCutPrPtMin) { - if (cfgSelORPr == true && cfgSelANDPr == false) { - if ((cfgSelLowPr == true && mcParticle.p() <= cfgCutPrThrsldP) || (cfgSelHighPr == true && mcParticle.p() > cfgCutPrThrsldP)) { + if (cfgSelOR == true && cfgSelAND == false) { + if ((cfgSelLow == true && mcParticle.p() <= cfgCutPrThrsldP) || (cfgSelHigh == true && mcParticle.p() > cfgCutPrThrsldP)) { FillMCPIDHist(mcParticle, PID, kProton, kProtonBar, N_Pr, Q1_Pr, Q2_Pr, Q3_Pr, Q4_Pr); } - } else if (cfgSelORPr == false && cfgSelANDPr == true) { - if ((cfgSelLowPr == true && mcParticle.p() <= cfgCutPrThrsldP) && (cfgSelHighPr == true && mcParticle.p() > cfgCutPrThrsldP)) { + } else if (cfgSelOR == false && cfgSelAND == true) { + if ((cfgSelLow == true && mcParticle.p() <= cfgCutPrThrsldP) && (cfgSelHigh == true && mcParticle.p() > cfgCutPrThrsldP)) { FillMCPIDHist(mcParticle, PID, kProton, kProtonBar, N_Pr, Q1_Pr, Q2_Pr, Q3_Pr, Q4_Pr); } } diff --git a/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx b/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx index 191158c7ba0..f4d50ac9c7a 100644 --- a/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/RobustFluctuationObservables.cxx @@ -14,6 +14,9 @@ #include #include +#include +#include +#include #include "TF1.h" #include "TGraphErrors.h" @@ -82,7 +85,7 @@ struct RobustFluctuationObservables { // for vertex vs time: bool flagShowInfo = false; int lastRunNumber = -1; - int nBCsPerOrbit = 3564; + uint64_t nBCsPerOrbit = 3564; // bc position correlations int64_t prevOrbit = -1; @@ -101,7 +104,7 @@ struct RobustFluctuationObservables { int64_t orbitSOR = -1; // int64_t bcSORbis = -1; // global bc of the start of the first orbit - try alternative int64_t nBCsPerTF = 1; // 128*3564; // duration of TF in bcs - int64_t TFid = -1; // count time frames in a given run + uint64_t TFid = 0; // count time frames in a given run bool flagWaitForNewTF = false; uint32_t nOrbitsPerTF = 0; @@ -154,7 +157,7 @@ struct RobustFluctuationObservables { // hand-made ITS ROF cut Configurable nITSROF{"nITSROF", 6, "nITSROF"}; Configurable nITSROF_BC_offset{"nITSROF_BC_offset", 65, "nITSROF_BC_offset"}; - Configurable nITSROF_BC_cutWidth{"nITSROF_BC_cutWidth", 40, "nITSROF_BC_cutWidth"}; + Configurable nITSROF_BC_cutWidth{"nITSROF_BC_cutWidth", 40, "nITSROF_BC_cutWidth"}; // Configurable nITSROF_middle_cut_forITSonlyVert{"nITSROF_middle_cut_forITSonlyVert", 198/2 /*ROF=198 in pp*/, "nITSROF_middle_cut_forITSonlyVert"}; // Configurable nNoITSonlyVertices{"nNoITSonlyVertices", false, "nITSROF_middle_cut_forITSonlyVert"}; @@ -163,7 +166,7 @@ struct RobustFluctuationObservables { Configurable cutVzTrackT0diffUpper{"cutVzTrackT0diffUpper", 1., "cutVzTrackT0diffUpper, cm"}; // splitting of the orbit into several BC ranges - Configurable> vSplitBCpointsOfTheOrbit{"SplitBCpointsOfTheOrbit", {1200, 2000, 3000}, "BC split points of the orbit"}; + Configurable> vSplitBCpointsOfTheOrbit{"SplitBCpointsOfTheOrbit", {1200, 2000, 3000}, "BC split points of the orbit"}; // orbit QA uint32_t orbitAtCollIndexZero = 0; @@ -968,7 +971,7 @@ struct RobustFluctuationObservables { } if (myDF_ID >= 0 && myDF_ID < nHistQAplotsDF) { - int diffOrbits = (int32_t)orbit - (int32_t)orbitAtCollIndexZero; + int diffOrbits = static_cast(orbit) - static_cast(orbitAtCollIndexZero); TString strDF = Form("DF_%d", static_cast(DF_ID_raw)); fV_h1D_Orbit_vs_CollIndex[myDF_ID]->Fill(collision.index(), diffOrbits); fV_h1D_Orbit_vs_CollIndex[myDF_ID]->SetTitle(strDF); @@ -1474,23 +1477,23 @@ struct RobustFluctuationObservables { // ##### check how often we analyze collision in the same BC (and also the vZ difference) if (collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { if (prevBC != 9999) { - int32_t diff = (int32_t)collBC - (int32_t)prevBC; + int32_t diff = static_cast(collBC) - static_cast(prevBC); histosEvent.fill(HIST("hBC_DIFF_to_previous"), diff); if (diff == 0) histosEvent.fill(HIST("hBC_DIFF_to_previous_vZvZ_2D"), vZ, prev_vZ); } if (prevBcInTF >= 0) { - int32_t diffBcInTF = (int32_t)bcInTF - (int32_t)prevBcInTF; + int32_t diffBcInTF = static_cast(bcInTF) - static_cast(prevBcInTF); histosEvent.fill(HIST("hBCinTF_DIFF_to_previous"), diffBcInTF); } if (prevFoundBcInTF >= 0) { - int32_t diffGlobalBcInTF = (int32_t)foundBcInTF - (int32_t)prevFoundBcInTF; + int32_t diffGlobalBcInTF = static_cast(foundBcInTF) - static_cast(prevFoundBcInTF); histosEvent.fill(HIST("hBCinTF_DIFF_to_previous_FOUND_BC"), diffGlobalBcInTF); } // global found BC: if (prevGlobalFoundBC != 9999) { - int32_t diff = (int32_t)globalFoundBC - (int32_t)prevGlobalFoundBC; + int32_t diff = static_cast(globalFoundBC) - static_cast(prevGlobalFoundBC); histosEvent.fill(HIST("hBC_DIFF_to_previous_FOUND_BC"), diff); if (counterPVcontributorsAfterTPCcuts > 0) { @@ -1620,8 +1623,8 @@ struct RobustFluctuationObservables { histosEventBcInTF.fill(HIST("hGlobalTracks_vs_bcInTF"), bcInTF, nTracksGlobalAccepted); } - histosEvent.fill(HIST("hOrbitStartFromCollIndexZeroAft"), (int32_t)orbit - (int32_t)orbitAtCollIndexZero); - histosEvent.fill(HIST("h2D_Orbit_vs_CollIndex_Aft"), collision.index(), (int32_t)orbit - (int32_t)orbitAtCollIndexZero); + histosEvent.fill(HIST("hOrbitStartFromCollIndexZeroAft"), static_cast(orbit) - static_cast(orbitAtCollIndexZero)); + histosEvent.fill(HIST("h2D_Orbit_vs_CollIndex_Aft"), collision.index(), static_cast(orbit) - static_cast(orbitAtCollIndexZero)); histosEvent.fill(HIST("hMF"), magneticField); int MFsign = magneticField > 0 ? +1 : -1; @@ -1680,11 +1683,11 @@ struct RobustFluctuationObservables { histosEvent.fill(HIST("hBCFound_Aft"), globalFoundBC); histosEvent.fill(HIST("h2D_numContrib_vs_BC"), collBC, collision.numContrib()); - int64_t diffFoundBC_vs_BC = (int64_t)globalFoundBC - (int64_t)collBC; + int64_t diffFoundBC_vs_BC = static_cast(globalFoundBC) - static_cast(collBC); histosEvent.fill(HIST("h2D_diffFoundBC_vs_BC"), collBC, diffFoundBC_vs_BC); if (collision.has_foundBC()) - histosEvent.fill(HIST("h2D_diffFoundBC_vs_BC_inTF"), collBC, (int64_t)foundBcInTF - (int64_t)bcInTF); + histosEvent.fill(HIST("h2D_diffFoundBC_vs_BC_inTF"), collBC, static_cast(foundBcInTF) - static_cast(bcInTF)); // with FT0 conditions if (isFT0) { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h index 64e9c339b55..83e9a59d9c1 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h @@ -16,6 +16,7 @@ /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch /// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch +/// \author Shirajum Monira, WUT Warsaw, shirajum.monira@cern.ch #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECASCADESELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECASCADESELECTION_H_ @@ -87,13 +88,13 @@ class FemtoUniverseCascadeSelection public: FemtoUniverseCascadeSelection() - : nPtCascadeMinSel(0), nPtCascadeMaxSel(0), nEtaCascadeMaxSel(0), nDCAV0DaughMax(0), nCPAV0Min(0), nTranRadV0Min(0), nTranRadV0Max(0), nV0DecVtxMax(0), nDCACascadeDaughMax(0), nCPACascadeMin(0), nTranRadCascadeMin(0), nTranRadCascadeMax(0), nDecVtxMax(0), nDCAPosToPV(0), nDCANegToPV(0), nDCABachToPV(0), nDCAV0ToPV(0), pTCascadeMin(9999999.), pTCascadeMax(-9999999.), etaCascadeMax(-9999999.), DCAV0DaughMax(-9999999.), CPAV0Min(9999999.), TranRadV0Min(9999999.), TranRadV0Max(-9999999.), V0DecVtxMax(-9999999.), DCACascadeDaughMax(-9999999.), CPACascadeMin(9999999.), TranRadCascadeMin(9999999.), TranRadCascadeMax(-9999999.), DecVtxMax(-9999999.), DCAPosToPV(9999999.), DCANegToPV(9999999.), DCABachToPV(9999999.), DCAV0ToPV(9999999.), fV0InvMassLowLimit(1.05), fV0InvMassUpLimit(1.3), fInvMassLowLimit(1.25), fInvMassUpLimit(1.4), fRejectOmega(false), fInvMassOmegaLowLimit(1.5), fInvMassOmegaUpLimit(2.0) /*, nSigmaPIDOffsetTPC(0.)*/ + : nPtCascadeMinSel(0), nPtCascadeMaxSel(0), nEtaCascadeMaxSel(0), nDCAV0DaughMax(0), nCPAV0Min(0), nTranRadV0Min(0), nTranRadV0Max(0), nV0DecVtxMax(0), nDCACascadeDaughMax(0), nCPACascadeMin(0), nTranRadCascadeMin(0), nTranRadCascadeMax(0), nDecVtxMax(0), nDCAPosToPV(0), nDCANegToPV(0), nDCABachToPV(0), nDCAV0ToPV(0), pTCascadeMin(9999999.), pTCascadeMax(-9999999.), etaCascadeMax(-9999999.), DCAV0DaughMax(-9999999.), CPAV0Min(9999999.), TranRadV0Min(9999999.), TranRadV0Max(-9999999.), V0DecVtxMax(-9999999.), DCACascadeDaughMax(-9999999.), CPACascadeMin(9999999.), TranRadCascadeMin(9999999.), TranRadCascadeMax(-9999999.), DecVtxMax(-9999999.), DCAPosToPV(9999999.), DCANegToPV(9999999.), DCABachToPV(9999999.), DCAV0ToPV(9999999.), fV0InvMassLowLimit(1.05), fV0InvMassUpLimit(1.3), fInvMassLowLimit(1.25), fInvMassUpLimit(1.4), fRejectCompetingMass(false), fInvMassCompetingLowLimit(1.5), fInvMassCompetingUpLimit(2.0), isCascOmega(false) /*, nSigmaPIDOffsetTPC(0.)*/ { } /// Initializes histograms for the task template - void init(HistogramRegistry* registry); + void init(HistogramRegistry* registry, bool isSelectCascOmega = false); template bool isSelectedMinimal(Col const& col, Casc const& cascade, Track const& posTrack, Track const& negTrack, Track const& bachTrack); @@ -168,11 +169,11 @@ class FemtoUniverseCascadeSelection /// Set limit for the omega rejection on the invariant mass /// \param lowLimit Lower limit for the invariant mass distribution /// \param upLimit Upper limit for the invariant mass distribution - void setOmegaInvMassLimits(float lowLimit, float upLimit) + void setCompetingInvMassLimits(float lowLimit, float upLimit) { - fRejectOmega = true; - fInvMassOmegaLowLimit = lowLimit; - fInvMassOmegaUpLimit = upLimit; + fRejectCompetingMass = true; + fInvMassCompetingLowLimit = lowLimit; + fInvMassCompetingUpLimit = upLimit; } private: @@ -217,9 +218,11 @@ class FemtoUniverseCascadeSelection float fInvMassLowLimit; float fInvMassUpLimit; - float fRejectOmega; - float fInvMassOmegaLowLimit; - float fInvMassOmegaUpLimit; + float fRejectCompetingMass; + float fInvMassCompetingLowLimit; + float fInvMassCompetingUpLimit; + + bool isCascOmega; // float nSigmaPIDOffsetTPC; @@ -259,8 +262,8 @@ class FemtoUniverseCascadeSelection femtoUniverseSelection::kLowerLimit, // DCA v0 to PV max femtoUniverseSelection::kLowerLimit, // v0 mass min femtoUniverseSelection::kUpperLimit, // v0 mass max - }; ///< Map to match a variable with - ///< its type + }; ///< Map to match a variable with + ///< its type static constexpr std::string_view mSelectionHelper[kNcascadeSelection] = { "Cascade particle sign (+1 or -1)", @@ -288,7 +291,7 @@ class FemtoUniverseCascadeSelection }; // namespace femtoUniverse template -void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry) +void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry, bool isSelectCascOmega) { if (registry) { @@ -297,7 +300,7 @@ void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry) fillSelectionHistogram(); // pos, neg fillSelectionHistogram(); // bach - AxisSpec massAxisCascade = {600, 1.25f, 1.4f, "m_{#Cascade} (GeV/#it{c}^{2})"}; + AxisSpec massAxisCascade = {2200, 1.25f, 1.8f, "m_{#Cascade} (GeV/#it{c}^{2})"}; AxisSpec massAxisV0 = {600, 0.0f, 3.0f, "m_{#V0} (GeV/#it{c}^{2})"}; AxisSpec DCADaughAxis = {1000, 0.0f, 2.0f, "DCA (cm)"}; AxisSpec DCAToPVAxis = {1000, -10.0f, 10.0f, "DCA to PV (cm)"}; @@ -410,6 +413,8 @@ void FemtoUniverseCascadeSelection::init(HistogramRegistry* registry) femtoUniverseSelection::kLowerLimit); fV0InvMassUpLimit = getMinimalSelection(femtoUniverseCascadeSelection::kCascadeV0MassMax, femtoUniverseSelection::kUpperLimit); + + isCascOmega = isSelectCascOmega; } template @@ -429,18 +434,18 @@ bool FemtoUniverseCascadeSelection::isSelectedMinimal(Col const& col, Casc const const float cpaCasc = cascade.casccosPA(col.posX(), col.posY(), col.posZ()); const float dcav0topv = cascade.dcav0topv(col.posX(), col.posY(), col.posZ()); const float invMassLambda = cascade.mLambda(); - const float invMassXi = cascade.mXi(); + const float invMass = isCascOmega ? cascade.mOmega() : cascade.mXi(); if (invMassLambda < fV0InvMassLowLimit || invMassLambda > fV0InvMassUpLimit) { return false; } - if (invMassXi < fInvMassLowLimit || invMassXi > fInvMassUpLimit) { + if (invMass < fInvMassLowLimit || invMass > fInvMassUpLimit) { return false; } - if (fRejectOmega) { - const float invMassOmega = cascade.mOmega(); - if (invMassOmega > fInvMassOmegaLowLimit && - invMassOmega < fInvMassOmegaUpLimit) { + if (fRejectCompetingMass) { + const float invMassCompeting = isCascOmega ? cascade.mXi() : cascade.mOmega(); + if (invMassCompeting > fInvMassCompetingLowLimit && + invMassCompeting < fInvMassCompetingUpLimit) { return false; } } @@ -539,10 +544,10 @@ void FemtoUniverseCascadeSelection::fillCascadeQA(Col const& col, Casc const& ca const float dcav0topv = cascade.dcav0topv(col.posX(), col.posY(), col.posZ()); const float invMassLambda = cascade.mLambda(); - const float invMassXi = cascade.mXi(); + const float invMass = isCascOmega ? cascade.mOmega() : cascade.mXi(); mHistogramRegistry->fill(HIST("CascadeQA/hInvMassV0Cut"), invMassLambda); - mHistogramRegistry->fill(HIST("CascadeQA/hInvMassCascadeCut"), invMassXi); + mHistogramRegistry->fill(HIST("CascadeQA/hInvMassCascadeCut"), invMass); mHistogramRegistry->fill(HIST("CascadeQA/hCascadePt"), cascade.pt()); mHistogramRegistry->fill(HIST("CascadeQA/hCascadeEta"), cascade.eta()); mHistogramRegistry->fill(HIST("CascadeQA/hCascadePhi"), cascade.phi()); diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h index 74f5554bde3..957fe316eb7 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h @@ -76,7 +76,6 @@ class FemtoUniverseMath const ROOT::Math::PtEtaPhiMVector vecpart1(part1.pt(), part1.eta(), part1.phi(), mass1); const ROOT::Math::PtEtaPhiMVector vecpart2(part2.pt(), part2.eta(), part2.phi(), mass2); const ROOT::Math::PtEtaPhiMVector trackSum = vecpart1 + vecpart2; - const ROOT::Math::PtEtaPhiMVector trackDiff = vecpart1 - vecpart2; const float beta = trackSum.Beta(); const float betax = beta * std::cos(trackSum.Phi()) * std::sin(trackSum.Theta()); diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h index a99d569fd65..bbddf41aefd 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h @@ -100,6 +100,19 @@ class FemtoUniversePairCleaner return false; } return part1.globalIndex() != part2.globalIndex(); + } else if constexpr (mPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { + /// Track-Cascade combination part1 is hadron and part2 is cascade + if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kCascade) { + LOG(fatal) << "FemtoUniversePairCleaner: passed arguments don't agree with FemtoUniversePairCleaner instantiation! Please provide first argument kTrack candidate and second argument kCascade candidate."; + return false; + } + // Getting cascade children for part2 + const auto& posChild = particles.iteratorAt(part2.index() - 3); + const auto& negChild = particles.iteratorAt(part2.index() - 2); + const auto& bachelor = particles.iteratorAt(part2.index() - 1); + if (part1.globalIndex() == posChild.globalIndex() || part1.globalIndex() == negChild.globalIndex() || part1.globalIndex() == bachelor.globalIndex()) { + return false; + } } else if constexpr (mPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kD0) { /// Track-D0 combination part1 is hadron and part2 is D0 if (part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kD0) { diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index f2465196a6f..7f43c675053 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -31,6 +31,8 @@ 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 DECLARE_SOA_COLUMN(MagField, magField, float); //! Magnetic field of the event +DECLARE_SOA_COLUMN(IRrate, irrate, float); //! Interaction rate +DECLARE_SOA_COLUMN(Occupancy, occupancy, int); //! TPC occupancy } // namespace femtouniversecollision @@ -43,6 +45,11 @@ DECLARE_SOA_TABLE(FDCollisions, "AOD", "FDCOLLISION", femtouniversecollision::MagField); using FDCollision = FDCollisions::iterator; +DECLARE_SOA_TABLE(FDExtCollisions, "AOD", "FDEXTCOLLISION", + femtouniversecollision::IRrate, + femtouniversecollision::Occupancy); +using FDExtCollision = FDExtCollisions::iterator; + /// FemtoUniverseTrack namespace femtouniverseparticle { diff --git a/PWGCF/FemtoUniverse/TableProducer/CMakeLists.txt b/PWGCF/FemtoUniverse/TableProducer/CMakeLists.txt index ecbb6e46873..b82a2e6d6f1 100644 --- a/PWGCF/FemtoUniverse/TableProducer/CMakeLists.txt +++ b/PWGCF/FemtoUniverse/TableProducer/CMakeLists.txt @@ -11,7 +11,7 @@ o2physics_add_dpl_workflow(femtouniverse-producer SOURCES femtoUniverseProducerTask.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(femtouniverse-mctruth-producer diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 30cc8d97278..2482c592275 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -14,6 +14,7 @@ /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch /// \author Malgorzata Janik, WUT Warsaw, majanik@cern.ch +/// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@cern.ch #include #include // FIXME @@ -128,6 +129,7 @@ struct femtoUniverseProducerTask { Configurable ConfIsActivateV0{"ConfIsActivateV0", false, "Activate filling of V0 into femtouniverse tables"}; Configurable ConfActivateSecondaries{"ConfActivateSecondaries", false, "Fill secondary MC gen particles that were reconstructed"}; Configurable ConfIsActivateCascade{"ConfIsActivateCascade", false, "Activate filling of Cascade into femtouniverse tables"}; + Configurable ConfIsSelectCascOmega{"ConfIsSelectCascOmega", false, "Select Omegas for cascade analysis"}; Configurable ConfIsActivatePhi{"ConfIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; Configurable ConfMCTruthAnalysisWithPID{"ConfMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; Configurable> ConfMCTruthPDGCodes{"ConfMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; @@ -251,14 +253,14 @@ struct femtoUniverseProducerTask { Configurable> ConfCascChildTPCnClsMin{"ConfCascChildTPCnClsMin", std::vector{80.f, 70.f, 60.f}, "Cascade Child sel: Min. nCls TPC"}; // Configurable> ConfCascChildDCAMin{"ConfCascChildDCAMin", std::vector{0.05f, 0.06f}, "Cascade Child sel: Max. DCA Daugh to PV (cm)"}; Configurable> ConfCascChildPIDnSigmaMax{"ConfCascChildPIDnSigmaMax", std::vector{3.f, 4.f}, "Cascade Child sel: Max. PID nSigma TPC"}; - Configurable> ConfCascChildPIDspecies{"ConfCascChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "V0 Child sel: Particles species for PID"}; + Configurable> ConfCascChildPIDspecies{"ConfCascChildPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Proton}, "Cascade Child sel: particle species for PID"}; - Configurable ConfCascInvMassLowLimit{"ConfCascInvMassLowLimit", 1.25, "Lower limit of the V0 invariant mass"}; - Configurable ConfCascInvMassUpLimit{"ConfCascInvMassUpLimit", 1.40, "Upper limit of the V0 invariant mass"}; + Configurable ConfCascInvMassLowLimit{"ConfCascInvMassLowLimit", 1.25, "Lower limit of the cascade invariant mass"}; + Configurable ConfCascInvMassUpLimit{"ConfCascInvMassUpLimit", 1.40, "Upper limit of the cascade invariant mass"}; - Configurable ConfCascRejectOmegas{"ConfCascRejectOmegas", false, "Switch on to reject Omegas (for Xi) or Xis (for Omega)"}; - Configurable ConfCascInvOmegaMassLowLimit{"ConfCascInvOmegaMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for Omega rejection"}; - Configurable ConfCascInvOmegaMassUpLimit{"ConfCascInvOmegaMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for Omega rejection"}; + Configurable ConfCascRejectCompetingMass{"ConfCascRejectCompetingMass", false, "Switch on to reject Omegas (for Xi) or Xis (for Omegas)"}; + Configurable ConfCascInvCompetingMassLowLimit{"ConfCascInvCompetingMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for competing mass rejection"}; + Configurable ConfCascInvCompetingMassUpLimit{"ConfCascInvCompetingMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for competing mass rejection"}; } ConfCascadeSelection; // PHI @@ -559,15 +561,15 @@ struct femtoUniverseProducerTask { // TODO cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kPosTrack, ConfV0Selection.ConfChildPIDspecies); cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kNegTrack, ConfV0Selection.ConfChildPIDspecies); - cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kBachTrack, ConfV0Selection.ConfChildPIDspecies); + cascadeCuts.setChildPIDSpecies(femtoUniverseCascadeSelection::kBachTrack, ConfCascadeSelection.ConfCascChildPIDspecies); // check if works correctly for bachelor track - cascadeCuts.init(&cascadeQaRegistry); + cascadeCuts.init(&cascadeQaRegistry, ConfIsSelectCascOmega); // invmass cuts cascadeCuts.setInvMassLimits(ConfCascadeSelection.ConfCascInvMassLowLimit, ConfCascadeSelection.ConfCascInvMassUpLimit); - if (ConfCascadeSelection.ConfCascRejectOmegas) { - cascadeCuts.setOmegaInvMassLimits(ConfCascadeSelection.ConfCascInvOmegaMassLowLimit, ConfCascadeSelection.ConfCascInvOmegaMassUpLimit); + if (ConfCascadeSelection.ConfCascRejectCompetingMass) { + cascadeCuts.setCompetingInvMassLimits(ConfCascadeSelection.ConfCascInvCompetingMassLowLimit, ConfCascadeSelection.ConfCascInvCompetingMassUpLimit); } } @@ -1137,8 +1139,8 @@ struct femtoUniverseProducerTask { 0, 0, indexCascChildID, - casc.mXi(), - casc.mXi(), + ConfIsSelectCascOmega ? casc.mOmega() : casc.mXi(), + ConfIsSelectCascOmega ? casc.mOmega() : casc.mXi(), casc.dcaV0daughters(), casc.v0cosPA(col.posX(), col.posY(), col.posZ()), casc.v0radius(), @@ -1443,7 +1445,7 @@ struct femtoUniverseProducerTask { std::vector tmpPDGCodes = ConfMCTruthPDGCodes; // necessary due to some features of the Configurable for (uint32_t pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { - if ((pdgCode == 333)) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles + if (pdgCode == 333) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles pass = true; } else { if (particle.isPhysicalPrimary() || (ConfActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) @@ -1495,11 +1497,11 @@ struct femtoUniverseProducerTask { if constexpr (resolveDaughs) { childIDs[0] = 0; childIDs[1] = 0; - for (int i = 0; i < tmpIDtrack.size(); i++) { + for (std::size_t i = 0; i < tmpIDtrack.size(); i++) { const auto& particle = tracks.iteratorAt(tmpIDtrack[i] - tracks.begin().globalIndex()); for (int daughIndex = 0, n = std::min(2ul, particle.daughtersIds().size()); daughIndex < n; daughIndex++) { // loop to find the corresponding index of the daughters - for (int j = 0; j < tmpIDtrack.size(); j++) { + for (std::size_t j = 0; j < tmpIDtrack.size(); j++) { if (tmpIDtrack[j] == particle.daughtersIds()[daughIndex]) { childIDs[daughIndex] = i - j; break; @@ -1785,7 +1787,7 @@ struct femtoUniverseProducerTask { void processTrackCentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, - aod::FemtoFullTracks const& tracks) + soa::Filtered const& tracks) { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index feb6495e1cd..04b6424455b 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -70,7 +70,7 @@ struct femtoUniverseEfficiencyBase { /// Particle 1 Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 2212, "Particle 1 - PDG code"}; - Configurable ConfParticleTypePartOne{"ConfParticleTypePartOne", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 1 - particle type: 0 - track, 2 - V0, 6 - phi"}; + Configurable ConfParticleTypePartOne{"ConfParticleTypePartOne", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 1 - particle type: 0 - track, 2 - V0, 6 - phi"}; Configurable ConfNoPDGPartOne{"ConfNoPDGPartOne", false, "0: selecting part one 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"}; @@ -91,7 +91,7 @@ struct femtoUniverseEfficiencyBase { /// Particle 2 Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 333, "Particle 2 - PDG code"}; - Configurable ConfParticleTypePartTwo{"ConfParticleTypePartTwo", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 2 - particle type: 0 - track, 2 - V0, 6 - phi"}; + Configurable ConfParticleTypePartTwo{"ConfParticleTypePartTwo", aod::femtouniverseparticle::ParticleType::kTrack, "Particle 2 - particle type: 0 - track, 2 - V0, 6 - phi"}; Configurable ConfNoPDGPartTwo{"ConfNoPDGPartTwo", false, "0: selecting part two 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"}; @@ -283,7 +283,7 @@ struct femtoUniverseEfficiencyBase { { /// Histogramming same event for (auto& part : grouppartsOneMCGen) { - if (!ConfNoPDGPartOne && part.pidcut() != ConfPDGCodePartOne) { + if (!ConfNoPDGPartOne && part.tempFitVar() != ConfPDGCodePartOne) { continue; } trackHistoPartOneGen.fillQA(part); @@ -291,7 +291,7 @@ struct femtoUniverseEfficiencyBase { if (!ConfIsSame) { for (auto& part : grouppartsTwoMCGen) { - if (!ConfNoPDGPartTwo && part.pidcut() != ConfPDGCodePartTwo) { + if (!ConfNoPDGPartTwo && part.tempFitVar() != ConfPDGCodePartTwo) { continue; } trackHistoPartTwoGen.fillQA(part); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index 3e07257147f..914017c9b7d 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -11,6 +11,7 @@ /// \brief Task for cascade QA; in the future: for cascade correlations /// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch +/// \author Shirajum Monira, WUT Warsaw, shirajum.monira@cern.ch #include #include "Framework/AnalysisTask.h" @@ -55,15 +56,61 @@ struct femtoUniversePairTaskTrackCascadeExtended { Configurable NSigmaTPCPion{"NSigmaTPCPion", 4, "NSigmaTPCPion"}; Configurable NSigmaTPCProton{"NSigmaTPCProton", 4, "NSigmaTPCProton"}; + // configs for correlation part + Configurable ConfTrackChoicePartOne{"ConfTrackChoicePartOne", 0, "0:Proton, 1:Pion, 2:Kaon"}; + Configurable ConfTrkPDGCodePartOne{"ConfTrkPDGCodePartOne", 2212, "Particle 1 (Track) - PDG code"}; + Configurable ConfCascType1{"ConfCascType1", 0, "select one of the V0s (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for track-cascade combination"}; + Configurable ConfChargePart1{"ConfChargePart1", 0, "sign of particle 1"}; + Configurable ConfHPtPart1{"ConfHPtPart1", 4.0f, "higher limit for pt of particle 1"}; + Configurable ConfLPtPart1{"ConfLPtPart1", 0.5f, "lower limit for pt of particle 1"}; + Configurable ConfHPtPart2{"ConfHPtPart2", 4.0f, "higher limit for pt of particle 2"}; + Configurable ConfLPtPart2{"ConfLPtPart2", 0.3f, "lower limit for pt of particle 2"}; + Configurable Confmom{"Confmom", 0.75, "momentum threshold for particle identification using TOF"}; + Configurable ConfNsigmaTPCParticle{"ConfNsigmaTPCParticle", 3.0, "TPC Sigma for particle momentum < Confmom"}; + Configurable ConfNsigmaCombinedParticle{"ConfNsigmaCombinedParticle", 3.0, "TPC and TOF Sigma (combined) for particle momentum > Confmom"}; + + ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; + 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 ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis ConfmultBins3D{"ConfMultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; + Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; + Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histograms in the case of a MonteCarlo Run"}; + Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + 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 ConfTrkTempFitVarpTBins{"ConfTrkTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfTrkTempFitVarBins{"ConfTrkDTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + + /// Partition for particle 1 (track) + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == ConfChargePart1) && (aod::femtouniverseparticle::pt < ConfHPtPart1) && (aod::femtouniverseparticle::pt > ConfLPtPart1); + + /// Partition for particle 2 (cascade) + Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < ConfHPtPart2) && (aod::femtouniverseparticle::pt > ConfLPtPart2); + /// Partition for cascades Partition cascs = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)); + /// Histogramming for track particle + FemtoUniverseParticleHisto trackHistoPartOnePos; + FemtoUniverseParticleHisto trackHistoPartOneNeg; + + /// Histogramming for cascade FemtoUniverseParticleHisto posChildHistos; FemtoUniverseParticleHisto negChildHistos; FemtoUniverseParticleHisto bachHistos; + FemtoUniverseContainer sameEventCont; + FemtoUniverseContainer mixedEventCont; + HistogramRegistry rXiQA{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Table to select cascade daughters + // Charges: = +--, +--, +-+, +-+ + static constexpr UInt_t CascChildTable[][3] = {{0, 1, 2}, {0, 1, 1}, {1, 0, 2}, {1, 0, 1}}; bool invMCascade(float invMassCascade, float invMassAntiCascade) { @@ -73,6 +120,41 @@ struct femtoUniversePairTaskTrackCascadeExtended { return true; } + bool IsNSigmaTPC(float nsigmaTPCParticle) + { + if (TMath::Abs(nsigmaTPCParticle) < ConfNsigmaTPCParticle) { + return true; + } else { + return false; + } + } + + bool IsNSigmaCombined(float mom, float nsigmaTPCParticle, float nsigmaTOFParticle) + { + if (mom <= Confmom) { + return (TMath::Abs(nsigmaTPCParticle) < ConfNsigmaTPCParticle); + } else { + return (TMath::Hypot(nsigmaTOFParticle, nsigmaTPCParticle) < ConfNsigmaCombinedParticle); + } + } + + template + bool IsParticleTPC(const T& part, int id) + { + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + + return IsNSigmaTPC(tpcNSigmas[id]); + } + + template + bool IsParticleCombined(const T& part, int id) + { + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + + return IsNSigmaCombined(part.p(), tpcNSigmas[id], tofNSigmas[id]); + } + void init(InitContext const&) { // Axes @@ -102,9 +184,19 @@ struct femtoUniversePairTaskTrackCascadeExtended { rXiQA.add("hDcaBachtoPV", "hDcaBachtoPV", {HistType::kTH1F, {DCAToPVAxis}}); rXiQA.add("hDcaV0toPV", "hDcaV0toPV", {HistType::kTH1F, {DCAToPVAxis}}); + qaRegistry.add("Tracks_pos/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("Tracks_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("Tracks_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("Tracks_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + + trackHistoPartOnePos.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfIsMC, ConfTrkPDGCodePartOne); + trackHistoPartOneNeg.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfIsMC, ConfTrkPDGCodePartOne); posChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, 0, true); negChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, 0, true); bachHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, 0, true, "hBachelor"); + + sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfEtaBins, ConfPhiBins, ConfIsMC, ConfUse3D); + mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfEtaBins, ConfPhiBins, ConfIsMC, ConfUse3D); } void processCascades(FilteredFDCollision& col, FemtoFullParticles& parts) @@ -168,6 +260,100 @@ struct femtoUniversePairTaskTrackCascadeExtended { } } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processCascades, "Enable processing cascades", true); + + void processSameEvent(FilteredFDCollision& col, FemtoFullParticles& parts) + { + // const auto& magFieldTesla = col.magField(); + + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + for (auto& part : groupPartsTwo) { + if (!invMCascade(part.mLambda(), part.mAntiLambda())) + continue; + const auto& posChild = parts.iteratorAt(part.index() - 3); + const auto& negChild = parts.iteratorAt(part.index() - 2); + const auto& bachelor = parts.iteratorAt(part.index() - 1); + /// Child particles must pass this condition to be selected + /*if (!IsParticleTPC(posChild, CascChildTable[ConfCascType1][0]) || !IsParticleTPC(negChild, CascChildTable[ConfCascType1][1]) || !IsParticleTPC(bachelor, CascChildTable[ConfCascType1][2])) + continue;*/ + + posChildHistos.fillQA(posChild); + negChildHistos.fillQA(negChild); + bachHistos.fillQABase(bachelor, HIST("hBachelor")); + } + + for (auto& part : groupPartsOne) { + /// PID plot for track particle + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + + if (!IsNSigmaCombined(part.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) + continue; + + if (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); + } + } + + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + if (!invMCascade(p2.mLambda(), p2.mAntiLambda())) + continue; + if (!IsParticleCombined(p1, ConfTrackChoicePartOne)) + continue; + // const auto& posChild = parts.iteratorAt(p2.index() - 3); + // const auto& negChild = parts.iteratorAt(p2.index() - 2); + // const auto& bachelor = parts.iteratorAt(p2.index() - 1); + + /// Child particles must pass this condition to be selected + /*if (!IsParticleTPC(posChild, CascChildTable[ConfCascType1][0]) || !IsParticleTPC(negChild, CascChildTable[ConfCascType1][1]) || !IsParticleTPC(bachelor, CascChildTable[ConfCascType1][2])) + continue;*/ + + sameEventCont.setPair(p1, p2, col.multNtr(), ConfUse3D, 1.0f); + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEvent, "Enable processing same event for track - cascade", true); + + void processMixedEvent(FilteredFDCollisions& cols, FemtoFullParticles& /*parts*/) + { + ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + + for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + if (!invMCascade(p2.mLambda(), p2.mAntiLambda())) + continue; + if (!IsParticleCombined(p1, ConfTrackChoicePartOne)) + continue; + + // const auto& posChild = parts.iteratorAt(p2.index() - 3); + // const auto& negChild = parts.iteratorAt(p2.index() - 2); + // const auto& bachelor = parts.iteratorAt(p2.index() - 1); + + /// Child particles must pass this condition to be selected + /*if (!IsParticleTPC(posChild, CascChildTable[ConfCascType1][0]) || !IsParticleTPC(negChild, CascChildTable[ConfCascType1][1]) || !IsParticleTPC(bachelor, CascChildTable[ConfCascType1][2])) + continue;*/ + + mixedEventCont.setPair(p1, p2, collision1.multNtr(), ConfUse3D, 1.0f); + } + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEvent, "Enable processing mixed event for track - cascade", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index c224194e604..f377c2aaa90 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -109,7 +109,7 @@ struct femtoUniversePairTaskTrackD0 { Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; Configurable ConfPDGCodeTrack{"ConfPDGCodeTrack", 2212, "Particle 2 - PDG code"}; 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; @@ -133,7 +133,7 @@ struct femtoUniversePairTaskTrackD0 { } ConfD0D0barSideBand; Configurable> binsPt{"binsPt", std::vector{hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits"}; - Configurable ConfChooseD0trackCorr{"ConfChooseD0trackCorr", 3, "If 0 - only D0s, 1 - only D0bars, 2 - D0/D0bar (one mass hypo.), 3 - all D0/D0bar cand."}; + Configurable ConfChooseD0trackCorr{"ConfChooseD0trackCorr", 3, "If 0 - only D0s, 1 - only D0bars, 2 - D0/D0bar (one mass hypo.), 3 - all D0/D0bar cand."}; Configurable ConfUsePtCutForD0D0bar{"ConfUsePtCutForD0D0bar", false, "Include pT cut for D0/D0bar in same and mixed processes."}; Configurable ConfUseMassCutForD0D0bar{"ConfUseMassCutForD0D0bar", false, "Switch to save D0/D0bar within declared inv. mass range"}; diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index b5b1aeb6296..15aea7eee19 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -17,6 +17,7 @@ /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch #include +#include #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" @@ -72,8 +73,8 @@ struct femtoUniversePairTaskTrackPhi { struct : o2::framework::ConfigurableGroup { Configurable ConfEfficiencyTrackPath{"ConfEfficiencyTrackPath", "", "Local path to proton efficiency TH2F file"}; Configurable ConfEfficiencyPhiPath{"ConfEfficiencyPhiPath", "", "Local path to Phi efficiency TH2F file"}; - Configurable ConfEfficiencyTrackTimestamp{"ConfEfficiencyTrackTimestamp", 0, "(long int) Timestamp for hadron"}; - Configurable ConfEfficiencyPhiTimestamp{"ConfEfficiencyPhiTimestamp", 0, "(long int) Timestamp for phi"}; + Configurable ConfEfficiencyTrackTimestamp{"ConfEfficiencyTrackTimestamp", 0, "(int64_t) Timestamp for hadron"}; + Configurable ConfEfficiencyPhiTimestamp{"ConfEfficiencyPhiTimestamp", 0, "(int64_t) Timestamp for phi"}; } ConfEff; struct : o2::framework::ConfigurableGroup { @@ -438,7 +439,7 @@ struct femtoUniversePairTaskTrackPhi { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); if (!ConfEff.ConfEfficiencyTrackPath.value.empty()) { @@ -584,10 +585,11 @@ struct femtoUniversePairTaskTrackPhi { float mMassTwo = TDatabasePDG::Instance()->GetParticle(-321)->Mass(); // FIXME: Get from the PDG service of the common header for (auto& [kaon1, kaon2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsKaons, groupPartsKaons))) { - if (!IsKaonNSigma(kaon1.p(), trackCuts.getNsigmaTPC(kaon1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(kaon1, o2::track::PID::Kaon))) { - } - if (!IsKaonNSigma(kaon2.p(), trackCuts.getNsigmaTPC(kaon2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(kaon2, o2::track::PID::Kaon))) { - } + // empty if statements commented out on 20241114 to get rid of MegaLinter errors + // if (!IsKaonNSigma(kaon1.p(), trackCuts.getNsigmaTPC(kaon1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(kaon1, o2::track::PID::Kaon))) { + // } + // if (!IsKaonNSigma(kaon2.p(), trackCuts.getNsigmaTPC(kaon2, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(kaon2, o2::track::PID::Kaon))) { + // } if ((kaon1.mAntiLambda() == 1) && (kaon2.mAntiLambda() == 1)) { part1Vec.SetPtEtaPhiM(kaon1.pt(), kaon1.eta(), kaon1.phi(), mMassOne); part2Vec.SetPtEtaPhiM(kaon2.pt(), kaon2.eta(), kaon2.phi(), mMassOne); @@ -765,7 +767,7 @@ struct femtoUniversePairTaskTrackPhi { registryMCtruth.fill(HIST("MCtruthKp"), part.pt(), part.eta()); registryMCtruth.fill(HIST("MCtruthKpPt"), part.pt()); } - if ((pdgCode == 333)) { + if (pdgCode == 333) { registryMCtruth.fill(HIST("MCtruthPhi"), part.pt(), part.eta()); continue; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index 3b1dcce4d73..4810c79298d 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -15,6 +15,8 @@ /// \author Shirajum Monira, WUT Warsaw, shirajum.monira.dokt@pw.edu.pl #include +#include +#include #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" @@ -152,6 +154,8 @@ struct femtoUniversePairTaskTrackV0Extended { HistogramRegistry registryMCtruth{"MCtruthHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry registryMCreco{"MCrecoHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + std::unique_ptr plocalEffFile; std::unique_ptr plocalEffp1; std::unique_ptr plocalEffp2; @@ -220,6 +224,8 @@ struct femtoUniversePairTaskTrackV0Extended { posChildV0Type2.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, 0, true, "posChildV0Type2"); negChildV0Type2.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, 0, true, "negChildV0Type2"); + MixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + // MC truth registryMCtruth.add("plus/MCtruthLambda", "MC truth Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCtruth.add("minus/MCtruthLambda", "MC truth Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); @@ -511,7 +517,7 @@ struct femtoUniversePairTaskTrackV0Extended { PROCESS_SWITCH(femtoUniversePairTaskTrackV0Extended, processMCSameEvent, "Enable processing same event for MC truth track - V0", false); /// This function processes MC same events for V0 - V0 - void processMCSameEventV0(FilteredFDCollision& col, FemtoFullParticles& parts) + void processMCSameEventV0(FilteredFDCollision& col, FemtoFullParticles& /*parts*/) { auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); const int multCol = ConfUseCent ? col.multV0M() : col.multNtr(); @@ -555,10 +561,10 @@ struct femtoUniversePairTaskTrackV0Extended { template void doMixedEvent(FilteredFDCollisions& cols, PartType& parts, PartitionType& partitionOne, PartitionType& partitionTwo, [[maybe_unused]] MCParticles mcParts = nullptr) { - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; - - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + ColumnBinningPolicy colBinningMult{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinningCent{{ConfVtxBins, ConfMultBins}, true}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { const int multCol = ConfUseCent ? collision1.multV0M() : collision1.multNtr(); auto groupPartsOne = partitionOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); @@ -568,7 +574,7 @@ struct femtoUniversePairTaskTrackV0Extended { const auto& magFieldTesla2 = collision2.magField(); if (magFieldTesla1 != magFieldTesla2) { - continue; + return; } for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { @@ -603,6 +609,18 @@ struct femtoUniversePairTaskTrackV0Extended { else mixedEventCont.setPair(p1, p2, multCol, ConfUse3D, weight); } + }; + + if (ConfUseCent) { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } } } @@ -621,10 +639,10 @@ struct femtoUniversePairTaskTrackV0Extended { /// This function processes the mixed event for V0 - V0 void processMixedEventV0(FilteredFDCollisions& cols, FemtoFullParticles& parts) { - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; - - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + ColumnBinningPolicy colBinningMult{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinningCent{{ConfVtxBins, ConfMultBins}, true}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { const int multCol = ConfUseCent ? collision1.multV0M() : collision1.multNtr(); auto groupPartsOne = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); @@ -634,16 +652,18 @@ struct femtoUniversePairTaskTrackV0Extended { const auto& magFieldTesla2 = collision2.magField(); if (magFieldTesla1 != magFieldTesla2) { - continue; + return; } for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { // Lambda invariant mass cut for p1 - if (!invMLambda(p1.mLambda(), p1.mAntiLambda())) + if (!invMLambda(p1.mLambda(), p1.mAntiLambda())) { continue; + } // Lambda invariant mass cut for p2 - if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) + if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) { continue; + } const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2); const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1); @@ -668,6 +688,18 @@ struct femtoUniversePairTaskTrackV0Extended { } mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); } + }; + + if (ConfUseCent) { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } } } PROCESS_SWITCH(femtoUniversePairTaskTrackV0Extended, processMixedEventV0, "Enable processing mixed events for V0 - V0", false); @@ -675,10 +707,10 @@ struct femtoUniversePairTaskTrackV0Extended { /// This function processes MC mixed events for Track - V0 void processMCMixedEvent(FilteredFDCollisions& cols, FemtoFullParticles& parts) { - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; - - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + ColumnBinningPolicy colBinningMult{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinningCent{{ConfVtxBins, ConfMultBins}, true}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { const int multCol = ConfUseCent ? collision1.multV0M() : collision1.multNtr(); auto groupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); @@ -688,7 +720,7 @@ struct femtoUniversePairTaskTrackV0Extended { const auto& magFieldTesla2 = collision2.magField(); if (magFieldTesla1 != magFieldTesla2) { - continue; + return; } for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { if (static_cast(p1.pidcut()) != ConfTrkPDGCodePartOne) @@ -703,18 +735,30 @@ struct femtoUniversePairTaskTrackV0Extended { } mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); } + }; + + if (ConfUseCent) { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } } } PROCESS_SWITCH(femtoUniversePairTaskTrackV0Extended, processMCMixedEvent, "Enable processing mixed events for MC truth track - V0", false); /// This function processes MC mixed events for V0 - V0 - void processMCMixedEventV0(FilteredFDCollisions& cols, FemtoFullParticles& parts) + void processMCMixedEventV0(FilteredFDCollisions& cols, FemtoFullParticles& /*parts*/) { - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; - - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + ColumnBinningPolicy colBinningMult{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinningCent{{ConfVtxBins, ConfMultBins}, true}; + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { const int multCol = ConfUseCent ? collision1.multV0M() : collision1.multNtr(); auto groupPartsOne = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); @@ -729,6 +773,18 @@ struct femtoUniversePairTaskTrackV0Extended { continue; mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); } + }; + + if (ConfUseCent) { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, 5, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } } } diff --git a/PWGCF/Flow/TableProducer/ZDCQvectors.cxx b/PWGCF/Flow/TableProducer/ZDCQvectors.cxx index 82202d86e3d..f8cfb02a8a4 100644 --- a/PWGCF/Flow/TableProducer/ZDCQvectors.cxx +++ b/PWGCF/Flow/TableProducer/ZDCQvectors.cxx @@ -82,15 +82,16 @@ std::vector hZN_mean(10, nullptr); // Get from calibration file std::vector mean_10perCent_v(4, nullptr); // hQXA, hQYA, hQXC, hQYC // step2: Small bins 1D -std::vector mean_1perCent_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC -std::vector mean_vx_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC -std::vector mean_vy_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC -std::vector mean_vz_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC +std::vector mean_cent_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC +std::vector mean_vx_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC +std::vector mean_vy_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC +std::vector mean_vz_Run(4, nullptr); // hQXA, hQYA, hQXC, hQYC // Define histogrm names here to use same names for creating and later uploading and retrieving data from ccdb // Energy calibration: std::vector names_Ecal(10, ""); std::vector> names(5, std::vector()); //(1x 4d 4x 1d) +std::vector vnames = {"hvertex_vx", "hvertex_vy"}; // https://alice-notes.web.cern.ch/system/files/notes/analysis/620/017-May-31-analysis_note-ALICE_analysis_note_v2.pdf std::vector ZDC_px = {-1.75, 1.75, -1.75, 1.75}; @@ -98,7 +99,7 @@ std::vector ZDC_py = {-1.75, -1.75, 1.75, 1.75}; double alphaZDC = 0.395; // step 0 tm 5 A&C -std::vector>> q(5, std::vector>(7, std::vector(4, 0.0))); // 5 iterations with 5 steps, each with 4 values +std::vector>> q(6, std::vector>(7, std::vector(4, 0.0))); // 5 iterations with 5 steps, each with 4 values // for energy calibration std::vector EZN(8); // uncalibrated energy for the 2x4 towers (a1, a2, a3, a4, c1, c2, c3, c4) @@ -108,6 +109,7 @@ std::vector e(8, 0.); // calibrated energies (a1, a2, a3, a4, c1, c2, // Define variables needed to do the recentring steps. double centrality = 0; int runnumber = 0; +int lastRunnumber = 0; std::vector v(3, 0); // vx, vy, vz bool isSelected = false; @@ -122,13 +124,12 @@ struct ZDCqvectors { ConfigurableAxis axisCent{"axisCent", {90, 0, 90}, "Centrality axis in 1% bins"}; ConfigurableAxis axisCent10{"axisCent10", {9, 0, 90}, "Centrality axis in 10% bins"}; ConfigurableAxis axisQ{"axisQ", {100, -2, 2}, "Q vector (xy) in ZDC"}; - ConfigurableAxis axisVx_big{"axisVx_big", {3, -0.006, -0.006}, "for Pos X of collision"}; - ConfigurableAxis axisVy_big{"axisVy_big", {3, -0.003, 0.003}, "for Pos Y of collision"}; + ConfigurableAxis axisVx_big{"axisVx_big", {3, -0.01, 0.01}, "for Pos X of collision"}; + ConfigurableAxis axisVy_big{"axisVy_big", {3, -0.01, 0.01}, "for Pos Y of collision"}; ConfigurableAxis axisVz_big{"axisVz_big", {3, -10, 10}, "for Pos Z of collision"}; - ConfigurableAxis axisVx{"axisVx", {10, -0.006, 0.006}, "for Pos X of collision"}; - ConfigurableAxis axisVy{"axisVy", {10, -0.003, 0.003}, "for Pos Y of collision"}; + ConfigurableAxis axisVx{"axisVx", {10, -0.01, 0.01}, "for Pos X of collision"}; + ConfigurableAxis axisVy{"axisVy", {10, -0.01, 0.01}, "for Pos Y of collision"}; ConfigurableAxis axisVz{"axisVz", {10, -10, 1}, "for vz of collision"}; - ConfigurableAxis axisRun{"axisRun", {1e6, 0, 1e6}, "for runNumber in ThnSparse"}; O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range") O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMin, float, 0.2f, "Minimal.q pT for poi tracks") @@ -140,10 +141,12 @@ struct ZDCqvectors { O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field; default CCDB will be queried") O2_DEFINE_CONFIGURABLE(cfgEnergyCal, std::string, "", "ccdb path for energy calibration histos") O2_DEFINE_CONFIGURABLE(cfgMeanv, std::string, "", "ccdb path for mean v histos") + Configurable> cfgRec1{"cfgRec1", {"", "", "", "", ""}, "ccdb paths for recentering calibration histos iteration 1"}; Configurable> cfgRec2{"cfgRec2", {"", "", "", "", ""}, "ccdb paths for recentering calibration histos iteration 2"}; Configurable> cfgRec3{"cfgRec3", {"", "", "", "", ""}, "ccdb paths for recentering calibration histos iteration 3"}; Configurable> cfgRec4{"cfgRec4", {"", "", "", "", ""}, "ccdb paths for recentering calibration histos iteration 4"}; + Configurable> cfgRec5{"cfgRec5", {"", "", "", "", ""}, "ccdb paths for recentering calibration histos iteration 5"}; // Define output HistogramRegistry registry{"Registry"}; @@ -179,6 +182,8 @@ struct ZDCqvectors { // Qx_vs_Qy for each step for ZNA and ZNC for (int step = 0; step < 6; step++) { + registry.add(Form("step%i/QA/hSPplaneA", step), "hSPplaneA", kTH2D, {{100, -4, 4}, axisCent10}); + registry.add(Form("step%i/QA/hSPplaneC", step), "hSPplaneC", kTH2D, {{100, -4, 4}, axisCent10}); for (const char* side : sides) { hQx_vs_Qy[step] = registry.add(Form("step%i/hZN%s_Qx_vs_Qy", step, side), Form("hZN%s_Qx_vs_Qy", side), kTH2F, {axisQ, axisQ}); } @@ -202,28 +207,28 @@ struct ZDCqvectors { if (step == 1 || step == 5) { TString name = TString::Format("hQ%s%s_mean_Cent_V_run", coord, side); - registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_Cent_V_run", coord, side), {HistType::kTHnSparseD, {axisRun, axisCent10, axisVx_big, axisVy_big, axisVz_big, axisQ}}); + registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_Cent_V_run", coord, side), {HistType::kTHnSparseD, {axisCent10, axisVx_big, axisVy_big, axisVz_big, axisQ}}); if (step == 1) names[step - 1].push_back(name); } if (step == 2) { - TString name = TString::Format("hQ%s%s_mean_1percent_run", coord, side); - registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_1percent_run", coord, side), kTProfile2D, {{1, 0., 1.}, axisCent}); + TString name = TString::Format("hQ%s%s_mean_cent_run", coord, side); + registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_cent_run", coord, side), kTProfile, {axisCent}); names[step - 1].push_back(name); } if (step == 3) { TString name = TString::Format("hQ%s%s_mean_vx_run", coord, side); - registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_vx_run", coord, side), kTProfile2D, {{1, 0., 1.}, axisVx}); + registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_vx_run", coord, side), kTProfile, {axisVx}); names[step - 1].push_back(name); } if (step == 4) { TString name = TString::Format("hQ%s%s_mean_vy_run", coord, side); - registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_vy_run", coord, side), kTProfile2D, {{1, 0., 1.}, axisVy}); + registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_vy_run", coord, side), kTProfile, {axisVy}); names[step - 1].push_back(name); } if (step == 5) { TString name = TString::Format("hQ%s%s_mean_vz_run", coord, side); - registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_vz_run", coord, side), kTProfile2D, {{1, 0., 1.}, axisVz}); + registry.add(Form("step%i/%s", step, name.Data()), Form("hQ%s%s_mean_vz_run", coord, side), kTProfile, {axisVz}); names[step - 1].push_back(name); } } // end of COORDS @@ -233,6 +238,13 @@ struct ZDCqvectors { // recentered q-vectors (to check what steps are finished in the end) registry.add("hStep", "hStep", {HistType::kTH1D, {{10, 0., 10.}}}); registry.add("hIteration", "hIteration", {HistType::kTH1D, {{10, 0., 10.}}}); + registry.add("vmean/hvertex_vx", "hvertex_vx", kTProfile, {{1, 0., 1.}}); + registry.add("vmean/hvertex_vy", "hvertex_vy", kTProfile, {{1, 0., 1.}}); + registry.add("QA/centrality_before", "centrality_before", kTH1D, {{200, 0, 100}}); + registry.add("QA/centrality_after", "centrality_after", kTH1D, {{200, 0, 100}}); + + registry.add("QA/ZNA_Energy", "ZNA_Energy", kTProfile, {{8, 0, 8}}); + registry.add("QA/ZNC_Energy", "ZNC_Energy", kTProfile, {{8, 0, 8}}); } inline void fillRegistry(int iteration, int step) @@ -248,42 +260,42 @@ struct ZDCqvectors { } if (step == 1) { - registry.get(HIST("step2/hQXA_mean_1percent_run"))->Fill(Form("%d", runnumber), centrality, q[iteration][step][0], 1); - registry.get(HIST("step2/hQYA_mean_1percent_run"))->Fill(Form("%d", runnumber), centrality, q[iteration][step][1], 1); - registry.get(HIST("step2/hQXC_mean_1percent_run"))->Fill(Form("%d", runnumber), centrality, q[iteration][step][2], 1); - registry.get(HIST("step2/hQYC_mean_1percent_run"))->Fill(Form("%d", runnumber), centrality, q[iteration][step][3], 1); + registry.get(HIST("step2/hQXA_mean_cent_run"))->Fill(centrality, q[iteration][step][0]); + registry.get(HIST("step2/hQYA_mean_cent_run"))->Fill(centrality, q[iteration][step][1]); + registry.get(HIST("step2/hQXC_mean_cent_run"))->Fill(centrality, q[iteration][step][2]); + registry.get(HIST("step2/hQYC_mean_cent_run"))->Fill(centrality, q[iteration][step][3]); registry.fill(HIST("hStep"), step, 1); } if (step == 2) { - registry.get(HIST("step3/hQXA_mean_vx_run"))->Fill(Form("%d", runnumber), v[0], q[iteration][step][0], 1); - registry.get(HIST("step3/hQYA_mean_vx_run"))->Fill(Form("%d", runnumber), v[0], q[iteration][step][1], 1); - registry.get(HIST("step3/hQXC_mean_vx_run"))->Fill(Form("%d", runnumber), v[0], q[iteration][step][2], 1); - registry.get(HIST("step3/hQYC_mean_vx_run"))->Fill(Form("%d", runnumber), v[0], q[iteration][step][3], 1); + registry.get(HIST("step3/hQXA_mean_vx_run"))->Fill(v[0], q[iteration][step][0]); + registry.get(HIST("step3/hQYA_mean_vx_run"))->Fill(v[0], q[iteration][step][1]); + registry.get(HIST("step3/hQXC_mean_vx_run"))->Fill(v[0], q[iteration][step][2]); + registry.get(HIST("step3/hQYC_mean_vx_run"))->Fill(v[0], q[iteration][step][3]); registry.fill(HIST("hStep"), step, 1); } if (step == 3) { - registry.get(HIST("step4/hQXA_mean_vy_run"))->Fill(Form("%d", runnumber), v[1], q[iteration][step][0], 1); - registry.get(HIST("step4/hQYA_mean_vy_run"))->Fill(Form("%d", runnumber), v[1], q[iteration][step][1], 1); - registry.get(HIST("step4/hQXC_mean_vy_run"))->Fill(Form("%d", runnumber), v[1], q[iteration][step][2], 1); - registry.get(HIST("step4/hQYC_mean_vy_run"))->Fill(Form("%d", runnumber), v[1], q[iteration][step][3], 1); + registry.get(HIST("step4/hQXA_mean_vy_run"))->Fill(v[1], q[iteration][step][0]); + registry.get(HIST("step4/hQYA_mean_vy_run"))->Fill(v[1], q[iteration][step][1]); + registry.get(HIST("step4/hQXC_mean_vy_run"))->Fill(v[1], q[iteration][step][2]); + registry.get(HIST("step4/hQYC_mean_vy_run"))->Fill(v[1], q[iteration][step][3]); registry.fill(HIST("hStep"), step, 1); } if (step == 4) { - registry.get(HIST("step5/hQXA_mean_vz_run"))->Fill(Form("%d", runnumber), v[2], q[iteration][step][0], 1); - registry.get(HIST("step5/hQYA_mean_vz_run"))->Fill(Form("%d", runnumber), v[2], q[iteration][step][1], 1); - registry.get(HIST("step5/hQXC_mean_vz_run"))->Fill(Form("%d", runnumber), v[2], q[iteration][step][2], 1); - registry.get(HIST("step5/hQYC_mean_vz_run"))->Fill(Form("%d", runnumber), v[2], q[iteration][step][3], 1); + registry.get(HIST("step5/hQXA_mean_vz_run"))->Fill(v[2], q[iteration][step][0]); + registry.get(HIST("step5/hQYA_mean_vz_run"))->Fill(v[2], q[iteration][step][1]); + registry.get(HIST("step5/hQXC_mean_vz_run"))->Fill(v[2], q[iteration][step][2]); + registry.get(HIST("step5/hQYC_mean_vz_run"))->Fill(v[2], q[iteration][step][3]); registry.fill(HIST("hStep"), step, 1); } if (step == 5) { - registry.fill(HIST("step5/hQXA_mean_Cent_V_run"), runnumber, centrality, v[0], v[1], v[2], q[iteration][step][0]); - registry.fill(HIST("step5/hQYA_mean_Cent_V_run"), runnumber, centrality, v[0], v[1], v[2], q[iteration][step][1]); - registry.fill(HIST("step5/hQXC_mean_Cent_V_run"), runnumber, centrality, v[0], v[1], v[2], q[iteration][step][2]); - registry.fill(HIST("step5/hQYC_mean_Cent_V_run"), runnumber, centrality, v[0], v[1], v[2], q[iteration][step][3]); + registry.fill(HIST("step5/hQXA_mean_Cent_V_run"), centrality, v[0], v[1], v[2], q[iteration][step][0]); + registry.fill(HIST("step5/hQYA_mean_Cent_V_run"), centrality, v[0], v[1], v[2], q[iteration][step][1]); + registry.fill(HIST("step5/hQXC_mean_Cent_V_run"), centrality, v[0], v[1], v[2], q[iteration][step][2]); + registry.fill(HIST("step5/hQYC_mean_Cent_V_run"), centrality, v[0], v[1], v[2], q[iteration][step][3]); registry.fill(HIST("hStep"), step, 1); } } @@ -353,6 +365,13 @@ struct ZDCqvectors { registry.fill(HIST(subdir[index]) + HIST("QA/hQYA_vs_vz"), v[2], q[iteration][index_rt][1]); registry.fill(HIST(subdir[index]) + HIST("QA/hQXC_vs_vz"), v[2], q[iteration][index_rt][2]); registry.fill(HIST(subdir[index]) + HIST("QA/hQYC_vs_vz"), v[2], q[iteration][index_rt][3]); + + // add psi!! + double Psi_A = 1.0 * TMath::ATan2(q[iteration][index_rt][2], q[iteration][index_rt][0]); + registry.fill(HIST(subdir[index]) + HIST("QA/hSPplaneA"), Psi_A, centrality, 1); + double Psi_C = 1.0 * TMath::ATan2(q[iteration][index_rt][3], q[iteration][index_rt][1]); + registry.fill(HIST(subdir[index]) + HIST("QA/hSPplaneC"), Psi_C, centrality, 1); + }); } @@ -365,7 +384,7 @@ struct ZDCqvectors { cal.calibList[iteration][step] = ccdb->getForTimeStamp(ccdb_dir, timestamp); if (cal.calibList[iteration][step]) { - for (int i = 0; i < names.size(); i++) { + for (std::size_t i = 0; i < names.size(); i++) { TObject* obj = reinterpret_cast(cal.calibList[iteration][step]->FindObject(Form("%s", names[i].Data()))); if (!obj) { if (counter < 1) { @@ -426,7 +445,7 @@ struct ZDCqvectors { double getCorrection(int iteration, int step, const char* objName) { T* hist = nullptr; - double calibConstant; + double calibConstant{0}; hist = reinterpret_cast(cal.calibList[iteration][step]->FindObject(Form("%s", objName))); if (!hist) { @@ -434,33 +453,38 @@ struct ZDCqvectors { } if (hist->InheritsFrom("TProfile2D")) { - if (counter < 1) - LOGF(info, "correction is TProfile2D %s for q[%i][%i]", objName, iteration, step); + // needed for energy calibration! TProfile2D* h = reinterpret_cast(hist); + TString name = h->GetName(); int binrunnumber = h->GetXaxis()->FindBin(TString::Format("%i", runnumber)); - int bincentrality = h->GetYaxis()->FindBin(centrality); - calibConstant = h->GetBinContent(binrunnumber, bincentrality); + int bin = h->GetYaxis()->FindBin(centrality); + calibConstant = h->GetBinContent(binrunnumber, bin); + } else if (hist->InheritsFrom("TProfile")) { - if (counter < 1) - LOGF(info, "correction is TProfile %s for q[%i][%i]", objName, iteration, step); TProfile* h = reinterpret_cast(hist); - int binrunnumber = h->GetXaxis()->FindBin(TString::Format("%i", runnumber)); - calibConstant = h->GetBinContent(binrunnumber); + TString name = h->GetName(); + int bin; + if (name.Contains("mean_vx")) + bin = h->GetXaxis()->FindBin(v[0]); + if (name.Contains("mean_vy")) + bin = h->GetXaxis()->FindBin(v[1]); + if (name.Contains("mean_vz")) + bin = h->GetXaxis()->FindBin(v[2]); + if (name.Contains("mean_cent")) + bin = h->GetXaxis()->FindBin(centrality); + if (name.Contains("vertex")) + bin = h->GetXaxis()->FindBin(TString::Format("%i", runnumber)); + calibConstant = h->GetBinContent(bin); } else if (hist->InheritsFrom("THnSparse")) { - if (counter < 1) - LOGF(info, "correction is THnSparse %s for q[%i][%i]", objName, iteration, step); std::vector sparsePars; - if (counter < 1) - LOGF(info, "correction is THnSparse %s for q[%i][%i]", objName, iteration, step); THnSparseD* h = reinterpret_cast(hist); if (step == 0 && iteration > 0) { - sparsePars.push_back(h->GetAxis(0)->FindBin(runnumber)); sparsePars.push_back(h->GetAxis(1)->FindBin(centrality)); sparsePars.push_back(h->GetAxis(2)->FindBin(v[0])); sparsePars.push_back(h->GetAxis(3)->FindBin(v[1])); sparsePars.push_back(h->GetAxis(4)->FindBin(v[2])); } - for (int i = 0; i < sparsePars.size(); i++) { + for (std::size_t i = 0; i < sparsePars.size(); i++) { h->GetAxis(i)->SetRange(sparsePars[i], sparsePars[i]); } calibConstant = h->Projection(sparsePars.size())->GetMean(); @@ -493,14 +517,18 @@ struct ZDCqvectors { auto cent = collision.centFT0C(); if (cent < 0 || cent > 90) { - SPtableZDC(0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, 0); + SPtableZDC(runnumber, cent, v[0], v[1], v[2], 0, 0, 0, 0, false, 0, 0); + lastRunnumber = runnumber; return; } + registry.fill(HIST("QA/centrality_before"), cent); + const auto& foundBC = collision.foundBC_as(); if (!foundBC.has_zdc()) { - SPtableZDC(0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, 0); + SPtableZDC(runnumber, cent, v[0], v[1], v[2], 0, 0, 0, 0, false, 0, 0); + lastRunnumber = runnumber; return; } @@ -518,12 +546,22 @@ struct ZDCqvectors { } // load the calibration histos for iteration 0 step 0 (Energy Calibration) - loadCalibrations(0, 0, foundBC.timestamp(), cfgEnergyCal, names_Ecal); + if (runnumber != lastRunnumber) + loadCalibrations(0, 0, foundBC.timestamp(), cfgEnergyCal, names_Ecal); if (!cal.calibfilesLoaded[0][0]) { if (counter < 1) { LOGF(info, " --> No Energy calibration files found.. -> Only Energy calibration will be done. "); } } + // load the calibrations for the mean v + if (runnumber != lastRunnumber) + loadCalibrations(0, 1, foundBC.timestamp(), cfgMeanv, vnames); + if (!cal.calibfilesLoaded[0][1]) { + if (counter < 1) + LOGF(warning, " --> No mean V found.. -> THis wil lead to wrong axis for vx, vy (will be created in vmean/)"); + registry.get(HIST("vmean/hvertex_vx"))->Fill(Form("%d", runnumber), v[0]); + registry.get(HIST("vmean/hvertex_vy"))->Fill(Form("%d", runnumber), v[1]); + } if (counter < 1) LOGF(info, "=====================> .....Start Energy Calibration..... <====================="); @@ -563,13 +601,15 @@ struct ZDCqvectors { // if ZNA or ZNC not hit correctly.. do not use event in q-vector calculation if (!isZNAhit || !isZNChit) { counter++; - SPtableZDC(0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, 0); + SPtableZDC(runnumber, centrality, v[0], v[1], v[2], 0, 0, 0, 0, false, 0, 0); + lastRunnumber = runnumber; return; } if (!cal.calibfilesLoaded[0][0]) { counter++; - SPtableZDC(0, 0, 0, 0, 0, 0, 0, 0, 0, false, 0, 0); + SPtableZDC(runnumber, centrality, v[0], v[1], v[2], 0, 0, 0, 0, false, 0, 0); + lastRunnumber = runnumber; return; } @@ -598,6 +638,14 @@ struct ZDCqvectors { calibtower++; } + for (int i = 0; i < 4; i++) { + float bincenter = i + .5; + registry.fill(HIST("QA/ZNA_Energy"), bincenter, EZN[i]); + registry.fill(HIST("QA/ZNA_Energy"), bincenter + 4, e[i]); + registry.fill(HIST("QA/ZNC_Energy"), bincenter, EZN[i + 4]); + registry.fill(HIST("QA/ZNC_Energy"), bincenter + 4, e[i + 4]); + } + // Now calculate Q-vector for (int tower = 0; tower < 8; tower++) { int side = (tower > 3) ? 1 : 0; @@ -616,19 +664,30 @@ struct ZDCqvectors { } } - for (int iteration = 1; iteration < 5; iteration++) { - std::vector ccdb_dirs; - if (iteration == 1) - ccdb_dirs = cfgRec1.value; - if (iteration == 2) - ccdb_dirs = cfgRec2.value; - if (iteration == 3) - ccdb_dirs = cfgRec3.value; - if (iteration == 4) - ccdb_dirs = cfgRec4.value; - - for (int step = 0; step < 5; step++) { - loadCalibrations(iteration, step, foundBC.timestamp(), (ccdb_dirs)[step], names[step]); + if (cal.calibfilesLoaded[0][1]) { + if (counter < 1) + LOGF(info, "=====================> Setting v to vmean!"); + v[0] = v[0] - getCorrection(0, 1, vnames[0].Data()); + v[1] = v[1] - getCorrection(0, 1, vnames[1].Data()); + } + + if (runnumber != lastRunnumber) { + for (int iteration = 1; iteration < 6; iteration++) { + std::vector ccdb_dirs; + if (iteration == 1) + ccdb_dirs = cfgRec1.value; + if (iteration == 2) + ccdb_dirs = cfgRec2.value; + if (iteration == 3) + ccdb_dirs = cfgRec3.value; + if (iteration == 4) + ccdb_dirs = cfgRec4.value; + if (iteration == 5) + ccdb_dirs = cfgRec5.value; + + for (int step = 0; step < 5; step++) { + loadCalibrations(iteration, step, foundBC.timestamp(), (ccdb_dirs)[step], names[step]); + } } } @@ -637,6 +696,7 @@ struct ZDCqvectors { LOGF(warning, "Calibation files missing!!! Output created with q-vectors right after energy gain eq. !!"); fillAllRegistries(0, 0); SPtableZDC(runnumber, centrality, v[0], v[1], v[2], q[0][0][0], q[0][0][1], q[0][0][2], q[0][0][3], true, 0, 0); + lastRunnumber = runnumber; counter++; return; } else { @@ -651,7 +711,7 @@ struct ZDCqvectors { q[iteration][step + 1][i] = q[iteration - 1][5][i] - getCorrection(iteration, step, names[step][i].Data()); } } else { - q[iteration][step + 1][i] = q[iteration][step][i] - getCorrection(iteration, step, names[step][i].Data()); + q[iteration][step + 1][i] = q[iteration][step][i] - getCorrection(iteration, step, names[step][i].Data()); } } } else { @@ -662,9 +722,11 @@ struct ZDCqvectors { } // end of iteration if (counter < 1) - LOGF(warning, "Calibation files missing!!! Output created with q-vectors at iteration %i and step %i!!!!", cal.atIteration, cal.atStep + 1); + LOGF(info, "Output created with q-vectors at iteration %i and step %i!!!!", cal.atIteration, cal.atStep + 1); fillAllRegistries(cal.atIteration, cal.atStep + 1); + registry.fill(HIST("QA/centrality_after"), centrality); SPtableZDC(runnumber, centrality, v[0], v[1], v[2], q[cal.atIteration][cal.atStep][0], q[cal.atIteration][cal.atStep][1], q[cal.atIteration][cal.atStep][2], q[cal.atIteration][cal.atStep][3], true, cal.atIteration, cal.atStep); + lastRunnumber = runnumber; counter++; return; } diff --git a/PWGCF/Flow/Tasks/FlowGFWPbPb.cxx b/PWGCF/Flow/Tasks/FlowGFWPbPb.cxx index 23442a4ee0b..39cddafbd2a 100644 --- a/PWGCF/Flow/Tasks/FlowGFWPbPb.cxx +++ b/PWGCF/Flow/Tasks/FlowGFWPbPb.cxx @@ -162,7 +162,7 @@ struct FlowGFWPbPb { ccdb->setCreatedNotAfter(nolaterthan.value); // Add some output objects to the histogram registry - registry.add("hEventCount", "Number of Events;; No. of Events", {HistType::kTH1D, {{kNOOFEVENTSTEPS, -0.5, kNOOFEVENTSTEPS - 0.5}}}); + registry.add("hEventCount", "Number of Events;; No. of Events", {HistType::kTH1D, {{kNOOFEVENTSTEPS, -0.5, +kNOOFEVENTSTEPS - 0.5}}}); registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kFILTERED + 1, "Filtered events"); registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kSEL8 + 1, "Sel8"); registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(kOCCUPANCY + 1, "Occupancy"); diff --git a/PWGCF/Flow/Tasks/FlowRunbyRun.cxx b/PWGCF/Flow/Tasks/FlowRunbyRun.cxx index d24350df022..02f006f2c3c 100644 --- a/PWGCF/Flow/Tasks/FlowRunbyRun.cxx +++ b/PWGCF/Flow/Tasks/FlowRunbyRun.cxx @@ -36,6 +36,7 @@ #include "GFW.h" #include "GFWCumulant.h" #include "GFWWeights.h" +#include "FlowContainer.h" #include "TList.h" #include #include @@ -60,6 +61,8 @@ struct FlowRunbyRun { O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Use Nch for flow observables") Configurable> cfgRunNumbers{"cfgRunNumbers", std::vector{544095, 544098, 544116, 544121, 544122, 544123, 544124}, "Preconfigured run numbers"}; + Configurable> cfgUserDefineGFWCorr{"cfgUserDefineGFWCorr", std::vector{"refN10 {2} refP10 {-2}"}, "User defined GFW CorrelatorConfig"}; + Configurable> cfgUserDefineGFWName{"cfgUserDefineGFWName", std::vector{"Ch10Gap22"}, "User defined GFW Name"}; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; @@ -76,11 +79,15 @@ struct FlowRunbyRun { Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; // Define output + OutputObj fFC{FlowContainer("FlowContainer")}; HistogramRegistry registry{"registry"}; // define global variables GFW* fGFW = new GFW(); std::vector corrconfigs; + std::vector corrconfigsFC; + TAxis* fPtAxis; + TRandom3* fRndm = new TRandom3(0); std::vector RunNumbers; // vector of run numbers std::map>> TH1sList; // map of histograms for all runs std::map>> ProfilesList; // map of profiles for all runs @@ -114,12 +121,43 @@ struct FlowRunbyRun { CreateOutputObjectsForRun(runNumber); } + o2::framework::AxisSpec axis = axisPt; + int nPtBins = axis.binEdges.size() - 1; + double* PtBins = &(axis.binEdges)[0]; + fPtAxis = new TAxis(nPtBins, PtBins); + + // Create FlowContainer + TObjArray* oba = new TObjArray(); + std::vector UserDefineGFWCorr = cfgUserDefineGFWCorr; + std::vector UserDefineGFWName = cfgUserDefineGFWName; + if (!UserDefineGFWCorr.empty() && !UserDefineGFWName.empty()) { + for (uint i = 0; i < UserDefineGFWName.size(); i++) { + oba->Add(new TNamed(UserDefineGFWName.at(i).c_str(), UserDefineGFWName.at(i).c_str())); + } + } + fFC->SetName("FlowContainer"); + fFC->SetXAxis(fPtAxis); + fFC->Initialize(oba, axisIndependent, 1); + delete oba; + fGFW->AddRegion("full", -0.8, 0.8, 1, 1); fGFW->AddRegion("refN10", -0.8, -0.5, 1, 1); fGFW->AddRegion("refP10", 0.5, 0.8, 1, 1); corrconfigs.resize(kCount_TProfileNames); corrconfigs[c22] = fGFW->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE); corrconfigs[c22_gap10] = fGFW->GetCorrelatorConfig("refN10 {2} refP10 {-2}", "Ch10Gap22", kFALSE); + if (!UserDefineGFWCorr.empty() && !UserDefineGFWName.empty()) { + LOGF(info, "User adding GFW CorrelatorConfig:"); + // attentaion: here we follow the index of cfgUserDefineGFWCorr + for (uint i = 0; i < UserDefineGFWCorr.size(); i++) { + if (i >= UserDefineGFWName.size()) { + LOGF(fatal, "The names you provided are more than configurations. UserDefineGFWName.size(): %d > UserDefineGFWCorr.size(): %d", UserDefineGFWName.size(), UserDefineGFWCorr.size()); + break; + } + LOGF(info, "%d: %s %s", i, UserDefineGFWCorr.at(i).c_str(), UserDefineGFWName.at(i).c_str()); + corrconfigsFC.push_back(fGFW->GetCorrelatorConfig(UserDefineGFWCorr.at(i).c_str(), UserDefineGFWName.at(i).c_str(), kFALSE)); + } + } fGFW->CreateRegions(); } @@ -139,6 +177,29 @@ struct FlowRunbyRun { return; } + void FillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm) + { + double dnx, val; + dnx = fGFW->Calculate(corrconf, 0, kTRUE).real(); + if (dnx == 0) + return; + if (!corrconf.pTDif) { + val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm); + return; + } + for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) { + dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real(); + if (dnx == 0) + continue; + val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx; + if (TMath::Abs(val) < 1) + fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm); + } + return; + } + void CreateOutputObjectsForRun(int runNumber) { std::vector> histos(kCount_TH1Names); @@ -164,6 +225,7 @@ struct FlowRunbyRun { // detect run number auto bc = collision.bc_as(); int runNumber = bc.runNumber(); + float l_Random = fRndm->Rndm(); if (std::find(RunNumbers.begin(), RunNumbers.end(), runNumber) == RunNumbers.end()) { // if run number is not in the preconfigured list, create new output histograms for this run CreateOutputObjectsForRun(runNumber); @@ -185,7 +247,6 @@ struct FlowRunbyRun { for (auto& track : tracks) { TH1sList[runNumber][hPhi]->Fill(track.phi()); TH1sList[runNumber][hEta]->Fill(track.eta()); - bool WithinPtPOI = (cfgCutPtPOIMin < track.pt()) && (track.pt() < cfgCutPtPOIMax); // within POI pT range bool WithinPtRef = (cfgCutPtRefMin < track.pt()) && (track.pt() < cfgCutPtRefMax); // within RF pT range if (WithinPtRef) { fGFW->Fill(track.eta(), 1, track.phi(), wacc * weff, 1); @@ -196,6 +257,10 @@ struct FlowRunbyRun { for (uint i = 0; i < kCount_TProfileNames; ++i) { FillProfile(corrconfigs[i], ProfilesList[runNumber][i], cent); } + // Filling Flow Container + for (uint l_ind = 0; l_ind < corrconfigsFC.size(); l_ind++) { + FillFC(corrconfigsFC.at(l_ind), cent, l_Random); + } } }; diff --git a/PWGCF/Flow/Tasks/FlowTask.cxx b/PWGCF/Flow/Tasks/FlowTask.cxx index 7639b4af2d7..0f4d6977855 100644 --- a/PWGCF/Flow/Tasks/FlowTask.cxx +++ b/PWGCF/Flow/Tasks/FlowTask.cxx @@ -248,13 +248,15 @@ struct FlowTask { // add in FlowContainer to Get boostrap sample automatically TObjArray* oba = new TObjArray(); oba->Add(new TNamed("ChGap22", "ChGap22")); - for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) - oba->Add(new TNamed(Form("ChGap22_pt_%i", i + 1), "ChGap22_pTDiff")); oba->Add(new TNamed("ChFull22", "ChFull22")); oba->Add(new TNamed("ChFull32", "ChFull32")); oba->Add(new TNamed("ChFull42", "ChFull42")); oba->Add(new TNamed("ChFull24", "ChFull24")); oba->Add(new TNamed("ChFull26", "ChFull26")); + for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("ChFull22_pt_%i", i + 1), "ChFull22_pTDiff")); + for (Int_t i = 0; i < fPtAxis->GetNbins(); i++) + oba->Add(new TNamed(Form("ChFull24_pt_%i", i + 1), "ChFull24_pTDiff")); oba->Add(new TNamed("Ch04Gap22", "Ch04Gap22")); oba->Add(new TNamed("Ch06Gap22", "Ch06Gap22")); oba->Add(new TNamed("Ch08Gap22", "Ch08Gap22")); @@ -324,8 +326,10 @@ struct FlowTask { fGFW->AddRegion("refM", -0.4, 0.4, 1, 1); fGFW->AddRegion("poiN", -0.8, -0.4, 1 + fPtAxis->GetNbins(), 2); fGFW->AddRegion("poiN10", -0.8, -0.5, 1 + fPtAxis->GetNbins(), 2); + fGFW->AddRegion("poifull", -0.8, 0.8, 1 + fPtAxis->GetNbins(), 2); fGFW->AddRegion("olN", -0.8, -0.4, 1, 4); fGFW->AddRegion("olN10", -0.8, -0.5, 1, 4); + fGFW->AddRegion("olfull", -0.8, 0.8, 1, 4); corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {2 -2}", "ChFull22", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("full {3 -3}", "ChFull32", kFALSE)); @@ -348,7 +352,8 @@ struct FlowTask { corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN10 {4} refP10 {-4}", "Ch10Gap42", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN12 {4} refP12 {-4}", "Ch12Gap42", kFALSE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("refN {2} refP {-2}", "ChGap22", kFALSE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN refN | olN {2} refP {-2}", "ChGap22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifull full | olfull {2 -2}", "ChFull22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poifull full | olfull {2 2 -2 -2}", "ChFull24", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN10 refN10 | olN10 {2} refP10 {-2}", "Ch10Gap22", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN10 refN10 | olN10 {3} refP10 {-3}", "Ch10Gap32", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiN10 refN10 | olN10 {4} refP10 {-4}", "Ch10Gap42", kTRUE)); @@ -546,13 +551,6 @@ struct FlowTask { // no collisions in specified time range 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(); auto occupancy = collision.trackOccupancyInTimeRange(); if (cfgEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) diff --git a/PWGCF/Flow/Tasks/FlowZDCtask.cxx b/PWGCF/Flow/Tasks/FlowZDCtask.cxx index fbb6e068cf6..7efdeff3d05 100644 --- a/PWGCF/Flow/Tasks/FlowZDCtask.cxx +++ b/PWGCF/Flow/Tasks/FlowZDCtask.cxx @@ -70,15 +70,19 @@ struct FlowZDCtask { Configurable nBinsADC{"nBinsADC", 1000, "nbinsADC"}; Configurable nBinsAmp{"nBinsAmp", 1025, "nbinsAmp"}; Configurable MaxZN{"MaxZN", 4099.5, "Max ZN signal"}; + Configurable acceptnace_ZNA{"acceptnace_ZNA", 0.92, "ZNA acceptance factor"}; + Configurable acceptnace_ZNC{"acceptnace_ZNC", 0.90, "ZNC acceptance factor"}; + Configurable acceptnace_ZPA{"acceptnace_ZPA", 0.52, "ZPA acceptance factor"}; + Configurable acceptnace_ZPC{"acceptnace_ZPC", 0.50, "ZPC acceptance factor"}; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"}; ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"}; ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.25, 0.30, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.20, 2.40, 2.60, 2.80, 3.00}, "pt axis for histograms"}; ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "centrality axis for histograms"}; + ConfigurableAxis axisEnergy{"axisEnergy", {100, 0, 700}, "energy axis for zdc histos"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); - Partition tracksIUWithTPC = (aod::track::tpcNClsFindable > (uint8_t)0); TComplex qTPC; // init q TPC @@ -101,11 +105,10 @@ struct FlowZDCtask { OutputObj ZDC_ZEM_Energy{TProfile("ZDC_ZEM_Energy", "ZDC vs ZEM Energy", 10, 0, 1000)}; OutputObj pCosPsiDifferences{TProfile("pCosPsiDifferences", "Differences in cos(psi) vs Centrality;Centrality;Mean cos(psi) Difference", 200, 0, 100, -1, 1)}; OutputObj pSinPsiDifferences{TProfile("pSinPsiDifferences", "Differences in sin(psi) vs Centrality;Centrality;Mean sin(psi) Difference", 200, 0, 100, -1, 1)}; - OutputObj pZNvsFT0MAmp{TProfile("pZNvsFT0MAmp", "ZN Energy vs FT0M Amplitude", 100, 0, 50000, 0, 500)}; - OutputObj pZPvsFT0MAmp{TProfile("pZPvsFT0MAmp", "ZP Energy vs FT0M Amplitude", 100, 0, 50000, 0, 500)}; - - OutputObj pZNvsFT0Ccent{TProfile("pZNvsFT0Ccent", "ZN Energy vs FT0C Centrality", 100, 0, 100, 0, 50000)}; - OutputObj pZPvsFT0Ccent{TProfile("pZPvsFT0Ccent", "ZP Energy vs FT0C Centrality", 100, 0, 100, 0, 50000)}; + OutputObj pZNvsFT0MAmp{TProfile("pZNvsFT0MAmp", "ZN Energy vs FT0M Amplitude", 1025, 0, 1e7, 0, 500)}; + OutputObj pZPvsFT0MAmp{TProfile("pZPvsFT0MAmp", "ZP Energy vs FT0M Amplitude", 1025, 0, 1e7, 0, 500)}; + OutputObj pZNvsFT0Ccent{TProfile("pZNvsFT0Ccent", "ZN Energy vs FT0C Centrality", 100, 0, 100, 0, 500)}; + OutputObj pZPvsFT0Ccent{TProfile("pZPvsFT0Ccent", "ZP Energy vs FT0C Centrality", 100, 0, 100, 0, 500)}; OutputObj pZNratiovscent{TProfile("pZNratiovscent", "Ratio ZNC/ZNA vs FT0C Centrality", 100, 0, 100, 0, 5)}; OutputObj pZPratiovscent{TProfile("pZPratiovscent", "Ratio ZPC/ZPA vs FT0C Centrality", 100, 0, 100, 0, 5)}; @@ -126,7 +129,6 @@ struct FlowZDCtask { const AxisSpec axisQZNA{100, -1, 1, "Q"}; const AxisSpec axisREQ{100, -1, 1, "real Q"}; const AxisSpec axisIMQ{100, -1, 1, "imag Q"}; - const AxisSpec axisEnergy{100, 0, 50000., "energy"}; AxisSpec axisVtxcounts{2, -0.5f, 1.5f, "Vtx info (0=no, 1=yes)"}; AxisSpec axisZvert{120, -30.f, 30.f, "Vtx z (cm)"}; @@ -159,6 +161,15 @@ struct FlowZDCtask { histos.add("EnergyZNA", "ZNA Sector Energy", kTH1F, {axisEnergy}); histos.add("EnergyZNC", "ZNC Sector Energy", kTH1F, {axisEnergy}); histos.add("hCentFT0C", "FT0C Centrality Distribution", kTH1F, {{100, 0, 105}}); + histos.add("hZNvsFT0Ccent", + "ZN Energy vs FT0C Centrality;Centrality [%];ZN Energy [TeV]", + kTH2F, + {AxisSpec{100, 0, 100, "Centrality [%]"}, AxisSpec{100, 0, 500, "ZN Energy [TeV]"}}); + + histos.add("hZPvsFT0Ccent", + "ZP Energy vs FT0C Centrality;Centrality [%];ZP Energy [TeV]", + kTH2F, + {AxisSpec{100, 0, 100, "Centrality [%]"}, AxisSpec{100, 0, 500, "ZP Energy [TeV]"}}); // for q vector recentering histos.add("revsimag", "revsimag", kTH2F, {axisREQ, axisIMQ}); @@ -193,9 +204,9 @@ struct FlowZDCtask { histos.add("ZPAenergy", "ZP energy side a", kTH1F, {axisEnergy}); histos.add("ZNenergy", "common zn (a + c sides) energy", kTH1F, {axisEnergy}); histos.add("ZPenergy", "common zp energy (a + c sides)", kTH1F, {axisEnergy}); - histos.add("hFT0CAmp", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 10000000}}); - histos.add("hFT0AAmp", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 10000000}}); - histos.add("hFT0MAmp", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 10000000}}); + histos.add("hFT0CAmp", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 1e7}}); + histos.add("hFT0AAmp", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 1e7}}); + histos.add("hFT0MAmp", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 1e7}}); histos.add("hMultT0A", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 250000}}); histos.add("hMultT0C", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 250000}}); histos.add("hMultT0M", ";Amplitude;counts", kTH1F, {{nBinsAmp, 0, 250000}}); @@ -249,7 +260,7 @@ struct FlowZDCtask { ColEvSels const& cols, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcs*/, - aod::FT0s const& ft0s) + aod::FT0s const& /*ft0s*/) { double sumCosPsiDiff = 0.0; // initialize Sum of cosPsiDiff for averaging double sumSinPsiDiff = 0.0; // initialize Sum of cosPsiDiff for averaging @@ -305,10 +316,10 @@ struct FlowZDCtask { float sumZEM = zdcread.amplitudeZEM1() + zdcread.amplitudeZEM2(); // common energies - float common_sumZNC = (zdcread.energyCommonZNC()); - float common_sumZNA = (zdcread.energyCommonZNA()); - float common_sumZPC = (zdcread.energyCommonZPC()); - float common_sumZPA = (zdcread.energyCommonZPA()); + float common_sumZNC = (zdcread.energyCommonZNC()) / acceptnace_ZNC; + float common_sumZNA = (zdcread.energyCommonZNA()) / acceptnace_ZNA; + float common_sumZPC = (zdcread.energyCommonZPC()) / acceptnace_ZPC; + float common_sumZPA = (zdcread.energyCommonZPA()) / acceptnace_ZPA; float sumZN = (sumZNC) + (sumZNA); float sumZP = (sumZPC) + (sumZPA); @@ -318,7 +329,8 @@ struct FlowZDCtask { histos.fill(HIST("ZNAenergy"), common_sumZNA); histos.fill(HIST("ZPAenergy"), common_sumZPA); histos.fill(HIST("ZPCenergy"), common_sumZPC); - + histos.fill(HIST("hZNvsFT0Ccent"), cent, sumZN); + histos.fill(HIST("hZPvsFT0Ccent"), cent, sumZP); float ratioZN = sumZNC / sumZNA; float ratioZP = sumZPC / sumZPA; pZNratiovscent->Fill(cent, ratioZN); diff --git a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx index 43a6eff399d..874f0c3d2df 100644 --- a/PWGCF/Flow/Tasks/flowPtEfficiency.cxx +++ b/PWGCF/Flow/Tasks/flowPtEfficiency.cxx @@ -14,11 +14,15 @@ /// \author everyone #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" #include "Framework/ASoAHelpers.h" #include "Framework/HistogramRegistry.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" using namespace o2; using namespace o2::framework; @@ -32,18 +36,38 @@ struct flowPtEfficiency { O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "Minimal pT for tracks") O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 3.0f, "Maximal pT for tracks") O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") + O2_DEFINE_CONFIGURABLE(cfgTrkSelRun3ITSMatch, bool, false, "GlobalTrackRun3ITSMatching::Run3ITSall7Layers selection") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 70.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCcrossedrows, float, 70.0f, "minimum TPC crossed rows") O2_DEFINE_CONFIGURABLE(cfgCutDCAxy, float, 0.2f, "DCAxy cut for tracks") + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "DCAz cut for tracks") + O2_DEFINE_CONFIGURABLE(cfgCutDCAxyppPass3Enabled, bool, false, "switch of ppPass3 DCAxy pt dependent cut") + O2_DEFINE_CONFIGURABLE(cfgCutDCAzPtDepEnabled, bool, false, "switch of DCAz pt dependent cut") + O2_DEFINE_CONFIGURABLE(cfgSelRunNumberEnabled, bool, false, "switch of run number selection") + Configurable> cfgRunNumberList{"cfgRunNumberList", std::vector{-1}, "runnumber list in consideration for analysis"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.25, 0.30, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.20, 2.40, 2.60, 2.80, 3.00}, "pt axis for histograms"}; // Filter the tracks - Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (nabs(aod::track::dcaXY) < cfgCutDCAxy); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls); using myTracks = soa::Filtered>; + // Filter for collisions + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + using myCollisions = soa::Filtered>; + // Filter for MCParticle Filter particleFilter = (nabs(aod::mcparticle::eta) < cfgCutEta) && (aod::mcparticle::pt > cfgCutPtMin) && (aod::mcparticle::pt < cfgCutPtMax); using myMcParticles = soa::Filtered; + // Filter for MCcollisions + Filter mccollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVertex; + using myMcCollisions = soa::Filtered; + + // Additional filters for tracks + TrackSelection myTrackSel; + // Define the output HistogramRegistry registry{"registry"}; @@ -71,13 +95,46 @@ struct flowPtEfficiency { registry.add("mcEventCounter", "Monte Carlo Truth EventCounter", kTH1F, {axisCounter}); registry.add("hPtMCGen", "Monte Carlo Truth", {HistType::kTH1D, {axisPt}}); + + if (cfgTrkSelRun3ITSMatch) { + myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSall7Layers, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + } else { + myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + } + if (cfgCutDCAxyppPass3Enabled) { + myTrackSel.SetMaxDcaXYPtDep([](float pt) { return 0.004f + 0.013f / pt; }); + } else { + myTrackSel.SetMaxDcaXY(cfgCutDCAxy); + } + myTrackSel.SetMinNClustersTPC(cfgCutTPCclu); + myTrackSel.SetMinNCrossedRowsTPC(cfgCutTPCcrossedrows); + if (!cfgCutDCAzPtDepEnabled) + myTrackSel.SetMaxDcaZ(cfgCutDCAz); } - void processReco(o2::aod::Collision const&, myTracks const& tracks, aod::McParticles const&) + template + bool trackSelected(TTrack track) + { + if (cfgCutDCAzPtDepEnabled && (track.dcaZ() > (0.004f + 0.013f / track.pt()))) + return false; + return myTrackSel.IsSelected(track); + } + + void processReco(myCollisions::iterator const& collision, aod::BCsWithTimestamps const&, myTracks const& tracks, aod::McParticles const&) { registry.fill(HIST("eventCounter"), 0.5); + if (!collision.sel8()) + return; + if (tracks.size() < 1) + return; + if (cfgSelRunNumberEnabled) { + auto bc = collision.bc_as(); + int RunNumber = bc.runNumber(); + if (!std::count(cfgRunNumberList.value.begin(), cfgRunNumberList.value.end(), RunNumber)) + return; + } for (const auto& track : tracks) { - if (track.tpcNClsCrossedRows() < 70) + if (!trackSelected(track)) continue; if (track.has_mcParticle()) { auto mcParticle = track.mcParticle(); @@ -89,8 +146,14 @@ struct flowPtEfficiency { } PROCESS_SWITCH(flowPtEfficiency, processReco, "process reconstructed information", true); - void processSim(aod::McCollision const&, soa::SmallGroups> const& collisions, myMcParticles const& mcParticles) + void processSim(myMcCollisions::iterator const& collision, aod::BCsWithTimestamps const&, soa::SmallGroups> const& collisions, myMcParticles const& mcParticles) { + if (cfgSelRunNumberEnabled) { + auto bc = collision.bc_as(); + int RunNumber = bc.runNumber(); + if (!std::count(cfgRunNumberList.value.begin(), cfgRunNumberList.value.end(), RunNumber)) + return; + } if (collisions.size() > -1) { registry.fill(HIST("mcEventCounter"), 0.5); for (const auto& mcParticle : mcParticles) { diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h index d2bc6c08c8c..201115e2241 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-Configurables.h @@ -26,19 +26,20 @@ struct : ConfigurableGroup { Configurable cfVerboseForEachParticle{"cfVerboseForEachParticle", false, "run or not in verbose mode (also for function calls per particle)"}; Configurable cfDoAdditionalInsanityChecks{"cfDoAdditionalInsanityChecks", false, "do additional insanity checks at run time (this leads to small loss of performance)"}; Configurable cfInsanityCheckForEachParticle{"cfInsanityCheckForEachParticle", false, "do insanity checks at run time for each particle, at the expense of losing a lot of performance. Use only during debugging."}; - Configurable cfUseCCDB{"cfUseCCDB", true, "if requested, access personal files from CCDB (true) or from home dir in AliEn (false)"}; Configurable cfRandomSeed{"cfRandomSeed", 0, "0 = random seed is guaranteed to be unique in space and time"}; Configurable cfUseFisherYates{"cfUseFisherYates", false, "use or not Fisher-Yates algorithm to randomize particle indices"}; Configurable cfFixedNumberOfRandomlySelectedTracks{"cfFixedNumberOfRandomlySelectedTracks", -1, "set to some integer > 0, to apply and use. Set to <=0, to ignore."}; Configurable cfUseStopwatch{"cfUseStopwatch", false, "if true, some basic info on time execution is printed, here and there. Very loosely, this can be used for execution time profiling."}; Configurable cfFloatingPointPrecision{"cfFloatingPointPrecision", 0.000001, "two floats are the same if TMath::Abs(f1 - f2) < fFloatingPointPrecision"}; + Configurable cfSequentialBailout{"cfSequentialBailout", 0, "if fSequentialBailout > 0, then each fSequentialBailout events the function BailOut() is called. Can be used for real analysis and for IV"}; + } cf_tc; // *) QA: struct : ConfigurableGroup { Configurable cfCheckUnderflowAndOverflow{"cfCheckUnderflowAndOverflow", false, "check and bail out if in event and particle histograms there are entries which went to underflow or overflow bins (use only locally)"}; Configurable cfFillQAEventHistograms2D{"cfFillQAEventHistograms2D", false, "if false, all QA 2D event histograms are not filled. if true, only the ones for which fBookQAEventHistograms2D[...] is true, are filled"}; - Configurable> cfBookQAEventHistograms2D{"cfBookQAEventHistograms2D", {"MultTPC_vs_NContributors-1", "Vertex_z_vs_MultTPC-1", "Vertex_z_vs_NContributors-1", "CentFT0M_vs_CentNTPV-1", "CentRun2V0M_vs_CentRun2SPDTracklets-1", "CentRun2V0M_vs_NContributors-1", "TrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange-1", "TrackOccupancyInTimeRange_vs_MultTPC-1", "TrackOccupancyInTimeRange_vs_Vertex_z-1"}, "book (1) or do not book (0) this QA 2D event histogram"}; + Configurable> cfBookQAEventHistograms2D{"cfBookQAEventHistograms2D", {"MultTPC_vs_NContributors-1", "MultTPC_vs_Centrality-1", "Vertex_z_vs_MultTPC-1", "Vertex_z_vs_NContributors-1", "CentFT0C_vs_CentNTPV-1", "CentFT0M_vs_CentNTPV-1", "CentRun2V0M_vs_CentRun2SPDTracklets-1", "CentRun2V0M_vs_NContributors-1", "TrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange-1", "TrackOccupancyInTimeRange_vs_MultTPC-1", "TrackOccupancyInTimeRange_vs_Vertex_z-1", "TrackOccupancyInTimeRange_vs_Centrality-1"}, "book (1) or do not book (0) this QA 2D event histogram"}; Configurable cfFillQAParticleHistograms2D{"cfFillQAParticleHistograms2D", false, "if false, all QA 2D particle histograms are not filled. if true, only the ones for which fBookQAParticleHistograms2D[...] is true, are filled"}; Configurable> cfBookQAParticleHistograms2D{"cfBookQAParticleHistograms2D", {"Pt_vs_dcaXY-1"}, "book (1) or do not book (0) this QA 2D particle histogram"}; } cf_qa; @@ -74,7 +75,7 @@ struct : ConfigurableGroup { Configurable cfTrigger{"cfTrigger", "some supported trigger", "set here some supported trigger (kINT7, ...) "}; Configurable cfUseSel7{"cfUseSel7", false, "use for Run 1 and 2 data and MC (see official doc)"}; Configurable cfUseSel8{"cfUseSel8", false, "use for Run 3 data and MC (see official doc)"}; - Configurable cfCentralityEstimator{"cfCentralityEstimator", "some supported centrality estimator", "set here some supported centrality estimator (CentFT0M, CentFV0A, CentNTPV, ... for Run 3, and CentRun2V0M, CentRun2SPDTracklets, ..., for Run 2 and 1) "}; + Configurable cfCentralityEstimator{"cfCentralityEstimator", "some supported centrality estimator", "set here some supported centrality estimator (CentFT0C, CentFT0M, CentFV0A, CentNTPV, ... for Run 3, and CentRun2V0M, CentRun2SPDTracklets, ..., for Run 2 and 1) "}; Configurable> cfSelectedEvents{"cfSelectedEvents", {-1, 1000000000}, "Selected number of events to process (i.e. only events which survive event cuts): {min, max}, with convention: min <= N < max"}; Configurable cfUseNoSameBunchPileup{"cfUseNoSameBunchPileup", false, "TBI 20240521 explanation"}; Configurable cfUseIsGoodZvtxFT0vsPV{"cfUseIsGoodZvtxFT0vsPV", false, "TBI 20240521 explanation"}; @@ -89,7 +90,7 @@ struct : ConfigurableGroup { Configurable cfFillParticleHistograms{"cfFillParticleHistograms", true, "if false, all 1D particle histograms are not filled. if kTRUE, the ones for which fBookParticleHistograms[...] is kTRUE, are filled"}; Configurable> cfBookParticleHistograms{"cfBookParticleHistograms", {"Phi-1", "Pt-1", "Eta-1", "Charge-1", "tpcNClsFindable-1", "tpcNClsShared-1", "tpcNClsFound-1", "tpcNClsCrossedRows-1", "itsNCls-1", "itsNClsInnerBarrel-1", "tpcCrossedRowsOverFindableCls-1", "tpcFoundOverFindableCls-1", "tpcFractionSharedCls-1", "dcaXY-1", "dcaZ-1", "PDG-1"}, "Book (1) or do not book (0) particle histogram"}; Configurable cfFillParticleHistograms2D{"cfFillParticleHistograms2D", true, "if false, all 2D particle histograms are not filled. if kTRUE, the ones for which fBookParticleHistograms2D[...] is kTRUE, are filled"}; - Configurable> cfBookParticleHistograms2D{"cfBookParticleHistograms2D", {"Phi_vs_Pt-1", "Phi_vs_Eta-1"}, "Book (1) or do not book (0) this 2D particle histogram"}; + Configurable> cfBookParticleHistograms2D{"cfBookParticleHistograms2D", {"Phi_vs_Pt-1", "Phi_vs_Eta-1"}, "Book (1) or do not book (0) 2D particle histograms"}; } cf_ph; // *) Particle cuts: @@ -149,6 +150,7 @@ struct : ConfigurableGroup { Configurable cfCalculateTest0AsFunctionOfEta{"cfCalculateTest0AsFunctionOfEta", false, "calculate or not Test0 as a function of eta"}; Configurable cfCalculateTest0AsFunctionOfOccupancy{"cfCalculateTest0AsFunctionOfOccupancy", false, "calculate or not Test0 as a function of occupancy"}; Configurable cfFileWithLabels{"cfFileWithLabels", "/home/abilandz/DatasetsO2/labels.root", "path to external ROOT file which specifies all labels"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" + Configurable cfUseDefaultLabels{"cfUseDefaultLabels", false, "use default internally hardwired labels, only for testing purposes"}; } cf_t0; // *) Particle weights: @@ -161,6 +163,12 @@ struct : ConfigurableGroup { Configurable cfFileWithWeights{"cfFileWithWeights", "/home/abilandz/DatasetsO2/weights.root", "path to external ROOT file which holds all particle weights in O2 format"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" } cf_pw; +// *) Centrality weights: +struct : ConfigurableGroup { + Configurable cfUseCentralityWeights{"cfUseCentralityWeights", false, "use or not centrality weights"}; + Configurable cfFileWithCentralityWeights{"cfFileWithCentralityWeights", "/home/abilandz/DatasetsO2/centralityWeights.root", "path to external ROOT file which holds centrality weights in O2 format"}; // for AliEn file prepend "/alice/cern.ch/", for CCDB prepend "/alice-ccdb.cern.ch" +} cf_cw; + // *) Nested loops: struct : ConfigurableGroup { Configurable cfCalculateNestedLoops{"cfCalculateNestedLoops", false, "cross-check for all events all correlations with nested loops"}; @@ -184,8 +192,8 @@ struct : ConfigurableGroup { Configurable cfnEventsInternalValidation{"cfnEventsInternalValidation", 0, "number of events simulated on-the-fly for internal validation"}; Configurable cfHarmonicsOptionInternalValidation{"cfHarmonicsOptionInternalValidation", "constant", "for internal validation, set whether flow amplitudes are \"constant\" or \"correlated\""}; Configurable cfRescaleWithTheoreticalInput{"cfRescaleWithTheoreticalInput", false, "if kTRUE, all correlators are rescaled with theoretical input, so that all results in profiles are 1"}; - Configurable> cfInternalValidationAmplitudes{"cfInternalValidationAmplitudes", {0.01, 0.02, 0.03, 0.04}, "{v1, v2, v3, v4, ...} + has an effect only in combination with cfHarmonicsOptionInternalValidation = \"constant\". Max number of vn's is gMaxHarmonic."}; - Configurable> cfInternalValidationPlanes{"cfInternalValidationPlanes", {0.0, 0.0, 0.0, 0.0}, "{Psi1, Psi2, Psi3, Psi4, ...} + has an effect only in combination with cfHarmonicsOptionInternalValidation = \"constant\". Max number of Psin's is gMaxHarmonic."}; + Configurable> cfInternalValidationAmplitudes{"cfInternalValidationAmplitudes", {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09}, "{v1, v2, v3, v4, ...} + has an effect only in combination with cfHarmonicsOptionInternalValidation = \"constant\". Max number of vn's is gMaxHarmonic."}; + Configurable> cfInternalValidationPlanes{"cfInternalValidationPlanes", {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, "{Psi1, Psi2, Psi3, Psi4, ...} + has an effect only in combination with cfHarmonicsOptionInternalValidation = \"constant\". Max number of Psin's is gMaxHarmonic."}; Configurable> cfMultRangeInternalValidation{"cfMultRangeInternalValidation", {1000, 1001}, "{min, max}, with convention: min <= M < max"}; } cf_iv; @@ -208,7 +216,7 @@ struct : ConfigurableGroup { Configurable cfUseVariableLength_pt_bins{"cfUseVariableLength_pt_bins", false, "use or not variable-length pt bins"}; Configurable> cfVariableLength_pt_bins{"cfVariableLength_pt_bins", {0.20, 0.30, 0.40, 0.65, 1.00, 2.00, 5.00}, "variable-length pt bins"}; Configurable cfUseVariableLength_eta_bins{"cfUseVariableLength_eta_bins", false, "use or not variable-length eta bins"}; - Configurable> cfVariableLength_eta_bins{"cfVariableLength_eta_bins", {3.0, -1.0, -0.4, 0.0, 0.4, 1.0, 3.0}, "variable-length eta bins"}; + Configurable> cfVariableLength_eta_bins{"cfVariableLength_eta_bins", {-0.8, 0.0, 0.3, 0.8}, "variable-length eta bins"}; Configurable cfUseVariableLength_occu_bins{"cfUseVariableLength_occu_bins", false, "use or not variable-length occupancy bins"}; Configurable> cfVariableLength_occu_bins{"cfVariableLength_occu_bins", {0., 5., 6., 7., 8., 9., 100., 200., 500., 1000., 10000.}, "variable-length occupancy bins"}; diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h index 1ea50d6ff64..bb020581fc7 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h @@ -48,8 +48,6 @@ struct TaskConfiguration { Bool_t fDoAdditionalInsanityChecks = kFALSE; // do additional insanity checks at run time, at the expense of losing a bit of performance // (for instance, check if the run number in the current 'collision' is the same as run number in the first 'collision', etc.) Bool_t fInsanityCheckForEachParticle = kFALSE; // do additional insanity checks at run time for each particle, at the expense of losing a lot of performance. Use only during debugging. - Bool_t fUseCCDB = kFALSE; // access personal files from CCDB (kTRUE, this is set as default in Configurables), - // or from home dir in AliEn (kFALSE, use with care, as this is discouraged) Bool_t fProcess[eProcess_N] = {kFALSE}; // set what to process. See enum eProcess for full description. Set via implicit variables within a PROCESS_SWITCH clause. TString fWhichProcess = "ProcessRec"; // dump in this variable which process was used UInt_t fRandomSeed = 0; // argument for TRandom3 constructor. By default it is 0 (seed is guaranteed to be unique in time and space) @@ -59,10 +57,8 @@ struct TaskConfiguration { Bool_t fUseStopwatch = kFALSE; // do some basing profiling with TStopwatch for where the execution time is going TStopwatch* fTimer[eTimer_N] = {NULL}; // stopwatch, global (overal execution time) and local Float_t fFloatingPointPrecision = 1.e-6; // two floats are the same if TMath::Abs(f1 - f2) < fFloatingPointPrecision (there is configurable for it) - // Bool_t fRescaleWithTheoreticalInput; // if kTRUE, all measured correlators are - // rescaled with theoretical input, so that in profiles everything is at 1. Used - // both in OTF and internal val. -} tc; // "tc" labels an instance of this group of variables. + Int_t fSequentialBailout = 0; // if fSequentialBailout > 0, then each fSequentialBailout events the function BailOut() is called. Can be used for real analysis and for IV. +} tc; // "tc" labels an instance of this group of variables. // *) Event-by-event quantities: struct EventByEventQuantities { @@ -106,6 +102,7 @@ struct EventHistograms { Bool_t fBookEventHistograms[eEventHistograms_N] = {kTRUE}; // book or not this histogram, see SetBookEventHistograms Float_t fEventHistogramsBins[eEventHistograms_N][3] = {{0.}}; // [nBins,min,max] TString fEventHistogramsName[eEventHistograms_N] = {""}; // name of event histogram, used both for 1D and 2D histograms + Int_t fEventCounter[eEventCounter_N] = {0}; // event counters, see enum eEventCounter for full explanation // 2D: // ... // Remark: All 2D event histograms are still in the QA group. Move here only the ones I will use regularly in the analysis @@ -203,6 +200,16 @@ struct ParticleWeights { Bool_t fParticleWeightsAreFetched = kFALSE; // ensures that particle weights are fetched only once } pw; // "pw" labels an instance of this group of histograms +// *) Centrality weights: +struct CentralityWeights { + TList* fCentralityWeightsList = NULL; // list to hold all Q-vector objects + TProfile* fCentralityWeightsFlagsPro = NULL; // profile to hold all flags for CentralityWeights + Bool_t fUseCentralityWeights = false; // use centrality weights + TH1D* fCentralityWeightsHist = NULL; // histograms holding centrality weights + TString fFileWithCentralityWeights = ""; // path to external ROOT file which holds all centrality weights + Bool_t fCentralityWeightsAreFetched = kFALSE; // ensures that centrality weights are fetched only once +} cw; + // *) Nested loops: struct NestedLoops { TList* fNestedLoopsList = NULL; // list to hold all nested loops objects @@ -239,6 +246,7 @@ struct InternalValidation { Bool_t fInternalValidationForceBailout = kFALSE; // force bailout in internal validation after either eNumberOfEvents or eSelectedEvents is reached. // This is OK as long as I do not apply any event cuts in InternalValidation(). // Remember that for each real event, I do fnEventsInternalValidation events on-the-fly. + // Can be used in combination with setting fSequentialBailout > 0. UInt_t fnEventsInternalValidation = 0; // how many on-the-fly events will be sampled for each real event, for internal validation TString* fHarmonicsOptionInternalValidation = NULL; // "constant" or "correlated", see .cxx for full documentation Bool_t fRescaleWithTheoreticalInput = kFALSE; // if kTRUE, all measured correlators are rescaled with theoretical input, so that in profiles everything is at 1 @@ -255,6 +263,7 @@ struct Test0 { TString* fTest0Labels[gMaxCorrelator][gMaxIndex] = {{NULL}}; // all labels: k-p'th order is stored in k-1'th index. So yes, I also store 1-p Bool_t fCalculateTest0AsFunctionOf[eAsFunctionOf_N] = {true, true, true, false, false, false}; //! [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pT,4=eta,5=vs. occupancy] TString fFileWithLabels = ""; // path to external ROOT file which specifies all labels of interest + Bool_t fUseDefaultLabels = kFALSE; // use default labels hardwired in GetDefaultObjArrayWithLabels() TH1I* fTest0LabelsPlaceholder = NULL; // store all Test0 labels in this histogram } t0; // "t0" labels an instance of this group of histograms diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h index 30a2069c2e5..fb03e94a8a8 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-Enums.h @@ -21,13 +21,13 @@ enum eConfiguration { eVerboseForEachParticle, eDoAdditionalInsanityChecks, eInsanityCheckForEachParticle, - eUseCCDB, eWhichProcess, eRandomSeed, eUseFisherYates, eFixedNumberOfRandomlySelectedTracks, eUseStopwatch, eFloatingPointPrecision, + eSequentialBailout, eConfiguration_N }; @@ -206,7 +206,7 @@ enum eTimer { eTimer_N }; -enum eEventCounter { +enum eEventCounterForDryRun { eFill = 0, ePrint }; @@ -225,16 +225,18 @@ enum eCutCounter { }; enum eQAEventHistograms2D { - // Common: eMultTPC_vs_NContributors = 0, + eMultTPC_vs_Centrality, // only vs. chosen centrality estimator eVertex_z_vs_MultTPC, eVertex_z_vs_NContributors, + eCentFT0C_vs_CentNTPV, // Run 3 centrality eCentFT0M_vs_CentNTPV, // Run 3 centrality eCentRun2V0M_vs_CentRun2SPDTracklets, // Run 2 centrality (do not use in Run 1 converted, because there is no centrality information) eCentRun2V0M_vs_NContributors, // Run 2 centrality (do not use in Run 1 converted, because there is no centrality information) eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange, eTrackOccupancyInTimeRange_vs_MultTPC, eTrackOccupancyInTimeRange_vs_Vertex_z, + eTrackOccupancyInTimeRange_vs_Centrality, // only vs. chosen centrality estimator eQAEventHistograms2D_N }; @@ -245,7 +247,8 @@ enum eQAParticleHistograms2D { enum eCentralityEstimators { // Run 3: - eCentFT0M = 0, + eCentFT0C = 0, + eCentFT0M, eCentFV0A, eCentNTPV, // Run 2: @@ -260,4 +263,10 @@ enum eOccupancyEstimators { eOccupancyEstimators_N }; +enum eEventCounter { + eTotal, // total number of events, before any cuts are applied + eProcessed, // number of processed events, i.e. number of events which survived cuts and on which analysis have been performed + eEventCounter_N +}; + #endif // PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_ENUMS_H_ diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h index 416640dd9c7..417690caeb4 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-MemberFunctions.h @@ -64,9 +64,6 @@ void BookBaseList() fBasePro->GetXaxis()->SetBinLabel(eInsanityCheckForEachParticle, "fInsanityCheckForEachParticle"); fBasePro->Fill(eInsanityCheckForEachParticle, static_cast(tc.fInsanityCheckForEachParticle)); - fBasePro->GetXaxis()->SetBinLabel(eUseCCDB, "fUseCCDB"); - fBasePro->Fill(eUseCCDB, static_cast(tc.fUseCCDB)); - fBasePro->GetXaxis()->SetBinLabel(eWhichProcess, Form("WhichProcess = %s", tc.fWhichProcess.Data())); fBasePro->GetXaxis()->SetBinLabel(eRandomSeed, "fRandomSeed"); @@ -84,6 +81,9 @@ void BookBaseList() fBasePro->GetXaxis()->SetBinLabel(eFloatingPointPrecision, "fFloatingPointPrecision"); fBasePro->Fill(eFloatingPointPrecision, tc.fFloatingPointPrecision); + fBasePro->GetXaxis()->SetBinLabel(eSequentialBailout, "fSequentialBailout"); + fBasePro->Fill(eSequentialBailout, static_cast(tc.fSequentialBailout)); + fBaseList->Add(fBasePro); if (tc.fVerbose) { @@ -133,7 +133,6 @@ void DefaultConfiguration() tc.fVerboseUtility = cf_tc.cfVerboseUtility; tc.fVerboseForEachParticle = cf_tc.cfVerboseForEachParticle; tc.fDoAdditionalInsanityChecks = cf_tc.cfDoAdditionalInsanityChecks; - tc.fUseCCDB = cf_tc.cfUseCCDB; // Set automatically what to process, from an implicit variable "doprocessSomeProcessName" within a PROCESS_SWITCH clause: tc.fProcess[eProcessRec] = doprocessRec; tc.fProcess[eProcessRecSim] = doprocessRecSim; @@ -200,8 +199,9 @@ void DefaultConfiguration() tc.fFixedNumberOfRandomlySelectedTracks = cf_tc.cfFixedNumberOfRandomlySelectedTracks; tc.fUseStopwatch = cf_tc.cfUseStopwatch; tc.fFloatingPointPrecision = cf_tc.cfFloatingPointPrecision; + tc.fSequentialBailout = cf_tc.cfSequentialBailout; - // *) Event histograms: + // *) Event histograms (for QA see below): eh.fEventHistogramsName[eNumberOfEvents] = "NumberOfEvents"; eh.fEventHistogramsName[eTotalMultiplicity] = "TotalMultiplicity"; eh.fEventHistogramsName[eSelectedTracks] = "SelectedTracks"; @@ -261,7 +261,7 @@ void DefaultConfiguration() } } - // *) Particle histograms 1D: + // *) Particle histograms 1D (for QA see below): ph.fParticleHistogramsName[ePhi] = "Phi"; ph.fParticleHistogramsName[ePt] = "Pt"; ph.fParticleHistogramsName[eEta] = "Eta"; @@ -284,7 +284,7 @@ void DefaultConfiguration() } } - // *) Particle histograms 2D: + // *) Particle histograms 2D (for QA see below): ph.fParticleHistogramsName2D[ePhiPt] = Form("%s_vs_%s", ph.fParticleHistogramsName[ePhi].Data(), ph.fParticleHistogramsName[ePt].Data()), ph.fParticleHistogramsName2D[ePhiEta] = Form("%s_vs_%s", ph.fParticleHistogramsName[ePhi].Data(), ph.fParticleHistogramsName[eEta].Data()); for (Int_t t = 0; t < eParticleHistograms2D_N; t++) { @@ -348,6 +348,7 @@ void DefaultConfiguration() t0.fCalculateTest0AsFunctionOf[AFO_ETA] = cf_t0.cfCalculateTest0AsFunctionOfEta; t0.fCalculateTest0AsFunctionOf[AFO_OCCUPANCY] = cf_t0.cfCalculateTest0AsFunctionOfOccupancy; t0.fFileWithLabels = TString(cf_t0.cfFileWithLabels); + t0.fUseDefaultLabels = cf_t0.cfUseDefaultLabels; // *) Particle weights: pw.fUseWeights[wPHI] = cf_pw.cfUsePhiWeights; @@ -357,6 +358,10 @@ void DefaultConfiguration() pw.fUseDiffWeights[wPHIETA] = cf_pw.cfUseDiffPhiEtaWeights; pw.fFileWithWeights = cf_pw.cfFileWithWeights; + // *) Centrality weights: + cw.fUseCentralityWeights = cf_cw.cfUseCentralityWeights; + cw.fFileWithCentralityWeights = cf_cw.cfFileWithCentralityWeights; + // ... // *) Nested loops: @@ -403,6 +408,7 @@ void DefaultConfiguration() // *) histogram names with custom NUA distributions in that file + get those histograms immediately here: auto lCustomNUAPDFHistNames = (vector)cf_nua.cfCustomNUAPDFHistNames; + // TBI 20241115 For some reason, the default values of configurable "cfCustomNUAPDFHistNames" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being if (lCustomNUAPDFHistNames.size() != eNUAPDF_N) { LOGF(info, "\033[1;31m lCustomNUAPDFHistNames.size() = %d\033[0m", lCustomNUAPDFHistNames.size()); LOGF(info, "\033[1;31m eNUAPDF_N = %d\033[0m", static_cast(eNUAPDF_N)); @@ -449,6 +455,7 @@ void DefaultConfiguration() qa.fCheckUnderflowAndOverflow = cf_qa.cfCheckUnderflowAndOverflow; // **) Centrality estimators: + qa.fCentralityEstimatorName[eCentFT0C] = "CentFT0C"; qa.fCentralityEstimatorName[eCentFT0M] = "CentFT0M"; qa.fCentralityEstimatorName[eCentFV0A] = "CentFV0A"; qa.fCentralityEstimatorName[eCentNTPV] = "CentNTPV"; @@ -459,16 +466,20 @@ void DefaultConfiguration() qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange] = "TrackOccupancyInTimeRange"; qa.fOccupancyEstimatorName[eFT0COccupancyInTimeRange] = "FT0COccupancyInTimeRange"; - // **) Names of 2D event histograms: + // **) Names of QA 2D event histograms: + // Remark: Do NOT use FancyFormatting here, only later in BookQAHistograms() for axis titles! qa.fEventHistogramsName2D[eMultTPC_vs_NContributors] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultTPC].Data(), eh.fEventHistogramsName[eNContributors].Data()); + qa.fEventHistogramsName2D[eMultTPC_vs_Centrality] = Form("%s_vs_%s", eh.fEventHistogramsName[eMultTPC].Data(), eh.fEventHistogramsName[eCentrality].Data()); qa.fEventHistogramsName2D[eVertex_z_vs_MultTPC] = Form("%s_vs_%s", eh.fEventHistogramsName[eVertex_z].Data(), eh.fEventHistogramsName[eMultTPC].Data()); qa.fEventHistogramsName2D[eVertex_z_vs_NContributors] = Form("%s_vs_%s", eh.fEventHistogramsName[eVertex_z].Data(), eh.fEventHistogramsName[eNContributors].Data()); + qa.fEventHistogramsName2D[eCentFT0C_vs_CentNTPV] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0C].Data(), qa.fCentralityEstimatorName[eCentNTPV].Data()); qa.fEventHistogramsName2D[eCentFT0M_vs_CentNTPV] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentFT0M].Data(), qa.fCentralityEstimatorName[eCentNTPV].Data()); qa.fEventHistogramsName2D[eCentRun2V0M_vs_CentRun2SPDTracklets] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentRun2V0M].Data(), qa.fCentralityEstimatorName[eCentRun2SPDTracklets].Data()); qa.fEventHistogramsName2D[eCentRun2V0M_vs_NContributors] = Form("%s_vs_%s", qa.fCentralityEstimatorName[eCentRun2V0M].Data(), eh.fEventHistogramsName[eNContributors].Data()); qa.fEventHistogramsName2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = Form("%s_vs_%s", qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data(), qa.fOccupancyEstimatorName[eFT0COccupancyInTimeRange].Data()); qa.fEventHistogramsName2D[eTrackOccupancyInTimeRange_vs_MultTPC] = Form("%s_vs_%s", qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data(), eh.fEventHistogramsName[eMultTPC].Data()); qa.fEventHistogramsName2D[eTrackOccupancyInTimeRange_vs_Vertex_z] = Form("%s_vs_%s", qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data(), eh.fEventHistogramsName[eVertex_z].Data()); + qa.fEventHistogramsName2D[eTrackOccupancyInTimeRange_vs_Centrality] = Form("%s_vs_%s", qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data(), eh.fEventHistogramsName[eCentrality].Data()); // ***) Quick insanity check that all names are set: for (Int_t t = 0; t < eQAEventHistograms2D_N; t++) { @@ -477,7 +488,7 @@ void DefaultConfiguration() } } - // **) Names of 2D particle histograms: + // **) Names of QA 2D particle histograms: qa.fParticleHistogramsName2D[ePt_vs_dcaXY] = Form("%s_vs_%s", ph.fParticleHistogramsName[ePt].Data(), ph.fParticleHistogramsName[edcaXY].Data()); // ***) Quick insanity check that all names are set: @@ -563,7 +574,7 @@ void DefaultBooking() // use configurable array cfBookEventHistograms, where you can specify name of the histogram accompanied with flags 1 (book) or 0 (do not book). // Supported format: "someName-0" and "someName-1", where "-" is a field separator. // Ordering of the flags in that array is interpreted through ordering of enums in enum eEventHistograms. - auto lBookEventHistograms = (vector)cf_eh.cfBookEventHistograms; // this is now the local version of that int array from configurable. + auto lBookEventHistograms = cf_eh.cfBookEventHistograms.value; // this is now the local version of that string array from configurable. if (lBookEventHistograms.size() != eEventHistograms_N) { LOGF(info, "\033[1;31m lBookEventHistograms.size() = %d\033[0m", lBookEventHistograms.size()); LOGF(info, "\033[1;31m eEventHistograms_N) = %d\033[0m", static_cast(eEventHistograms_N)); @@ -605,7 +616,7 @@ void DefaultBooking() // *) If you do not want particular particle histogram to be booked, use configurable array cfBookParticleHistograms, where you can specify flags 1 (book) or 0 (do not book). // Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms. // TBI 20240124 is this safe enough? - auto lBookParticleHistograms = (vector)cf_ph.cfBookParticleHistograms; // this is now the local version of that int array from configurable. TBI 20240124 why is this casting mandatory? + auto lBookParticleHistograms = cf_ph.cfBookParticleHistograms.value; // this is now the local version of that string array from configurable. if (lBookParticleHistograms.size() != eParticleHistograms_N) { LOGF(info, "\033[1;31m lBookParticleHistograms.size() = %d\033[0m", lBookParticleHistograms.size()); LOGF(info, "\033[1;31m eParticleHistograms_N) = %d\033[0m", static_cast(eParticleHistograms_N)); @@ -646,8 +657,9 @@ void DefaultBooking() ph.fFillParticleHistograms2D = cf_ph.cfFillParticleHistograms2D; // If you do not want particular 2D particle histogram to be booked, use configurable array cfBookParticleHistograms2D, where you can specify flags 1 (book) or 0 (do not book). - // *) Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms2D. // TBI 20240124 is this safe enough? - auto lBookParticleHistograms2D = (vector)cf_ph.cfBookParticleHistograms2D; // this is now the local version of that int array from configurable. TBI 20240124 why is this casting mandatory? + // *) Ordering of the flags in that array is interpreted through ordering of enums in enum eParticleHistograms2D. + auto lBookParticleHistograms2D = cf_ph.cfBookParticleHistograms2D.value; // this is now the local version of that string array from configurable + // TBI 20241113 For some reason, the default values of configurable "cfBookParticleHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being if (lBookParticleHistograms2D.size() != eParticleHistograms2D_N) { LOGF(info, "\033[1;31m lBookParticleHistograms2D.size() = %d\033[0m", lBookParticleHistograms2D.size()); LOGF(info, "\033[1;31m eParticleHistograms2D_N) = %d\033[0m", static_cast(eParticleHistograms2D_N)); @@ -674,7 +686,8 @@ void DefaultBooking() // *) If you do not want particular 2D event histogram to be booked, use configurable array cfBookQAEventHistograms2D, where you can specify flags 1 (book) or 0 (do not book). // Ordering of the flags in that array is interpreted through ordering of enums in enum eQAEventHistograms2D - auto lBookQAEventHistograms2D = (vector)cf_qa.cfBookQAEventHistograms2D; // this is now the local version of that int array from configurable + auto lBookQAEventHistograms2D = cf_qa.cfBookQAEventHistograms2D.value; // this is now the local version of that string array from configurable + // TBI 20241115 For some reason, the default values of configurable "cfBookQAEventHistograms2D" are not correctly propagated in the local variables, but I can circumvent that with JSON settings for the time being if (lBookQAEventHistograms2D.size() != eQAEventHistograms2D_N) { LOGF(info, "\033[1;31m lBookQAEventHistograms2D.size() = %d\033[0m", lBookQAEventHistograms2D.size()); LOGF(info, "\033[1;31m eQAEventHistograms2D_N = %d\033[0m", static_cast(eQAEventHistograms2D_N)); @@ -692,14 +705,17 @@ void DefaultBooking() // I append "&& qa.fFillQAEventHistograms2D" below, to switch off booking of all 2D event histograms with one common flag: qa.fBookQAEventHistograms2D[eMultTPC_vs_NContributors] = Alright(lBookQAEventHistograms2D[eMultTPC_vs_NContributors]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eMultTPC_vs_Centrality] = Alright(lBookQAEventHistograms2D[eMultTPC_vs_Centrality]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eVertex_z_vs_MultTPC] = Alright(lBookQAEventHistograms2D[eVertex_z_vs_MultTPC]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eVertex_z_vs_NContributors] = Alright(lBookQAEventHistograms2D[eVertex_z_vs_NContributors]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0C_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV] = Alright(lBookQAEventHistograms2D[eCentFT0M_vs_CentNTPV]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets] = Alright(lBookQAEventHistograms2D[eCentRun2V0M_vs_CentRun2SPDTracklets]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eCentRun2V0M_vs_NContributors] = Alright(lBookQAEventHistograms2D[eCentRun2V0M_vs_NContributors]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_MultTPC] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_MultTPC]) && qa.fFillQAEventHistograms2D; qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Vertex_z] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Vertex_z]) && qa.fFillQAEventHistograms2D; + qa.fBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Centrality] = Alright(lBookQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Centrality]) && qa.fFillQAEventHistograms2D; // **) QA 2D particle histograms: qa.fFillQAParticleHistograms2D = cf_qa.cfFillQAParticleHistograms2D; @@ -757,32 +773,32 @@ void DefaultBinning() eh.fEventHistogramsBins[eNumberOfEvents][1] = 0.; eh.fEventHistogramsBins[eNumberOfEvents][2] = 1.; - eh.fEventHistogramsBins[eTotalMultiplicity][0] = 20000; - eh.fEventHistogramsBins[eTotalMultiplicity][1] = -1.e5; + eh.fEventHistogramsBins[eTotalMultiplicity][0] = 10000; + eh.fEventHistogramsBins[eTotalMultiplicity][1] = 0.; eh.fEventHistogramsBins[eTotalMultiplicity][2] = 1.e5; - eh.fEventHistogramsBins[eSelectedTracks][0] = 20000; - eh.fEventHistogramsBins[eSelectedTracks][1] = -1.e5; + eh.fEventHistogramsBins[eSelectedTracks][0] = 10000; + eh.fEventHistogramsBins[eSelectedTracks][1] = 0.; eh.fEventHistogramsBins[eSelectedTracks][2] = 1.e5; - eh.fEventHistogramsBins[eMultFV0M][0] = 20000; - eh.fEventHistogramsBins[eMultFV0M][1] = -1.e5; + eh.fEventHistogramsBins[eMultFV0M][0] = 10000; + eh.fEventHistogramsBins[eMultFV0M][1] = 0.; eh.fEventHistogramsBins[eMultFV0M][2] = 1.e5; - eh.fEventHistogramsBins[eMultFT0M][0] = 20000; - eh.fEventHistogramsBins[eMultFT0M][1] = -1.e5; + eh.fEventHistogramsBins[eMultFT0M][0] = 10000; + eh.fEventHistogramsBins[eMultFT0M][1] = 0.; eh.fEventHistogramsBins[eMultFT0M][2] = 1.e5; - eh.fEventHistogramsBins[eMultTPC][0] = 20000; - eh.fEventHistogramsBins[eMultTPC][1] = -1.e5; + eh.fEventHistogramsBins[eMultTPC][0] = 10000; + eh.fEventHistogramsBins[eMultTPC][1] = 0.; eh.fEventHistogramsBins[eMultTPC][2] = 1.e5; - eh.fEventHistogramsBins[eMultNTracksPV][0] = 20000; - eh.fEventHistogramsBins[eMultNTracksPV][1] = -1.e5; + eh.fEventHistogramsBins[eMultNTracksPV][0] = 10000; + eh.fEventHistogramsBins[eMultNTracksPV][1] = 0.; eh.fEventHistogramsBins[eMultNTracksPV][2] = 1.e5; - eh.fEventHistogramsBins[eMultTracklets][0] = 20000; - eh.fEventHistogramsBins[eMultTracklets][1] = -1.e5; + eh.fEventHistogramsBins[eMultTracklets][0] = 10000; + eh.fEventHistogramsBins[eMultTracklets][1] = 0.; eh.fEventHistogramsBins[eMultTracklets][2] = 1.e5; eh.fEventHistogramsBins[eCentrality][0] = 120; // intentionally, because if centrality is not determined, it's set to 105.0 at the moment @@ -1464,6 +1480,11 @@ void InsanityChecksBeforeBooking() LOGF(fatal, "\033[1;31m%s at line %d : set fFloatingPointPrecision = %f to some small positive value, which will determine if two floats are the same \033[0m", __FUNCTION__, __LINE__, tc.fFloatingPointPrecision); } + // **) Ensure that fSequentialBailout makes sense: + if (!(tc.fSequentialBailout >= 0)) { + LOGF(fatal, "\033[1;31m%s at line %d : set fSequentialBailout = %d either to 0 (not used), or to positive integer.\033[0m", __FUNCTION__, __LINE__, tc.fSequentialBailout); + } + // b) Ensure that Run 1/2 specific cuts and flags are used only in Run 1/2 (both data and sim): // **) Ensure that eSel7 is used only for converted Run 2 and Run 1 (both data and sim): if (ec.fUseEventCuts[eSel7]) { @@ -1474,9 +1495,9 @@ void InsanityChecksBeforeBooking() // **) Supported centrality estimators for Run 1 and 2 are enlisted here: if (tc.fProcess[eProcessRec_Run2] || tc.fProcess[eProcessRecSim_Run2] || tc.fProcess[eProcessSim_Run2] || tc.fProcess[eProcessRec_Run1] || tc.fProcess[eProcessRecSim_Run1] || tc.fProcess[eProcessSim_Run1]) { - if (!(ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2V0M", TString::kIgnoreCase) || - ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2SPDTracklets", TString::kIgnoreCase))) { - LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported yet for converted Run 2 and Run 1 analysis. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + if (!(ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2V0M") || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centRun2SPDTracklets"))) { + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported yet for converted Run 2 and Run 1 analysis.\nUse either \"centRun2V0M\" or \"centRun2SPDTracklets\" (case sensitive!) \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); } } @@ -1532,10 +1553,11 @@ void InsanityChecksBeforeBooking() // **) Supported centrality estimators for Run 3 are enlisted here: if (tc.fProcess[eProcessRec] || tc.fProcess[eProcessRecSim] || tc.fProcess[eProcessSim]) { - if (!(ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0M", TString::kIgnoreCase) || + if (!(ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0C", TString::kIgnoreCase) || + ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0M", TString::kIgnoreCase) || ec.fsEventCuts[eCentralityEstimator].EqualTo("centFV0A", TString::kIgnoreCase) || ec.fsEventCuts[eCentralityEstimator].EqualTo("centNTPV", TString::kIgnoreCase))) { - LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported yet for Run 3 analysis. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); + LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %s is not supported yet for Run 3 analysis.\nUse \"centFT0C\", \"centFT0M\", \"centFV0A\", or \"centNTPV\"\033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); } } @@ -1709,6 +1731,7 @@ void BookAndNestAllLists() // *) Correlations; // *) Q-vectors; // *) Particle weights; + // *) Centrality weights; // *) Nested loops; // *) Toy NUA; // *) Internal validation; @@ -1767,6 +1790,12 @@ void BookAndNestAllLists() pw.fWeightsList->SetOwner(kTRUE); fBaseList->Add(pw.fWeightsList); + // *) Centrality weights: + cw.fCentralityWeightsList = new TList(); + cw.fCentralityWeightsList->SetName("CentralityWeights"); + cw.fCentralityWeightsList->SetOwner(kTRUE); + fBaseList->Add(cw.fCentralityWeightsList); + // *) Nested loops: nl.fNestedLoopsList = new TList(); nl.fNestedLoopsList->SetName("NestedLoops"); @@ -1873,6 +1902,16 @@ void BookQAHistograms() max_y_Event[eMultTPC_vs_NContributors] = eh.fEventHistogramsBins[eNContributors][2]; title_y_Event[eMultTPC_vs_NContributors] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + // *) "MultTPC_vs_Centrality": + nBins_x_Event[eMultTPC_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eMultTPC][0]); // TBI 20240702 add support for rebinning + min_x_Event[eMultTPC_vs_Centrality] = eh.fEventHistogramsBins[eMultTPC][1]; + max_x_Event[eMultTPC_vs_Centrality] = eh.fEventHistogramsBins[eMultTPC][2]; + title_x_Event[eMultTPC_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eMultTPC].Data()); + nBins_y_Event[eMultTPC_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); // TBI 20240702 add support for rebinning + min_y_Event[eMultTPC_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eMultTPC_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eMultTPC_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + // *) "Vertex_z_vs_MultTPC": nBins_x_Event[eVertex_z_vs_MultTPC] = static_cast(eh.fEventHistogramsBins[eVertex_z][0]); // TBI 20240702 add support for rebinning min_x_Event[eVertex_z_vs_MultTPC] = eh.fEventHistogramsBins[eVertex_z][1]; @@ -1893,6 +1932,16 @@ void BookQAHistograms() max_y_Event[eVertex_z_vs_NContributors] = eh.fEventHistogramsBins[eNContributors][2]; title_y_Event[eVertex_z_vs_NContributors] = FancyFormatting(eh.fEventHistogramsName[eNContributors].Data()); + // *) "eCentFT0C_vs_CentNTPV": + nBins_x_Event[eCentFT0C_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_x_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; + max_x_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][2]; + title_x_Event[eCentFT0C_vs_CentNTPV] = FancyFormatting(qa.fCentralityEstimatorName[eCentFT0C].Data()); + nBins_y_Event[eCentFT0C_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eCentFT0C_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eCentFT0C_vs_CentNTPV] = FancyFormatting(qa.fCentralityEstimatorName[eCentNTPV].Data()); + // *) "eCentFT0M_vs_CentNTPV": nBins_x_Event[eCentFT0M_vs_CentNTPV] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); min_x_Event[eCentFT0M_vs_CentNTPV] = eh.fEventHistogramsBins[eCentrality][1]; @@ -1953,6 +2002,16 @@ void BookQAHistograms() max_y_Event[eTrackOccupancyInTimeRange_vs_Vertex_z] = eh.fEventHistogramsBins[eVertex_z][2]; title_y_Event[eTrackOccupancyInTimeRange_vs_Vertex_z] = FancyFormatting(eh.fEventHistogramsName[eVertex_z].Data()); + // *) "eTrackOccupancyInTimeRange_vs_Centrality": + nBins_x_Event[eTrackOccupancyInTimeRange_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eOccupancy][0]); + min_x_Event[eTrackOccupancyInTimeRange_vs_Centrality] = eh.fEventHistogramsBins[eOccupancy][1]; + max_x_Event[eTrackOccupancyInTimeRange_vs_Centrality] = eh.fEventHistogramsBins[eOccupancy][2]; + title_x_Event[eTrackOccupancyInTimeRange_vs_Centrality] = FancyFormatting(qa.fOccupancyEstimatorName[eTrackOccupancyInTimeRange].Data()); + nBins_y_Event[eTrackOccupancyInTimeRange_vs_Centrality] = static_cast(eh.fEventHistogramsBins[eCentrality][0]); + min_y_Event[eTrackOccupancyInTimeRange_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][1]; + max_y_Event[eTrackOccupancyInTimeRange_vs_Centrality] = eh.fEventHistogramsBins[eCentrality][2]; + title_y_Event[eTrackOccupancyInTimeRange_vs_Centrality] = FancyFormatting(eh.fEventHistogramsName[eCentrality].Data()); + // ... // *) Quick insanity check on title_x_Event and title_y_Event: @@ -1995,7 +2054,6 @@ void BookQAHistograms() Form("fQAEventHistograms2D[%s][%s][%s]", qa.fEventHistogramsName2D[t].Data(), srs[rs].Data(), sba[ba].Data()), Form("%s, %s, %s", "__RUN_NUMBER__", srs_long[rs].Data(), sba_long[ba].Data()), // __RUN_NUMBER__ is handled in DetermineAndPropagateRunNumber(T const& collision) nBins_x_Event[t], min_x_Event[t], max_x_Event[t], nBins_y_Event[t], min_y_Event[t], max_y_Event[t]); - qa.fQAEventHistograms2D[t][rs][ba]->GetXaxis()->SetTitle(title_x_Event[t].Data()); qa.fQAEventHistograms2D[t][rs][ba]->GetYaxis()->SetTitle(title_y_Event[t].Data()); qa.fQAEventHistograms2D[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); @@ -2112,9 +2170,9 @@ void BookEventHistograms() if (!eh.fBookEventHistograms[t]) { continue; } + for (Int_t rs = 0; rs < 2; rs++) // reco/sim { - if (Skip(rs)) { continue; } @@ -2126,13 +2184,11 @@ void BookEventHistograms() if (ba == eBefore && eh.fEventHistogramsName[t].EqualTo("SelectedTracks")) { continue; } - eh.fEventHistograms[t][rs][ba] = new TH1F( Form("fEventHistograms[%s][%s][%s]", eh.fEventHistogramsName[t].Data(), srs[rs].Data(), sba[ba].Data()), Form("%s, %s, %s", "__RUN_NUMBER__", srs_long[rs].Data(), sba_long[ba].Data()), // __RUN_NUMBER__ is handled in DetermineAndPropagateRunNumber(T const& collision) static_cast(eh.fEventHistogramsBins[t][0]), eh.fEventHistogramsBins[t][1], eh.fEventHistogramsBins[t][2]); - eh.fEventHistograms[t][rs][ba]->GetXaxis()->SetTitle(FancyFormatting(eh.fEventHistogramsName[t].Data())); eh.fEventHistograms[t][rs][ba]->SetLineColor(ec.fBeforeAfterColor[ba]); eh.fEventHistograms[t][rs][ba]->SetFillColor(ec.fBeforeAfterColor[ba] - 10); @@ -2632,6 +2688,43 @@ void BookWeightsHistograms() //============================================================ +void BookCentralityWeightsHistograms() +{ + // Book all objects for particle centrality weights. + + // a) Book the profile holding flags; + // b) Histograms for centrality weights. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Book the profile holding flags: + cw.fCentralityWeightsFlagsPro = + new TProfile("fWeightsFlagsPro", "flags for centrality weights", 1, 0., 1.); + cw.fCentralityWeightsFlagsPro->SetStats(kFALSE); + cw.fCentralityWeightsFlagsPro->SetLineColor(eColor); + cw.fCentralityWeightsFlagsPro->SetFillColor(eFillColor); + cw.fCentralityWeightsFlagsPro->GetXaxis()->SetLabelSize(0.05); + cw.fCentralityWeightsFlagsPro->GetXaxis()->SetBinLabel(1, "TBI 20241118 I need to store here name of centrality esimator for which centrality weights were calculated"); + if (cw.fUseCentralityWeights) { + cw.fCentralityWeightsFlagsPro->Fill(0.5, 1.); // TBI 20241118 shall I automate this? + } + cw.fCentralityWeightsList->Add(cw.fCentralityWeightsFlagsPro); + + // b) Histograms for centrality weights: + // As of 20240216, I have abandoned the idea to generate centrality weights internally, centrality weights + // are always fetched and cloned from external files, in any case (local, AliEn, CCDB). + // Therefore, add histos with centrality weights to this list only after they are cloned from external files. + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + +} // void BookWeightsHistograms() + +//============================================================ + void BookNestedLoopsHistograms() { // Book all nested loops histograms. @@ -3041,10 +3134,10 @@ void InternalValidation() // b) Loop over on-the-fly events. // b0) Reset ebye quantities; // b1) Determine multiplicity, centrality, reaction plane and configure p.d.f. for azimuthal angles if harmonics are not constant e-by-e; - // b2) Loop over particles; - // b3) Fill event histograms; - // b4) Calculate correlations; - // b5) Optionally, cross-check with nested loops; + // b2) Fill event histograms before cuts; + // b3) Loop over particles; + // b4) Fill event histograms after cuts; + // b5) Calculate everything for selected events and particles; // c) Delete persistent objects. if (tc.fVerbose) { @@ -3125,18 +3218,27 @@ void InternalValidation() ebye.fCentrality = static_cast(gRandom->Uniform(0., 100.)); // this is perfectly fine for this exercise ebye.fOccupancy = static_cast(gRandom->Uniform(0., 10000.)); // this is perfectly fine for this exercise + // b2) Fill event histograms before cuts: + if (eh.fFillEventHistograms) { + !eh.fEventHistograms[eNumberOfEvents][eSim][eBefore] ? true : eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]->Fill(0.5); + !eh.fEventHistograms[eTotalMultiplicity][eSim][eBefore] ? true : eh.fEventHistograms[eTotalMultiplicity][eSim][eBefore]->Fill(nMult); + !eh.fEventHistograms[eCentrality][eSim][eBefore] ? true : eh.fEventHistograms[eCentrality][eSim][eBefore]->Fill(ebye.fCentrality); + !eh.fEventHistograms[eOccupancy][eSim][eBefore] ? true : eh.fEventHistograms[eCentrality][eSim][eBefore]->Fill(ebye.fOccupancy); + } + + // ... here I could implement some event cuts, if necessary ... + // configure p.d.f. for azimuthal angles if harmonics are not constant e-by-e: if (iv.fHarmonicsOptionInternalValidation->EqualTo("correlated")) { // Sample 3 correlated vn's from TF3 fvnPDF, and with them initialize fPhiPDF: fvnPDF->GetRandom3(v1, v2, v3); - // cout<SetParameter(0, v1); fPhiPDF->SetParameter(1, v2); fPhiPDF->SetParameter(2, v3); // reaction plane is set above } // if(fHarmonicsOptionInternalValidation->EqualTo("correlated")) - // b2) Loop over particles: + // b3) Loop over particles: Double_t dPhi = 0.; Double_t dPt = 0.; Double_t dEta = 0.; @@ -3223,7 +3325,7 @@ void InternalValidation() } // for(Int_t p=0;pFill(0.5); !eh.fEventHistograms[eTotalMultiplicity][eSim][eAfter] ? true : eh.fEventHistograms[eTotalMultiplicity][eSim][eAfter]->Fill(nMult); @@ -3232,7 +3334,7 @@ void InternalValidation() !eh.fEventHistograms[eOccupancy][eSim][eAfter] ? true : eh.fEventHistograms[eCentrality][eSim][eAfter]->Fill(ebye.fOccupancy); } - // *) Calculate everything for selected events and particles: + // b5) Calculate everything for selected events and particles: CalculateEverything(); // *) Reset event-by-event quantities: @@ -3241,18 +3343,26 @@ void InternalValidation() // *) Print info on the current event number (within current real event): LOGF(info, " Event # %d/%d (within current real event) ....", e + 1, static_cast(iv.fnEventsInternalValidation)); - // *) Print info on the current event number (total): - PrintEventCounter(eAfter); + // *) Determine all event counters: + DetermineEventCounters(); + + // *) Sequential bailout: After each tc.fSequentialBailout events, I bail out: + if (iv.fInternalValidationForceBailout && tc.fSequentialBailout > 0 && eh.fEventCounter[eProcessed] > 0 && 0 == eh.fEventCounter[eProcessed] % tc.fSequentialBailout) { + BailOut(); + } // *) If I reached max number of events, ignore the remaining collisions: if (MaxNumberOfEvents(eAfter)) { if (iv.fInternalValidationForceBailout) { - BailOut(); + BailOut(kTRUE); } } } // for(Int_t e=0;e(iv.fnEventsInternalValidation);e++) + // *) Print info on the current event number (total): + PrintEventCounter(eAfter); + // c) Delete persistent objects: if (fPhiPDF) { delete fPhiPDF; @@ -3495,9 +3605,17 @@ void Preprocess(T const& collision) StartFunction(__FUNCTION__); } + // *) Determine all event counters: + DetermineEventCounters(); + + // *) Sequential bailout: After each tc.fSequentialBailout events, I bail out: + if (tc.fSequentialBailout > 0 && eh.fEventCounter[eProcessed] > 0 && 0 == eh.fEventCounter[eProcessed] % tc.fSequentialBailout) { + BailOut(); + } + // *) If I reached max number of events, ignore the remaining collisions: if (MaxNumberOfEvents(eAfter) || MaxNumberOfEvents(eBefore)) { // TBI 20240510 this is a bit confusing, implemented this way. Shall I split off? - BailOut(); + BailOut(kTRUE); } // *) Determine and propagate run number info to already booked objects: @@ -3517,6 +3635,15 @@ void Preprocess(T const& collision) } } + // *) Fetch the centrality weights for this particular run number. Do it only once. + // TBI 20231012 If eventualy I can access programatically run number in init(...) at run time, this shall go there. + if (!cw.fCentralityWeightsAreFetched) { + if (cw.fUseCentralityWeights) { + GetCentralityWeights(); + cw.fCentralityWeightsAreFetched = kTRUE; + } + } + if (tc.fVerbose) { ExitFunction(__FUNCTION__); } @@ -4445,8 +4572,10 @@ void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) // QA: if (qa.fFillQAEventHistograms2D) { !qa.fQAEventHistograms2D[eMultTPC_vs_NContributors][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultTPC_vs_NContributors][eRec][ba]->Fill(collision.multTPC(), collision.numContrib()); + !qa.fQAEventHistograms2D[eMultTPC_vs_Centrality][eRec][ba] ? true : qa.fQAEventHistograms2D[eMultTPC_vs_Centrality][eRec][ba]->Fill(collision.multTPC(), ebye.fCentrality); !qa.fQAEventHistograms2D[eVertex_z_vs_MultTPC][eRec][ba] ? true : qa.fQAEventHistograms2D[eVertex_z_vs_MultTPC][eRec][ba]->Fill(collision.posZ(), collision.multTPC()); !qa.fQAEventHistograms2D[eVertex_z_vs_NContributors][eRec][ba] ? true : qa.fQAEventHistograms2D[eVertex_z_vs_NContributors][eRec][ba]->Fill(collision.posZ(), collision.numContrib()); + !qa.fQAEventHistograms2D[eCentFT0C_vs_CentNTPV][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0C_vs_CentNTPV][eRec][ba]->Fill(qa.fCentrality[eCentFT0C], qa.fCentrality[eCentNTPV]); !qa.fQAEventHistograms2D[eCentFT0M_vs_CentNTPV][eRec][ba] ? true : qa.fQAEventHistograms2D[eCentFT0M_vs_CentNTPV][eRec][ba]->Fill(qa.fCentrality[eCentFT0M], qa.fCentrality[eCentNTPV]); } @@ -4496,6 +4625,7 @@ void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) !qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange][eRec][ba] ? true : qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_FT0COccupancyInTimeRange][eRec][ba]->Fill(collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); !qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_MultTPC][eRec][ba] ? true : qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_MultTPC][eRec][ba]->Fill(collision.trackOccupancyInTimeRange(), collision.multTPC()); !qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Vertex_z][eRec][ba] ? true : qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Vertex_z][eRec][ba]->Fill(collision.trackOccupancyInTimeRange(), collision.posZ()); + !qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Centrality][eRec][ba] ? true : qa.fQAEventHistograms2D[eTrackOccupancyInTimeRange_vs_Centrality][eRec][ba]->Fill(collision.trackOccupancyInTimeRange(), ebye.fCentrality); } // ... and corresponding MC truth simulated (Run 3 specific) @@ -5998,7 +6128,7 @@ void CalculateKineCorrelations(eAsFunctionOf AFO_variable) // *) Insanity checks on above settings: if (qvKine == eqvectorKine_N) { - LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } // ... @@ -6267,7 +6397,7 @@ void CalculateKineTest0(eAsFunctionOf AFO_variable) // *) Insanity checks on above settings: if (qvKine == eqvectorKine_N) { - LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } // *) Uniform loop over bin for all kine variables: @@ -7173,6 +7303,46 @@ void SetDiffWeightsHist(TH1D* const hist, eDiffWeights whichDiffWeight, Int_t bi //============================================================ +void SetCentralityWeightsHist(TH1D* const hist) +{ + // Copy histogram holding weights from an external file to the corresponding data member. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Finally: + hist->SetDirectory(0); + cw.fCentralityWeightsHist = reinterpret_cast(hist->Clone()); + + if (!cw.fCentralityWeightsHist) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + // Cosmetics: TBI 20240216 do I really want to overwrite initial cosmetics, perhaps this shall go better into MakeCentralityWeights.C ? + // Or I could move all this to GetHistogramWithCentralityWeights, where in any case I am setting e.g. histogram title, etc. + cw.fCentralityWeightsHist->SetStats(kFALSE); + cw.fCentralityWeightsHist->GetXaxis()->SetTitle("Centrality percentile"); + cw.fCentralityWeightsHist->GetYaxis()->SetTitle(Form("Centrality weight (%s)", ec.fsEventCuts[eCentralityEstimator].Data())); + cw.fCentralityWeightsHist->SetFillColor(eFillColor); + cw.fCentralityWeightsHist->SetLineColor(eColor); + if (!cw.fCentralityWeightsList) { + LOGF(fatal, "\033[1;31m%s at line %d: fCentralityWeightsList is NULL. That means that you have called SetCentralityWeightsHist(...) in init(), before this TList was booked.\033[0m", __FUNCTION__, __LINE__); + } + cw.fCentralityWeightsList->Add(cw.fCentralityWeightsHist); // This is working at the moment, because I am fetching all centrality weights in Preprocess(), which is called after init() + // But if eventually it will be possible to fetch run number programatically in init(), I will have to re-think this line. + + // Flag: + cw.fUseCentralityWeights = kTRUE; + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + +} // void SetCentralityWeightsHist(TH1D* const hist) + +//============================================================ + TH1D* GetWeightsHist(eWeights whichWeight) { // The standard getter. @@ -7301,14 +7471,10 @@ TH1D* GetHistogramWithWeights(const char* filePath, const char* runNumber, const ccdb->setURL("http://alice-ccdb.cern.ch"); if (tc.fVerbose) { - LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", - TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); + LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); } - baseList = - reinterpret_cast(ccdb->get(TString(filePath) - .ReplaceAll("/alice-ccdb.cern.ch/", "") - .Data())); + baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); if (!baseList) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); @@ -7343,10 +7509,9 @@ TH1D* GetHistogramWithWeights(const char* filePath, const char* runNumber, const LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } - weightsFile->GetObject( - "ccdb_object", baseList); // TBI 20231008 for simplicity, harwired name - // of base TList is "ccdb_object" also for - // local case, see if I need to change this + weightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, harwired name + // of base TList is "ccdb_object" also for + // local case, see if I need to change this if (!baseList) { // weightsFile->ls(); LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); @@ -7467,14 +7632,216 @@ TH1D* GetHistogramWithWeights(const char* filePath, const char* runNumber, const //============================================================ +TH1D* GetHistogramWithCentralityWeights(const char* filePath, const char* runNumber) +{ + // Get and return histogram with centrality weights from an external file. + + // TBI 20241118 Shall I merge this function with GetHistogramWithWeights(...) as there is a bit of code bloat? + + // TBI 20241021 Strictly speaking, I do not need to pass here first 2 arguments, "filePath" and "runNumber", because they are initialized at call from data members. + // But since this function is called only once, it's not an important performance loss. But re-think the design here eventually. + + // a) Return value; + // b) Basic protection for arguments; + // c) Determine from filePath if the file in on a local machine, or in AliEn, or in CCDB; + // d) Handle the AliEn case; + // e) Handle the CCDB case; + // f) Handle the local case; + // g) The final touch on histogram with centrality weights. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + LOGF(info, "\033[1;33m filePath = %s\033[0m", filePath); + LOGF(info, "\033[1;33m runNumber = %s\033[0m", runNumber); + LOGF(info, "\033[1;33m fTaskName = %s\033[0m", tc.fTaskName.Data()); + } + + // a) Return value: + TH1D* hist = NULL; + TList* baseList = NULL; // base top-level list in the TFile, e.g. named "ccdb_object" + TList* listWithRuns = NULL; // nested list with run-wise TList's holding run-specific weights + + // b) Basic protection for arguments: + // ... + + // c) Determine from filePath if the file in on a local machine, or in home + // dir AliEn, or in CCDB: + // Algorithm: If filePath begins with "/alice/cern.ch/" then it's in home + // dir AliEn. If filePath begins with "/alice-ccdb.cern.ch/" then it's in + // CCDB. Therefore, files in AliEn and CCDB must be specified with abs path, + // for local files both abs and relative paths are just fine. + Bool_t bFileIsInAliEn = kFALSE; + Bool_t bFileIsInCCDB = kFALSE; + if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + bFileIsInAliEn = kTRUE; + } else { + if (TString(filePath).BeginsWith("/alice-ccdb.cern.ch/")) { + bFileIsInCCDB = kTRUE; + } // else { + } // if (TString(filePath).BeginsWith("/alice/cern.ch/")) { + + if (bFileIsInAliEn) { + // d) Handle the AliEn case: + TGrid* alien = TGrid::Connect("alien", gSystem->Getenv("USER"), "", ""); + if (!alien) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + TFile* centralityWeightsFile = TFile::Open(Form("alien://%s", filePath), "READ"); + if (!centralityWeightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + centralityWeightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, harwired name + // of base TList is "ccdb_object" also for + // AliEn case, see if I need to change this + if (!baseList) { + // centralityWeightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else if (bFileIsInCCDB) { + + // e) Handle the CCDB case: Remember that here I do not access the file, + // instead directly object in that file. + // My home dir in CCDB: https://alice-ccdb.cern.ch/browse/Users/a/abilandz/ + // Inspired by: + // 1. Discussion at: + // https://alice-talk.web.cern.ch/t/access-to-lhc-filling-scheme/1073/17 + // 2. See also: + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyGlobal.cxx + // https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/efficiencyPerRun.cxx + // 3. O2 Analysis Tutorial 2.0: + // https://indico.cern.ch/event/1267433/timetable/#20230417.detailed + + ccdb->setURL("http://alice-ccdb.cern.ch"); + if (tc.fVerbose) { + LOGF(info, "\033[1;32mAccessing in CCDB %s\033[0m", TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data()); + } + + baseList = reinterpret_cast(ccdb->get(TString(filePath).ReplaceAll("/alice-ccdb.cern.ch/", "").Data())); + + if (!baseList) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } else { + + // f) Handle the local case: + // TBI 20231008 In principle, also for the local case in O2, I could + // maintain the same local structure of weights as it was in AliPhysics. + // But for simplicity, in O2 I organize local weights in the + // same way as in AliEn or CCDB. + + // Check if the external ROOT file exists at specified path: + if (gSystem->AccessPathName(filePath, kFileExists)) { + LOGF(info, "\033[1;33m if(gSystem->AccessPathName(filePath,kFileExists)), filePath = %s \033[0m", filePath); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + TFile* centralityWeightsFile = TFile::Open(filePath, "READ"); + if (!centralityWeightsFile) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + centralityWeightsFile->GetObject("ccdb_object", baseList); // TBI 20231008 for simplicity, harwired name + // of base TList is "ccdb_object" also for + // local case, see if I need to change this + if (!baseList) { + // centralityWeightsFile->ls(); + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumber)); + if (!listWithRuns) { + TString runNumberWithLeadingZeroes = "000"; + runNumberWithLeadingZeroes += runNumber; // another try, with "000" prepended to run number + listWithRuns = reinterpret_cast(GetObjectFromList(baseList, runNumberWithLeadingZeroes.Data())); + if (!listWithRuns) { + LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); + } + } + + } // else { + + // g) The final touch on histogram with centrality weights: + // fetch histogram directly from this list: + hist = reinterpret_cast(listWithRuns->FindObject(Form("%s_%s", ec.fsEventCuts[eCentralityEstimator].Data(), tc.fTaskName.Data()))); + // if the previous search failed, descend recursively also into the nested lists: + if (!hist) { + hist = reinterpret_cast(GetObjectFromList(listWithRuns, Form("%s_%s", ec.fsEventCuts[eCentralityEstimator].Data(), tc.fTaskName.Data()))); + } + if (!hist) { + hist = reinterpret_cast(GetObjectFromList(listWithRuns, Form("%s", ec.fsEventCuts[eCentralityEstimator].Data()))); // yes, for some simple tests I can have only histogram named e.g. 'CentFT0C' + } + if (!hist) { + listWithRuns->ls(); + LOGF(fatal, "\033[1;31m%s at line %d : \033[0m", __FUNCTION__, __LINE__); + } + hist->SetDirectory(0); + hist->SetTitle(Form("%s, %s", filePath, runNumber)); // I have to do it here, because only here I have "filePath" available + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + + return hist; + +} // TH1D* GetHistogramWithCentralityWeights(const char* filePath, const char* runNumber) + +//============================================================ + +TObjArray* GetDefaultObjArrayWithLabels() +{ + // To speed up testing, I hardwire here some labels and use them directly as they are. + + // Define TObjArray: + TObjArray* arr = new TObjArray(); + arr->SetOwner(); + + // Define some labels: + const Int_t nLabels = 4; + TString labels[nLabels] = {"1 -1", "2 -2", "1 2 -3", "2 3 -3 -2"}; + + // Make a transfer: + for (Int_t l = 0; l < nLabels; l++) { + TObjString* objstr = new TObjString(labels[l].Data()); + arr->Add(objstr); + } + + return arr; + +} // TObjArray* GetDefaultObjArrayWithLabels() + +//============================================================ + TObjArray* GetObjArrayWithLabels(const char* filePath) { // This function extracts from an external file TObjArray named "labels", and - // returns it. External file can be: 1) on a local computer; 2) in home - // directory AliEn => configurable "cfFileWithLabels" must begin with - // "/alice/cern.ch/" 3) in CCDB => configurable "cfFileWithLabels" must begin - // with "/alice-ccdb.cern.ch/" For all CCDB wisdom, see toggle "CCDB" in page - // "O2" + // returns it. External file can be: + // 1) on a local computer; + // 2) in home directory AliEn => configurable "cfFileWithLabels" must begin with "/alice/cern.ch/" + // 3) in CCDB => configurable "cfFileWithLabels" must begin with "/alice-ccdb.cern.ch/" + // For all CCDB wisdom, see toggle "CCDB" in page "O2" // a) Return value; // b) Determine from filePath if the file in on a local machine, or in AliEn; @@ -7769,7 +8136,12 @@ void StoreLabelsInPlaceholder() } // now it's safe :-) // b) Fetch TObjArray with labels from an external file: - TObjArray* oa = GetObjArrayWithLabels(t0.fFileWithLabels.Data()); + TObjArray* oa = NULL; + if (t0.fUseDefaultLabels) { + oa = GetDefaultObjArrayWithLabels(); + } else { + oa = GetObjArrayWithLabels(t0.fFileWithLabels.Data()); + } if (!oa) { LOGF(info, "\033[1;33m fFileWithLabels = %s \033[0m", t0.fFileWithLabels.Data()); @@ -7994,10 +8366,10 @@ Double_t DiffWeight(const Double_t& valueY, const Double_t& valueX, eqvectorKine // *) Insanity checks on above settings: if (AFO_var == eAsFunctionOf_N) { - LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == eAsFunctionOf_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == eAsFunctionOf_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } if (AFO_diffWeight == eDiffWeights_N) { - LOGF(fatal, "\033[1;31m%s at line %d : AFO_diffWeight == eDiffWeights_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : AFO_diffWeight == eDiffWeights_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } // *) Determine first to which bin the 'valueX' corresponds to. @@ -8167,6 +8539,39 @@ void GetParticleWeights() //============================================================ +void GetCentralityWeights() +{ + // Get the centrality weights. Call this function only once. + + // TBI 20231012 Here the current working assumption is that: + // 1) Corrections do not change within a given run; + // 2) Hyperloop proceeses the dataset one masterjob per run number. + // If any of these 2 assumptions are violated, this code will have to be modified. + + // a) Centrality weights; + // b) ... + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // a) Centrality weights: + if (cw.fUseCentralityWeights) { + TH1D* centralityWeights = GetHistogramWithCentralityWeights(cw.fFileWithCentralityWeights.Data(), tc.fRunNumber.Data()); + if (!centralityWeights) { + LOGF(fatal, "in function \033[1;31m%s at line %d : centralityWeights is NULL. Check the external file %s with centrality weights\033[0m", __FUNCTION__, __LINE__, cw.fFileWithCentralityWeights.Data()); + } + SetCentralityWeightsHist(centralityWeights); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + +} // void GetCentralityWeights() + +//============================================================ + Bool_t MaxNumberOfEvents(eBeforeAfter ba) { // Check if max number of events was reached. Can be used for cut eNumberOfEvents (= total events, with ba = eBefore), and eSelectedEvents (ba = eAfter). @@ -8227,7 +8632,7 @@ Bool_t MaxNumberOfEvents(eBeforeAfter ba) void PrintEventCounter(eBeforeAfter ba) { // Print how many events were processed by now. - // If I am processing RecSim, the counter is corresponding to Rec. + // Remark: If I am processing RecSim, the counter is corresponding to Rec. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -8236,27 +8641,10 @@ void PrintEventCounter(eBeforeAfter ba) // *) Print or die: switch (ba) { case eBefore: - if (eh.fEventHistograms[eNumberOfEvents][eRec][eBefore]) { - LOGF(info, "\033[1;32m%s : processing event %d\033[0m", __FUNCTION__, static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eBefore]->GetBinContent(1))); - } else if (eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]) { - LOGF(info, "\033[1;32m%s : processing event %d\033[0m", __FUNCTION__, static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]->GetBinContent(1))); - } + LOGF(info, "\033[1;32m%s : processing event %d ....\033[0m", __FUNCTION__, eh.fEventCounter[eTotal]); break; case eAfter: - - // *) special treatment for internal validation - for the time being, I fill there only [eSim][eAfter]: - if (iv.fUseInternalValidation && eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]) { - LOGF(info, " Processing on-the-fly event # %d (total) .... ", static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1))); - break; - } - - // *) all other cases, besides internal validation: - if (eh.fEventHistograms[eNumberOfEvents][eRec][eBefore] && eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]) { - LOGF(info, "\033[1;32m%s : this event passed all cuts %d/%d\033[0m", __FUNCTION__, static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->GetBinContent(1)), static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eBefore]->GetBinContent(1))); - } else if (eh.fEventHistograms[eNumberOfEvents][eSim][eBefore] && eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]) { - LOGF(info, "\033[1;32m%s : this event passed all cuts %d/%d\033[0m", __FUNCTION__, static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1)), static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]->GetBinContent(1))); - } - + LOGF(info, "\033[1;32m%s : event passed all cuts %d/%d\033[0m", __FUNCTION__, eh.fEventCounter[eProcessed], eh.fEventCounter[eTotal]); break; default: LOGF(fatal, "\033[1;31m%s at line %d : enum ba = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(ba)); @@ -8271,7 +8659,7 @@ void PrintEventCounter(eBeforeAfter ba) //============================================================ -void EventCounter(eEventCounter eVar) +void EventCounterForDryRun(eEventCounterForDryRun eVar) { // Simple utility function which either fills histogram with event count, or prints its current content. // Remark: Use only in combination with tc.fDryRun = kTRUE, otherwise I might be filling the same histogram in different member functions, there is a protection below. @@ -8282,7 +8670,7 @@ void EventCounter(eEventCounter eVar) } if (!tc.fDryRun) { - LOGF(fatal, "\033[1;31m%s at line %d : for the time being, function EventCounter(...) can be safely used only for tc.fDryRun = kTRUE \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : for the time being, function EventCounterForDryRun(...) can be safely used only for tc.fDryRun = kTRUE \033[0m", __FUNCTION__, __LINE__); } switch (eVar) { @@ -8309,7 +8697,7 @@ void EventCounter(eEventCounter eVar) ExitFunction(__FUNCTION__); } -} // void EventCounter() +} // void EventCounterForDryRun() //============================================================ @@ -8346,9 +8734,11 @@ const char* FancyFormatting(const char* name) } else if (TString(name).EqualTo("Centrality")) { TString tmp = ec.fsEventCuts[eCentralityEstimator]; // I have to introduce local TString tmp, because ReplaceAll replaces in-place if (tmp.BeginsWith("CentRun2")) { - fancyFormatting = Form("Centrality (%s)", tmp.ReplaceAll("CentRun2", "").Data()); + fancyFormatting = Form("Centrality (%s)", tmp.ReplaceAll("CentRun2", "").Data()); // "CentRun2V0M" => "Centrality (V0M)" } else if (tmp.BeginsWith("Cent")) { - fancyFormatting = Form("Centrality (%s)", tmp.ReplaceAll("Cent", "").Data()); + fancyFormatting = Form("Centrality (%s)", tmp.ReplaceAll("Cent", "").Data()); // "CentFT0C" => "Centrality (FT0C)" + } else { + LOGF(fatal, "\033[1;31m%s at line %d : the case tmp = %s is not supported yet\033[0m", __FUNCTION__, __LINE__, tmp.Data()); } } else if (TString(name).EqualTo("Trigger")) { fancyFormatting = Form("Trigger (%s)", ec.fsEventCuts[eTrigger].Data()); @@ -8601,37 +8991,50 @@ Double_t CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_va StartFunction(__FUNCTION__); } + Trace(__FUNCTION__, __LINE__); + if (!harmonics) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } + Trace(__FUNCTION__, __LINE__); + // *) ... eqvectorKine qvKine = eqvectorKine_N; // which component of q-vector TString kineVarName = ""; switch (AFO_variable) { case AFO_PT: + Trace(__FUNCTION__, __LINE__); qvKine = PTq; kineVarName = "pt"; break; case AFO_ETA: + Trace(__FUNCTION__, __LINE__); qvKine = ETAq; kineVarName = "eta"; break; default: + Trace(__FUNCTION__, __LINE__); LOGF(fatal, "\033[1;31m%s at line %d : This AFO_variable = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable)); break; } // switch(AFO_variable) + Trace(__FUNCTION__, __LINE__); + // *) Insanity checks on above settings: if (qvKine == eqvectorKine_N) { - LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : qvKine == eqvectorKine_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } + Trace(__FUNCTION__, __LINE__); + if (0 > bin || res.fResultsPro[AFO_variable]->GetNbinsX() < bin) { // this 'bin' starts from 0, i.e. this is an array bin // either underflow or overflow is hit, meaning that histogram is booked in narrower range than cuts LOGF(fatal, "\033[1;31m%s at line %d => AFO_variable = %d, bin = %d\033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable), bin); } + Trace(__FUNCTION__, __LINE__); + // Get the number of particles in this kine bin: Int_t nParticles = 0; for (Int_t i = 0; i < nl.ftaNestedLoopsKine[qvKine][bin][0]->GetSize(); i++) { @@ -8640,26 +9043,41 @@ Double_t CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_va } } + Trace(__FUNCTION__, __LINE__); + // 'qvKine' is enum eqvectorKine: if (!res.fResultsPro[AFO_variable]) { LOGF(fatal, "\033[1;31m%s at line %d : AFO_variable = %d, bin = %d \033[0m", __FUNCTION__, __LINE__, static_cast(AFO_variable), bin); } + + Trace(__FUNCTION__, __LINE__); + LOGF(info, " Processing qvKine = %d (vs. %s), nParticles in this kine bin = %d, bin range = [%f,%f) ....", static_cast(qvKine), kineVarName.Data(), nParticles, res.fResultsPro[AFO_variable]->GetBinLowEdge(bin + 1), res.fResultsPro[AFO_variable]->GetBinLowEdge(bin + 2)); + Trace(__FUNCTION__, __LINE__); + // a) Determine the order of correlator; Int_t order = harmonics->GetSize(); if (0 == order || order > gMaxCorrelator) { LOGF(fatal, "\033[1;31m%s at line %d\033[0m", __FUNCTION__, __LINE__); } + + Trace(__FUNCTION__, __LINE__); + if (order > nParticles) { LOGF(info, " There is no enough particles in this bin to calculate the requested correlator"); return 0.; // TBI 20240405 Is this really safe here? Re-think... } + + Trace(__FUNCTION__, __LINE__); + if (nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order) { LOGF(info, " nl.fMaxNestedLoop > 0 && nl.fMaxNestedLoop < order, where nl.fMaxNestedLoop = %d, order = %d", nl.fMaxNestedLoop, order); return 0.; // TBI 20240405 Is this really safe here? Re-think... } + Trace(__FUNCTION__, __LINE__); + // b) Custom nested loop: TProfile* profile = new TProfile("profile", "", 1, 0., 1.); // helper profile to get all averages automatically // profile->Sumw2(); @@ -8822,10 +9240,18 @@ Double_t CalculateKineCustomNestedLoops(TArrayI* harmonics, eAsFunctionOf AFO_va } // for(int i2=0; i2GetBinContent(1); + + Trace(__FUNCTION__, __LINE__); + delete profile; profile = NULL; + + Trace(__FUNCTION__, __LINE__); + if (tc.fVerbose) { ExitFunction(__FUNCTION__); } @@ -8855,17 +9281,20 @@ void DetermineCentrality(T const& collision) // a) For real data, determine centrality from default centrality estimator: if constexpr (rs == eRec || rs == eRecAndSim) { - if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0M", TString::kIgnoreCase)) { + if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0C", TString::kIgnoreCase)) { + ebye.fCentrality = collision.centFT0C(); + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFT0M", TString::kIgnoreCase)) { ebye.fCentrality = collision.centFT0M(); - } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("CentFV0A", TString::kIgnoreCase)) { + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centFV0A", TString::kIgnoreCase)) { ebye.fCentrality = collision.centFV0A(); - } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("CentNTPV", TString::kIgnoreCase)) { + } else if (ec.fsEventCuts[eCentralityEstimator].EqualTo("centNTPV", TString::kIgnoreCase)) { ebye.fCentrality = collision.centNTPV(); } else { LOGF(fatal, "\033[1;31m%s at line %d : centrality estimator = %d is not supported yet. \033[0m", __FUNCTION__, __LINE__, ec.fsEventCuts[eCentralityEstimator].Data()); } // QA: if (qa.fFillQAEventHistograms2D) { // TBI 20240515 this flag is too general here, I need to make it more specific + qa.fCentrality[eCentFT0C] = collision.centFT0C(); qa.fCentrality[eCentFT0M] = collision.centFT0M(); qa.fCentrality[eCentFV0A] = collision.centFV0A(); qa.fCentrality[eCentNTPV] = collision.centNTPV(); @@ -8983,6 +9412,32 @@ void DetermineOccupancy(T const& collision) //============================================================ +void DetermineEventCounters() +{ + // Determine all event counters. + + if (tc.fVerbose) { + StartFunction(__FUNCTION__); + } + + // Remark: For "RecSim", the total number of events is taken from eRec. + if (eh.fEventHistograms[eNumberOfEvents][eRec][eBefore] && eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]) { + eh.fEventCounter[eTotal] = static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eBefore]->GetBinContent(1)); + eh.fEventCounter[eProcessed] = static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->GetBinContent(1)); + } else if (eh.fEventHistograms[eNumberOfEvents][eSim][eBefore] && eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]) { + // Remark: This branch covers automatically also internal validation, because I book and fill there on [eSim]. + eh.fEventCounter[eTotal] = static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eBefore]->GetBinContent(1)); + eh.fEventCounter[eProcessed] = static_cast(eh.fEventHistograms[eNumberOfEvents][eSim][eAfter]->GetBinContent(1)); + } + + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + +} // void DetermineEventCounters() + +//============================================================ + void RandomIndices(Int_t nTracks) { // Randomize indices using Fisher-Yates algorithm. @@ -9085,7 +9540,7 @@ void BanishmentLoopOverParticles(T const& tracks) // *) 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 == lSelectedTracks) { - LOGF(info, "%s Breaking the loop over particles, since requested fixed number of %d particles was reached", __FUNCTION__, tc.fFixedNumberOfRandomlySelectedTracks); + LOGF(info, "%s : Breaking the loop over particles, since requested fixed number of %d particles was reached", __FUNCTION__, tc.fFixedNumberOfRandomlySelectedTracks); break; } @@ -9157,6 +9612,19 @@ void Trace(const char* functionName, Int_t lineNumber) //============================================================ +void Exit() +{ + // A simple utility wrapper. Used only during debugging. + // Use directly as: Exit(); + // Line number, function name, formatting, etc, are determinad automatically. + + LOGF(info, "\n\n\n\n\n\n\n\n\n\n"); + exit(1); + +} // void Exit() + +//============================================================ + void StartFunction(const char* functionName) { // A simple utility wrapper, used when tc.fVerbose = kTRUE. It merely ensures uniform formatting of notification when the function starts. @@ -9177,9 +9645,14 @@ void ExitFunction(const char* functionName) //============================================================ -void BailOut() +void BailOut(Bool_t finalBailout = kFALSE) { // Use only locally - bail out if maximum number of events was reached, and dump all results by that point in a local ROOT file. + // If fSequentialBailout > 0, bail out is performed each fSequentialBailout events, each time in a new local ROOT file. + // For sequential bailout, the naming scheme of ROOT files is AnalysisResultsBailOut_eh.fEventCounter[eProcessed].root . + // If ROOT file with the same name already exists, BailOut is not performed, since the argument is that + // it's pointless to perform Bailout for same eh.fEventCounter[eProcessed], even if eh.fEventCounter[eTotal] changed. + // Only if finalBailout = kTRUE, I will overwrite the existing file with the same name. if (tc.fVerbose) { StartFunction(__FUNCTION__); @@ -9189,6 +9662,17 @@ void BailOut() TString sBailOutFile = "AnalysisResultsBailOut.root"; TString sDirectoryFile = "multiparticle-correlations-a-b"; + // *) For sequential bailout, I need to adapt the ROOT file name, each time this function is called: + if (tc.fSequentialBailout > 0) { + sBailOutFile.ReplaceAll(".root", Form("_%d.root", eh.fEventCounter[eProcessed])); // replaces in-place + // basically, at 1st call "AnalysisResultsBailOut.root" => "AnalysisResultsBailOut_1*eh.fEventCounter[eProcessed].root", + // at 2nd call "AnalysisResultsBailOut.root" => "AnalysisResultsBailOut_2*eh.fEventCounter[eProcessed].root", etc. + if (!finalBailout && !gSystem->AccessPathName(sBailOutFile.Data(), kFileExists)) { // only for finalBailout = kTRUE, I will overwrite the existing file with the same name. + LOGF(info, "\033[1;33m\nsBailOutFile = %s already exits, that means that eh.fEventCounter[eProcessed] is the same as in the previous call of BailOut.\nJust skipping and waiting more event to pass selection criteria... \033[0m", sBailOutFile.Data()); + return; + } + } + // *) Info message: if (eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]) { LOGF(info, "\033[1;32m=> Per request, bailing out after %d selected events in the local file %s .\n\033[0m", static_cast(eh.fEventHistograms[eNumberOfEvents][eRec][eAfter]->GetBinContent(1)), sBailOutFile.Data()); @@ -9201,7 +9685,7 @@ void BailOut() // Therefore, adding one-by-one nested TList's I want to bail out. // Keep in sync with BookAndNestAllLists(). TList* bailOutList = new TList(); // this is sort of 'fake' fBaseList - bailOutList->SetOwner(kTRUE); + bailOutList->SetOwner(kFALSE); // yes, beacause for sequential bailout, with SetOwner(kTRUE) the code is crashing after 1st sequential bailout is done bailOutList->SetName(sBaseListName.Data()); bailOutList->Add(fBasePro); // yes, this one needs a special treatment bailOutList->Add(qa.fQAList); @@ -9225,13 +9709,21 @@ void BailOut() dirFile = NULL; f->Close(); - // *) Hasta la vista: - if (tc.fVerbose) { - LOGF(fatal, "\n\nHasta la vista - bailed out intentionally in function \033[1;31m%s at line %d\n The output file is: %s\n\n\033[0m", __FUNCTION__, __LINE__, sBailOutFile.Data()); + if (tc.fVerbose && !(tc.fSequentialBailout > 0)) { // then it will be called only once, for the only and permanent bailout ExitFunction(__FUNCTION__); } -} // void BailOut() + // *) Hasta la vista: + if (finalBailout) { + LOGF(fatal, "\033[1;31mHasta la vista - bailed out permanently in function %s at line %d\n The output file is: %s\n\n\033[0m", __FUNCTION__, __LINE__, sBailOutFile.Data()); + } else { + LOGF(info, "\033[1;32mBailed out sequentially in function %s at line %d\n The output file is: %s\n\n\033[0m", __FUNCTION__, __LINE__, sBailOutFile.Data()); + if (tc.fVerbose) { + ExitFunction(__FUNCTION__); + } + } + +} // void BailOut(Bool_t finalBailout = kFALSE) //============================================================ @@ -9333,13 +9825,13 @@ void Fillqvector(const Double_t& dPhi, const Double_t& kineVarValue, eqvectorKin // *) Insanity checks on above settings: if (AFO_var == eAsFunctionOf_N) { - LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == eAsFunctionOf_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : AFO_var == eAsFunctionOf_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } if (AFO_weight == eWeights_N) { - LOGF(fatal, "\033[1;31m%s at line %d : AFO_weight == eWeights_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : AFO_weight == eWeights_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } if (AFO_diffWeight == eDiffWeights_N) { - LOGF(fatal, "\033[1;31m%s at line %d : AFO_diffWeight == eDiffWeights_N => add some more entries to the case stamenent \033[0m", __FUNCTION__, __LINE__); + LOGF(fatal, "\033[1;31m%s at line %d : AFO_diffWeight == eDiffWeights_N => add some more entries to the case statement \033[0m", __FUNCTION__, __LINE__); } // *) Get the desired bin number: @@ -9473,8 +9965,8 @@ void Steer(T1 const& collision, T2 const& tracks) // *) Dry run: if (tc.fDryRun) { - EventCounter(eFill); - EventCounter(ePrint); + EventCounterForDryRun(eFill); + EventCounterForDryRun(ePrint); Preprocess(collision); // yes, so that e.g. I can only test if the weights were correctly fetched from external file and initialized locally into data members return; } @@ -9490,7 +9982,7 @@ void Steer(T1 const& collision, T2 const& tracks) // *) Global timestamp: if (tc.fUseStopwatch) { - LOGF(info, "\033[1;32m\n\n=> Global timer: Steer begins ... %.6f\n\033[0m", tc.fTimer[eGlobal]->RealTime()); + LOGF(info, "\033[1;32m=> Global timer: Steer begins ... %.6f\033[0m", tc.fTimer[eGlobal]->RealTime()); tc.fTimer[eGlobal]->Continue(); // yes } @@ -9571,7 +10063,7 @@ void Steer(T1 const& collision, T2 const& tracks) // *) Global timestamp: if (tc.fUseStopwatch) { - LOGF(info, "\033[1;32m\n\n=> Global timer: Steer ends ... %.6f\n\n\033[0m", tc.fTimer[eGlobal]->RealTime()); + LOGF(info, "\033[1;32m=> Global timer: Steer ends ... %.6f\033[0m\n", tc.fTimer[eGlobal]->RealTime()); tc.fTimer[eGlobal]->Continue(); // yes } @@ -9620,7 +10112,7 @@ void MainLoopOverParticles(T const& tracks) } // *) Local timestamp: - if (tc.fUseStopwatch) { + if (tc.fUseStopwatch && tc.fVerboseUtility) { LOGF(info, " Local timer starts at line %d", __LINE__); tc.fTimer[eLocal]->Reset(); tc.fTimer[eLocal]->Start(); @@ -9695,14 +10187,14 @@ void MainLoopOverParticles(T const& tracks) // *) 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 == ebye.fSelectedTracks) { - LOGF(info, " Breaking the loop over particles, since requested fixed number of %d particles was reached", tc.fFixedNumberOfRandomlySelectedTracks); + LOGF(info, "%s : Breaking the loop over particles, since requested fixed number of %d particles was reached", __FUNCTION__, tc.fFixedNumberOfRandomlySelectedTracks); break; } } // for (auto& track : tracks) // *) Local timestamp: - if (tc.fUseStopwatch) { + if (tc.fUseStopwatch && tc.fVerboseUtility) { LOGF(info, " Local timer ends at line %d, time elapsed ... %.6f", __LINE__, tc.fTimer[eLocal]->RealTime()); tc.fTimer[eLocal]->Continue(); } diff --git a/PWGCF/MultiparticleCorrelations/Tasks/ThreeParticleCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/ThreeParticleCorrelations.cxx index f16e72accd1..375f5917eba 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/ThreeParticleCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/ThreeParticleCorrelations.cxx @@ -9,20 +9,24 @@ // 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 "CCDB/BasicCCDBManager.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" #include "PWGLF/DataModel/LFStrangenessTables.h" #include "TPDGCode.h" -#include "TLorentzVector.h" +#include "RecoDecay.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; struct ThreePartCorr { + Service CCDB; // Histogram registry HistogramRegistry MECorrRegistry{"MECorrRegistry", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; @@ -79,6 +83,11 @@ struct ThreePartCorr { Double_t massLambda = o2::constants::physics::MassLambda0; Double_t DGaussSigma = 0.0021; + // Efficiency histograms + TH1D** hEffPions = new TH1D*[2]; + TH1D** hEffKaons = new TH1D*[2]; + TH1D** hEffProtons = new TH1D*[2]; + // Correlation variables Int_t T_Sign; Double_t CandMass; @@ -146,6 +155,16 @@ struct ThreePartCorr { MECorrRegistry.add("hMixLambdaKaon_SB", "Mixed-event #Lambda - K correlator (SB region)", {HistType::kTHnSparseD, {{PhiAxis}, {EtaAxis}, {CentralityAxis}, {ZvtxAxis}, {2, -2, 2}, {2, -2, 2}}}); MECorrRegistry.add("hMixLambdaProton_SGNL", "Mixed-event #Lambda - p correlator (SGNL region)", {HistType::kTHnSparseD, {{PhiAxis}, {EtaAxis}, {CentralityAxis}, {ZvtxAxis}, {2, -2, 2}, {2, -2, 2}}}); MECorrRegistry.add("hMixLambdaProton_SB", "Mixed-event #Lambda - p correlator (SB region)", {HistType::kTHnSparseD, {{PhiAxis}, {EtaAxis}, {CentralityAxis}, {ZvtxAxis}, {2, -2, 2}, {2, -2, 2}}}); + + CCDB->setURL("http://alice-ccdb.cern.ch"); + CCDB->setCaching(true); + TList* EfficiencyList = CCDB->getForTimeStamp("Users/j/jstaa/Efficiency/ChargedParticles", 1); + hEffPions[0] = static_cast(EfficiencyList->FindObject("hEfficiencyPionP")); + hEffPions[1] = static_cast(EfficiencyList->FindObject("hEfficiencyPionN")); + hEffKaons[0] = static_cast(EfficiencyList->FindObject("hEfficiencyKaonP")); + hEffKaons[1] = static_cast(EfficiencyList->FindObject("hEfficiencyKaonN")); + hEffProtons[0] = static_cast(EfficiencyList->FindObject("hEfficiencyProtonP")); + hEffProtons[1] = static_cast(EfficiencyList->FindObject("hEfficiencyProtonN")); } //================================================================================================================================================================================================================ @@ -205,19 +224,19 @@ struct ThreePartCorr { if (CandMass >= massLambda - 4 * DGaussSigma && CandMass <= massLambda + 4 * DGaussSigma) { if (A_PID[0] == 0.0) { // Pions - SECorrRegistry.fill(HIST("hSameLambdaPion_SGNL"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign()); + SECorrRegistry.fill(HIST("hSameLambdaPion_SGNL"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffPions, associate.sign(), associate.pt())); } else if (A_PID[0] == 1.0) { // Kaons - SECorrRegistry.fill(HIST("hSameLambdaKaon_SGNL"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign()); + SECorrRegistry.fill(HIST("hSameLambdaKaon_SGNL"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffKaons, associate.sign(), associate.pt())); } else if (A_PID[0] == 2.0) { // Protons - SECorrRegistry.fill(HIST("hSameLambdaProton_SGNL"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign()); + SECorrRegistry.fill(HIST("hSameLambdaProton_SGNL"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffProtons, associate.sign(), associate.pt())); } } else if (CandMass >= massLambda - 8 * DGaussSigma && CandMass <= massLambda + 8 * DGaussSigma) { if (A_PID[0] == 0.0) { // Pions - SECorrRegistry.fill(HIST("hSameLambdaPion_SB"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign()); + SECorrRegistry.fill(HIST("hSameLambdaPion_SB"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffPions, associate.sign(), associate.pt())); } else if (A_PID[0] == 1.0) { // Kaons - SECorrRegistry.fill(HIST("hSameLambdaKaon_SB"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign()); + SECorrRegistry.fill(HIST("hSameLambdaKaon_SB"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffKaons, associate.sign(), associate.pt())); } else if (A_PID[0] == 2.0) { // Protons - SECorrRegistry.fill(HIST("hSameLambdaProton_SB"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign()); + SECorrRegistry.fill(HIST("hSameLambdaProton_SB"), DeltaPhi, DeltaEta, collision.centFT0C(), collision.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffProtons, associate.sign(), associate.pt())); } } } @@ -250,19 +269,19 @@ struct ThreePartCorr { if (CandMass >= massLambda - 4 * DGaussSigma && CandMass <= massLambda + 4 * DGaussSigma) { if (A_PID[0] == 0.0) { // Pions - MECorrRegistry.fill(HIST("hMixLambdaPion_SGNL"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign()); + MECorrRegistry.fill(HIST("hMixLambdaPion_SGNL"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffPions, associate.sign(), associate.pt())); } else if (A_PID[0] == 1.0) { // Kaons - MECorrRegistry.fill(HIST("hMixLambdaKaon_SGNL"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign()); + MECorrRegistry.fill(HIST("hMixLambdaKaon_SGNL"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffKaons, associate.sign(), associate.pt())); } else if (A_PID[0] == 2.0) { // Protons - MECorrRegistry.fill(HIST("hMixLambdaProton_SGNL"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign()); + MECorrRegistry.fill(HIST("hMixLambdaProton_SGNL"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffProtons, associate.sign(), associate.pt())); } } else if (CandMass >= massLambda - 8 * DGaussSigma && CandMass <= massLambda + 8 * DGaussSigma) { if (A_PID[0] == 0.0) { // Pions - MECorrRegistry.fill(HIST("hMixLambdaPion_SB"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign()); + MECorrRegistry.fill(HIST("hMixLambdaPion_SB"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffPions, associate.sign(), associate.pt())); } else if (A_PID[0] == 1.0) { // Kaons - MECorrRegistry.fill(HIST("hMixLambdaKaon_SB"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign()); + MECorrRegistry.fill(HIST("hMixLambdaKaon_SB"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffKaons, associate.sign(), associate.pt())); } else if (A_PID[0] == 2.0) { // Protons - MECorrRegistry.fill(HIST("hMixLambdaProton_SB"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign()); + MECorrRegistry.fill(HIST("hMixLambdaProton_SB"), DeltaPhi, DeltaEta, coll_1.centFT0C(), coll_1.posZ(), T_Sign, associate.sign(), 1. / TrackEff(hEffProtons, associate.sign(), associate.pt())); } } } @@ -352,6 +371,32 @@ struct ThreePartCorr { return dPhi; } + Double_t TrackEff(TH1D** Efficiencies, Int_t Sign, Double_t pT) + { + + Int_t Index = -999; + if (Sign > 0) { + Index = 0; + } else if (Sign < 0) { + Index = 1; + } + + return Efficiencies[Index]->GetBinContent(Efficiencies[Index]->FindBin(pT)); + } + + template + Int_t V0Sign(const V0Cand& V0) + { + + if (TMath::Abs(V0.mLambda() - massLambda) <= TMath::Abs(V0.mAntiLambda() - massLambda)) { + return 1; + } else if (TMath::Abs(V0.mLambda() - massLambda) > TMath::Abs(V0.mAntiLambda() - massLambda)) { + return -1; + } + + return 0; + } + template Double_t* TrackPID(const TrackCand& Track) { @@ -387,19 +432,6 @@ struct ThreePartCorr { return ID; } - template - Int_t V0Sign(const V0Cand& V0) - { - - if (TMath::Abs(V0.mLambda() - massLambda) <= TMath::Abs(V0.mAntiLambda() - massLambda)) { - return 1; - } else if (TMath::Abs(V0.mLambda() - massLambda) > TMath::Abs(V0.mAntiLambda() - massLambda)) { - return -1; - } - - return 0; - } - template Bool_t V0Filters(const V0Cand& V0) { @@ -439,28 +471,37 @@ struct ThreePartCorr { if (ConfFilterSwitch) { - TLorentzVector Daughter, Associate; if (TrackPID(Track)[0] == 1.0) { // Kaons return kTRUE; - } else if (V0Sign(V0) == 1 && TrackPID(Track)[0] == 0.0 && Track.sign() == -1) { // Lambda - Pi_min - const auto& dTrack = V0.template posTrack_as(); - Daughter.SetPtEtaPhiM(dTrack.pt(), dTrack.eta(), dTrack.phi(), o2::constants::physics::MassProton); - Associate.SetPtEtaPhiM(Track.pt(), Track.eta(), Track.phi(), o2::constants::physics::MassPionCharged); - } else if (V0Sign(V0) == -1 && TrackPID(Track)[0] == 0.0 && Track.sign() == 1) { // Antilambda - Pi_plus - const auto& dTrack = V0.template negTrack_as(); - Daughter.SetPtEtaPhiM(dTrack.pt(), dTrack.eta(), dTrack.phi(), o2::constants::physics::MassProton); - Associate.SetPtEtaPhiM(Track.pt(), Track.eta(), Track.phi(), o2::constants::physics::MassPionCharged); - } else if (V0Sign(V0) == 1 && TrackPID(Track)[0] == 2.0 && Track.sign() == 1) { // Lambda - Proton - const auto& dTrack = V0.template negTrack_as(); - Daughter.SetPtEtaPhiM(dTrack.pt(), dTrack.eta(), dTrack.phi(), o2::constants::physics::MassPionCharged); - Associate.SetPtEtaPhiM(Track.pt(), Track.eta(), Track.phi(), o2::constants::physics::MassProton); - } else if (V0Sign(V0) == -1 && TrackPID(Track)[0] == 2.0 && Track.sign() == -1) { // Antilambda - Antiproton - const auto& dTrack = V0.template posTrack_as(); - Daughter.SetPtEtaPhiM(dTrack.pt(), dTrack.eta(), dTrack.phi(), o2::constants::physics::MassPionCharged); - Associate.SetPtEtaPhiM(Track.pt(), Track.eta(), Track.phi(), o2::constants::physics::MassProton); } - if ((Daughter + Associate).M() >= massLambda - 4 * DGaussSigma && (Daughter + Associate).M() <= massLambda + 4 * DGaussSigma) { + std::array MassArray; + std::array DMomArray; + std::array AMomArray = Track.pVector(); + if (TrackPID(Track)[0] == 0.0) { + MassArray = {o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}; + + if (V0Sign(V0) == 1 && Track.sign() == -1) { // Lambda - Pi_min + const auto& dTrack = V0.template posTrack_as(); + DMomArray = dTrack.pVector(); + } else if (V0Sign(V0) == -1 && Track.sign() == 1) { // Antilambda - Pi_plus + const auto& dTrack = V0.template negTrack_as(); + DMomArray = dTrack.pVector(); + } + } else if (TrackPID(Track)[0] == 2.0) { + MassArray = {o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}; + + if (V0Sign(V0) == 1 && Track.sign() == 1) { // Lambda - Proton + const auto& dTrack = V0.template negTrack_as(); + DMomArray = dTrack.pVector(); + } else if (V0Sign(V0) == -1 && Track.sign() == -1) { // Antilambda - Antiproton + const auto& dTrack = V0.template posTrack_as(); + DMomArray = dTrack.pVector(); + } + } + + Double_t M = RecoDecay::m(std::array{DMomArray, AMomArray}, MassArray); + if (M >= massLambda - 4 * DGaussSigma && M <= massLambda + 4 * DGaussSigma) { return kFALSE; } } diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx index 47a66f60ca0..fd0b3942024 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx @@ -24,7 +24,7 @@ using namespace o2; using namespace o2::framework; // *) Run 3: -using EventSelection = soa::Join; +using EventSelection = soa::Join; using CollisionRec = soa::Join::iterator; // use in json "isMC": "true" for "event-selection-task" using CollisionRecSim = soa::Join::iterator; using CollisionSim = aod::McCollision; @@ -62,6 +62,7 @@ using CollisionRecSim_Run1 = soa::Join #include #include +#include using namespace std; // *) Enums: @@ -133,6 +134,7 @@ struct MultiparticleCorrelationsAB // this name is used in lower-case format to BookQvectorHistograms(); BookCorrelationsHistograms(); BookWeightsHistograms(); + BookCentralityWeightsHistograms(); BookNestedLoopsHistograms(); BookNUAHistograms(); BookInternalValidationHistograms(); diff --git a/PWGCF/Tasks/CMakeLists.txt b/PWGCF/Tasks/CMakeLists.txt index fdc35cf2ef6..ab3d5edd9e2 100644 --- a/PWGCF/Tasks/CMakeLists.txt +++ b/PWGCF/Tasks/CMakeLists.txt @@ -28,3 +28,8 @@ o2physics_add_dpl_workflow(correlations SOURCES correlations.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(pid-cme + SOURCES pidcme.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Tasks/pidcme.cxx b/PWGCF/Tasks/pidcme.cxx new file mode 100644 index 00000000000..a776e584f7d --- /dev/null +++ b/PWGCF/Tasks/pidcme.cxx @@ -0,0 +1,498 @@ +// 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. + +// C++/ROOT includes. +#include +#include +#include +#include +#include +#include +#include +#include + +// o2Physics includes. +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StaticFor.h" + +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/PIDResponse.h" + +#include "CommonConstants/PhysicsConstants.h" + +// o2 includes. + +using namespace o2; +using namespace o2::framework; + +using MyCollisions = soa::Join; +using MyTracks = soa::Join; + +struct pidcme { + HistogramRegistry histosQA{"histosQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable> cfgnMods{"cfgnMods", {2}, "Modulation of interest"}; + Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; + Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; + + Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; + + Configurable cfgMinPt{"cfgMinPt", 0.15, "Minimum transverse momentum for charged track"}; + Configurable cfgMaxEta{"cfgMaxEta", 0.8, "Maximum pseudorapidiy for charged track"}; + Configurable cfgMaxDCArToPVcut{"cfgMaxDCArToPVcut", 0.1, "Maximum transverse DCA"}; + Configurable cfgMaxDCAzToPVcut{"cfgMaxDCAzToPVcut", 1.0, "Maximum longitudinal DCA"}; + + Configurable cfgnSigmaCutTPCPi{"cfgnSigmaCutTPCPi", 3.0, "Value of the TPC Nsigma cut for pions"}; + Configurable cfgnSigmaCutTPCKa{"cfgnSigmaCutTPCKa", 3.0, "Value of the TPC Nsigma cut for kaons"}; + Configurable cfgnSigmaCutTPCPr{"cfgnSigmaCutTPCPr", 3.0, "Value of the TPC Nsigma cut for protons"}; + Configurable cfgnSigmaCutTOFPi{"cfgnSigmaCutTOFPi", 3.0, "Value of the TOF Nsigma cut for pions"}; + Configurable cfgnSigmaCutTOFKa{"cfgnSigmaCutTOFKa", 3.0, "Value of the TOF Nsigma cut for kaons"}; + Configurable cfgnSigmaCutTOFPr{"cfgnSigmaCutTOFPr", 3.0, "Value of the TOF Nsigma cut for protons"}; + Configurable cfgnSigmaCutCombine{"cfgnSigmaCutCombine", 3.0, "Value of the Combined Nsigma cut"}; + + ConfigurableAxis cfgaxisQvecF{"cfgaxisQvecF", {300, -1, 1}, ""}; + ConfigurableAxis cfgaxisQvec{"cfgaxisQvec", {100, -3, 3}, ""}; + ConfigurableAxis cfgaxisCent{"cfgaxisCent", {100, 0, 100}, ""}; + + ConfigurableAxis cfgaxiscos{"cfgaxiscos", {102, -1.02, 1.02}, ""}; + ConfigurableAxis cfgaxispt{"cfgaxispt", {100, 0, 10}, ""}; + ConfigurableAxis cfgaxisCentMerged{"cfgaxisCentMerged", {20, 0, 100}, ""}; + + ConfigurableAxis cfgrigidityBins{"cfgrigidityBins", {200, -10.f, 10.f}, "Binning for rigidity #it{p}^{TPC}/#it{z}"}; + ConfigurableAxis cfgdedxBins{"cfgdedxBins", {1000, 0.f, 1000.f}, "Binning for dE/dx"}; + ConfigurableAxis cfgnSigmaBins{"cfgnSigmaBins", {200, -5.f, 5.f}, "Binning for n sigma"}; + + ConfigurableAxis cfgaxissumpt{"cfgaxissumpt", {7, 1, 8}, "Binning for #gamma and #delta pt(particle1 + particle2)"}; + ConfigurableAxis cfgaxisdeltaeta{"cfgaxisdeltaeta", {5, 0, 1}, "Binning for #gamma and #delta |#eta(particle1 - particle2)|"}; + + Configurable onlyTOF{"onlyTOF", false, "only TOF tracks"}; + Configurable onlyTOFHIT{"onlyTOFHIT", false, "accept only TOF hit tracks at high pt"}; + Configurable OpenCME = {"cfgkOpeanCME", false, "open PID CME"}; + bool onlyTPC = true; + + EventPlaneHelper helperEP; + + int DetId; + int RefAId; + int RefBId; + + template + int GetDetId(const T& name) + { + if (name.value == "BPos" || name.value == "BNeg" || name.value == "BTot") { + LOGF(warning, "Using deprecated label: %s. Please use TPCpos, TPCneg, TPCall instead.", name.value); + } + if (name.value == "FT0C") { + return 0; + } else if (name.value == "FT0A") { + return 1; + } else if (name.value == "FT0M") { + return 2; + } else if (name.value == "FV0A") { + return 3; + } else if (name.value == "TPCpos" || name.value == "BPos") { + return 4; + } else if (name.value == "TPCneg" || name.value == "BNeg") { + return 5; + } else if (name.value == "TPCall" || name.value == "BTot") { + return 6; + } else { + return 0; + } + } + + void init(InitContext const&) + { + + DetId = GetDetId(cfgDetName); + RefAId = GetDetId(cfgRefAName); + RefBId = GetDetId(cfgRefBName); + + if (DetId == RefAId || DetId == RefBId || RefAId == RefBId) { + LOGF(info, "Wrong detector configuration \n The FT0C will be used to get Q-Vector \n The TPCpos and TPCneg will be used as reference systems"); + DetId = 0; + RefAId = 4; + RefBId = 5; + } + + AxisSpec axisCent{cfgaxisCent, "centrality"}; + AxisSpec axisQvec{cfgaxisQvec, "Q"}; + AxisSpec axisQvecF{cfgaxisQvecF, "Q"}; + AxisSpec axisEvtPl = {100, -1.0 * constants::math::PI, constants::math::PI}; + + AxisSpec axisCos{cfgaxiscos, "angle function"}; + AxisSpec axisPt{cfgaxispt, "trasverse momentum"}; + AxisSpec axisCentMerged{cfgaxisCentMerged, "merged centrality"}; + + AxisSpec axisRigidity{cfgrigidityBins, "#it{p}^{TPC}/#it{z}"}; + AxisSpec axisdEdx{cfgdedxBins, "d#it{E}/d#it{x}"}; + AxisSpec axisnSigma{cfgnSigmaBins, "n_{#sigma}({}^{3}He)"}; + + AxisSpec axissumpt{cfgaxissumpt, "#it{p}_{T}^{sum}}"}; + AxisSpec axisdeltaeta{cfgaxisdeltaeta, "#Delta#eta"}; + AxisSpec axisvertexz = {100, -15., 15., "vrtx_{Z} [cm]"}; + + histosQA.add(Form("QA/histEventCount"), "", {HistType::kTH1F, {{2, 0.0, 2.0}}}); + histosQA.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(1, "Not selected events"); + histosQA.get(HIST("QA/histEventCount"))->GetXaxis()->SetBinLabel(2, "Selected events"); + histosQA.add(Form("QA/histVertexZRec"), "", {HistType::kTH1F, {axisvertexz}}); + histosQA.add(Form("QA/histCentrality"), "", {HistType::kTH1F, {axisCent}}); + histosQA.add(Form("QA/histQvec_CorrL0_V2"), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); + histosQA.add(Form("QA/histQvec_CorrL1_V2"), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); + histosQA.add(Form("QA/histQvec_CorrL2_V2"), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); + histosQA.add(Form("QA/histQvec_CorrL3_V2"), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); + histosQA.add(Form("QA/histEvtPl_CorrL0_V2"), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("QA/histEvtPl_CorrL1_V2"), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("QA/histEvtPl_CorrL2_V2"), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("QA/histEvtPl_CorrL3_V2"), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); + histosQA.add(Form("QA/histQvecRes_SigRefAV2"), "", {HistType::kTH2F, {axisQvecF, axisCent}}); + histosQA.add(Form("QA/histQvecRes_SigRefBV2"), "", {HistType::kTH2F, {axisQvecF, axisCent}}); + histosQA.add(Form("QA/histQvecRes_RefARefBV2"), "", {HistType::kTH2F, {axisQvecF, axisCent}}); + + histosQA.add(Form("QA/PID/histdEdxTPC_All"), "", {HistType::kTH2F, {axisRigidity, axisdEdx}}); + histosQA.add(Form("QA/PID/histdEdxTPC_Pi"), "", {HistType::kTH2F, {axisRigidity, axisdEdx}}); + histosQA.add(Form("QA/PID/histnSigma_Pi"), "", {HistType::kTH1F, {axisnSigma}}); + histosQA.add(Form("QA/PID/histdEdxTPC_Ka"), "", {HistType::kTH2F, {axisRigidity, axisdEdx}}); + histosQA.add(Form("QA/PID/histnSigma_Ka"), "", {HistType::kTH1F, {axisnSigma}}); + histosQA.add(Form("QA/PID/histdEdxTPC_Pr"), "", {HistType::kTH2F, {axisRigidity, axisdEdx}}); + histosQA.add(Form("QA/PID/histnSigma_Pr"), "", {HistType::kTH1F, {axisnSigma}}); + + histosQA.add(Form("V2/histCosDetV2"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + histosQA.add(Form("V2/histSinDetV2"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + + histosQA.add(Form("V2/PID/histCosDetV2_Pi"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + histosQA.add(Form("V2/PID/histCosDetV2_Ka"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + histosQA.add(Form("V2/PID/histCosDetV2_Pr"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + histosQA.add(Form("V2/PID/histCosDetV2_Pi_Neg"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + histosQA.add(Form("V2/PID/histCosDetV2_Ka_Neg"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + histosQA.add(Form("V2/PID/histCosDetV2_Pr_Neg"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); + + if (OpenCME) { + histosQA.add(Form("PIDCME/histgamama_PiKa_ss"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histgamama_PiKa_os"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histgamama_PiPr_ss"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histgamama_PiPr_os"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histgamama_KaPr_ss"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histgamama_KaPr_os"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + + histosQA.add(Form("PIDCME/histdelta_PiKa_ss"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histdelta_PiKa_os"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histdelta_PiPr_ss"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histdelta_PiPr_os"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histdelta_KaPr_ss"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + histosQA.add(Form("PIDCME/histdelta_KaPr_os"), "", {HistType::kTProfile3D, {axisCentMerged, axissumpt, axisdeltaeta}}); + } + } + + template + bool SelEvent(const CollType& collision) + { + if (!collision.sel8()) { + return 0; + } + if (!collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return 0; + } + if (!collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return 0; + } + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return 0; + } + if (std::abs(collision.posZ()) > 10.) { + return 0; + } + + return 1; + } + + template + bool SelTrack(const TrackType track) + { + if (track.pt() < cfgMinPt) + return false; + if (std::abs(track.eta()) > cfgMaxEta) + return false; + if (!track.passedITSNCls()) + return false; + if (!track.passedITSChi2NDF()) + return false; + if (!track.passedITSHits()) + return false; + if (!track.passedTPCCrossedRowsOverNCls()) + return false; + if (!track.passedTPCChi2NDF()) + return false; + if (!track.passedDCAxy()) + return false; + if (!track.passedDCAz()) + return false; + + return true; + } + + template + bool selectionPID(const T& candidate, int PID) + { + if (candidate.pt() > 0.4) { + onlyTPC = false; + } + + if (PID == 0) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < cfgnSigmaCutTOFPi) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < cfgnSigmaCutTOFPi) { + return true; + } + if (!candidate.hasTOF() && + std::abs(candidate.tpcNSigmaPi()) < cfgnSigmaCutTPCPi) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPi()) < cfgnSigmaCutTPCPi) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (cfgnSigmaCutCombine * cfgnSigmaCutCombine)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < cfgnSigmaCutTPCPi) { + return true; + } + } + } else if (PID == 1) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < cfgnSigmaCutTOFKa) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < cfgnSigmaCutTOFKa) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < cfgnSigmaCutTPCPi) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaKa()) < cfgnSigmaCutTPCPi) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (cfgnSigmaCutCombine * cfgnSigmaCutCombine)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < cfgnSigmaCutTPCPi) { + return true; + } + } + } else if (PID == 2) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < cfgnSigmaCutTOFPr) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < cfgnSigmaCutTOFPr) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < cfgnSigmaCutTPCPr) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPr()) < cfgnSigmaCutTPCPr) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPr() * candidate.tofNSigmaPr() + candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr()) < (cfgnSigmaCutCombine * cfgnSigmaCutCombine)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < cfgnSigmaCutTPCPr) { + return true; + } + } + } + return false; + } + + template + void fillHistosQvec(const CollType& collision, int nmode) + { + int DetInd = DetId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + int RefAInd = RefAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + int RefBInd = RefBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + if (nmode == 2) { + if (collision.qvecAmp()[DetId] > 1e-8) { + histosQA.fill(HIST("QA/histQvec_CorrL0_V2"), collision.qvecRe()[DetInd], collision.qvecIm()[DetInd], collision.centFT0C()); + histosQA.fill(HIST("QA/histQvec_CorrL1_V2"), collision.qvecRe()[DetInd + 1], collision.qvecIm()[DetInd + 1], collision.centFT0C()); + histosQA.fill(HIST("QA/histQvec_CorrL2_V2"), collision.qvecRe()[DetInd + 2], collision.qvecIm()[DetInd + 2], collision.centFT0C()); + histosQA.fill(HIST("QA/histQvec_CorrL3_V2"), collision.qvecRe()[DetInd + 3], collision.qvecIm()[DetInd + 3], collision.centFT0C()); + histosQA.fill(HIST("QA/histEvtPl_CorrL0_V2"), helperEP.GetEventPlane(collision.qvecRe()[DetInd], collision.qvecIm()[DetInd], nmode), collision.centFT0C()); + histosQA.fill(HIST("QA/histEvtPl_CorrL1_V2"), helperEP.GetEventPlane(collision.qvecRe()[DetInd + 1], collision.qvecIm()[DetInd + 1], nmode), collision.centFT0C()); + histosQA.fill(HIST("QA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[DetInd + 2], collision.qvecIm()[DetInd + 2], nmode), collision.centFT0C()); + histosQA.fill(HIST("QA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[DetInd + 3], collision.qvecIm()[DetInd + 3], nmode), collision.centFT0C()); + } + if (collision.qvecAmp()[DetId] > 1e-8 && collision.qvecAmp()[RefAId] > 1e-8 && collision.qvecAmp()[RefBId] > 1e-8) { + histosQA.fill(HIST("QA/histQvecRes_SigRefAV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[DetInd + 3], collision.qvecIm()[DetInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[RefAInd + 3], collision.qvecIm()[RefAInd + 3], nmode), nmode), collision.centFT0C()); + histosQA.fill(HIST("QA/histQvecRes_SigRefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[DetInd + 3], collision.qvecIm()[DetInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[RefBInd + 3], collision.qvecIm()[RefBInd + 3], nmode), nmode), collision.centFT0C()); + histosQA.fill(HIST("QA/histQvecRes_RefARefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[RefAInd + 3], collision.qvecIm()[RefAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[RefBInd + 3], collision.qvecIm()[RefBInd + 3], nmode), nmode), collision.centFT0C()); + } + } + } + + template + void fillHistosFlow_gamma_delta(const CollType& collision, const TrackType& track, int nmode) + { + if (collision.qvecAmp()[DetId] < 1e-8) { + return; + } + int DetInd = DetId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + bool kisPi = false, kisKa = false, kisPr = false; + bool kisPi_2 = false, kisKa_2 = false, kisPr_2 = false; + float Psi_n = helperEP.GetEventPlane(collision.qvecRe()[DetInd + 3], collision.qvecIm()[DetInd + 3], nmode); + for (auto& trk : track) { + histosQA.fill(HIST("QA/PID/histdEdxTPC_All"), trk.sign() * trk.tpcInnerParam(), trk.tpcSignal()); + if (!SelTrack(trk)) { + continue; + } + kisPi = selectionPID(trk, 0); + kisKa = selectionPID(trk, 1); + kisPr = selectionPID(trk, 2); + if (kisPi) { + histosQA.fill(HIST("QA/PID/histdEdxTPC_Pi"), trk.sign() * trk.tpcInnerParam(), trk.tpcSignal()); + histosQA.fill(HIST("QA/PID/histnSigma_Pi"), trk.tpcNSigmaPi()); + } + if (kisKa) { + histosQA.fill(HIST("QA/PID/histdEdxTPC_Ka"), trk.sign() * trk.tpcInnerParam(), trk.tpcSignal()); + histosQA.fill(HIST("QA/PID/histnSigma_Ka"), trk.tpcNSigmaKa()); + } + if (kisPr) { + histosQA.fill(HIST("QA/PID/histdEdxTPC_Pr"), trk.sign() * trk.tpcInnerParam(), trk.tpcSignal()); + histosQA.fill(HIST("QA/PID/histnSigma_Pr"), trk.tpcNSigmaPr()); + } + if (nmode == 2) { + histosQA.fill(HIST("V2/histSinDetV2"), collision.centFT0C(), trk.pt(), + std::sin(static_cast(nmode) * (trk.phi() - Psi_n))); + histosQA.fill(HIST("V2/histCosDetV2"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + if (kisPi) { + if (trk.sign() > 0) { + histosQA.fill(HIST("V2/PID/histCosDetV2_Pi"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + } else if (trk.sign() < 0) { + histosQA.fill(HIST("V2/PID/histCosDetV2_Pi_Neg"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + } + } + if (kisKa) { + if (trk.sign() > 0) { + histosQA.fill(HIST("V2/PID/histCosDetV2_Ka"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + } else if (trk.sign() < 0) { + histosQA.fill(HIST("V2/PID/histCosDetV2_Ka_Neg"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + } + } + if (kisPr) { + if (trk.sign() > 0) { + histosQA.fill(HIST("V2/PID/histCosDetV2_Pr"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + } else if (trk.sign() < 0) { + histosQA.fill(HIST("V2/PID/histCosDetV2_Pr_Neg"), collision.centFT0C(), trk.pt(), + std::cos(static_cast(nmode) * (trk.phi() - Psi_n))); + } + } + } + if (OpenCME) { + for (auto& trk_2 : track) { + if (trk_2.globalIndex() == trk.globalIndex()) + continue; + if (nmode == 2) { + kisPi_2 = selectionPID(trk_2, 0); + kisKa_2 = selectionPID(trk_2, 1); + kisPr_2 = selectionPID(trk_2, 2); + if (kisPi && kisKa_2) { + if (trk.sign() == trk_2.sign()) { + histosQA.fill(HIST("PIDCME/histgamama_PiKa_ss"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() + trk_2.phi() - static_cast(nmode) * Psi_n))); + histosQA.fill(HIST("PIDCME/histdelta_PiKa_ss"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() - trk_2.phi()))); + } else { + histosQA.fill(HIST("PIDCME/histgamama_PiKa_os"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() + trk_2.phi() - static_cast(nmode) * Psi_n))); + histosQA.fill(HIST("PIDCME/histdelta_PiKa_os"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() - trk_2.phi()))); + } + } + if (kisPi && kisPr_2) { + if (trk.sign() == trk_2.sign()) { + histosQA.fill(HIST("PIDCME/histgamama_PiPr_ss"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() + trk_2.phi() - static_cast(nmode) * Psi_n))); + histosQA.fill(HIST("PIDCME/histdelta_PiPr_ss"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() - trk_2.phi()))); + } else { + histosQA.fill(HIST("PIDCME/histgamama_PiPr_os"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() + trk_2.phi() - static_cast(nmode) * Psi_n))); + histosQA.fill(HIST("PIDCME/histdelta_PiPr_os"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() - trk_2.phi()))); + } + } + if (kisKa && kisPr_2) { + if (trk.sign() == trk_2.sign()) { + histosQA.fill(HIST("PIDCME/histgamama_KaPr_ss"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() + trk_2.phi() - static_cast(nmode) * Psi_n))); + histosQA.fill(HIST("PIDCME/histdelta_KaPr_ss"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() - trk_2.phi()))); + } else { + histosQA.fill(HIST("PIDCME/histgamama_KaPr_os"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() + trk_2.phi() - static_cast(nmode) * Psi_n))); + histosQA.fill(HIST("PIDCME/histdelta_KaPr_os"), collision.centFT0C(), trk.pt() + trk_2.pt(), std::abs(trk.eta() - trk_2.eta()), + std::cos((trk.phi() - trk_2.phi()))); + } + } + } + } + } + } + } + + void process(MyCollisions::iterator const& collision, MyTracks const& tracks) + { + histosQA.fill(HIST("QA/histEventCount"), 0.5); + if (!SelEvent(collision)) { + return; + } + histosQA.fill(HIST("QA/histEventCount"), 1.5); + histosQA.fill(HIST("QA/histCentrality"), collision.centFT0C()); + histosQA.fill(HIST("QA/histVertexZRec"), collision.posZ()); + for (auto i = 0; i < static_cast(cfgnMods->size()); i++) { + fillHistosQvec(collision, cfgnMods->at(i)); + fillHistosFlow_gamma_delta(collision, tracks, cfgnMods->at(i)); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx b/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx index fb6355c55b2..fee15c95f97 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx +++ b/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.cxx @@ -12,6 +12,8 @@ #include #include +#include +#include #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" @@ -935,11 +937,9 @@ struct IdentifiedBfFilterTracks { template inline MatchRecoGenSpecies IdentifyTrack(TrackObject const& track); template - MatchRecoGenSpecies trackIdentification(TrackObject const& track); - template int8_t AcceptTrack(TrackObject const& track); template - int8_t AcceptParticle(ParticleObject& particle, MCCollisionObject const&); + int8_t AcceptParticle(ParticleObject& particle, MCCollisionObject const& mccollision); template int8_t selectTrackAmbiguousCheck(CollisionObjects const& collisions, TrackObject const& track); template @@ -1020,7 +1020,6 @@ struct IdentifiedBfFilterTracks { void filterParticles(soa::Join const& gencollisions, aod::McParticles const& particles) { using namespace identifiedbffilter; - int acceptedparticles = 0; int acceptedcollisions = 0; if (!fullDerivedData) { @@ -1049,38 +1048,9 @@ struct IdentifiedBfFilterTracks { fillParticleHistosBeforeSelection(particle, mccollision, charge); /* track selection */ - /* TODO: at some point the pid has to be substituted by the identified species */ pid = AcceptParticle(particle, mccollision); - if (!(pid < 0)) { - /* the particle has been accepted */ - /* let's identify the particle */ - /* TODO: probably this needs to go to AcceptParticle */ - MatchRecoGenSpecies sp = IdentifyParticle(particle); - if (sp != kWrongSpecies) { - if (sp != kIdBfCharged) { - /* fill the charged particle histograms */ - fillParticleHistosAfterSelection(particle, mccollision, charge, kIdBfCharged); - /* update charged multiplicities */ - if (pid % 2 == 0) { - partMultPos[kIdBfCharged]++; - } - if (pid % 2 == 1) { - partMultNeg[kIdBfCharged]++; - } - } - /* fill the species histograms */ - fillParticleHistosAfterSelection(particle, mccollision, charge, sp); - /* update species multiplicities */ - if (pid % 2 == 0) { - partMultPos[sp]++; - } - if (pid % 2 == 1) { - partMultNeg[sp]++; - } - acceptedparticles++; - } else { - pid = -1; - } + if (!(pid < 0)) { // if PID isn't negative + acceptedparticles++; } } } else { @@ -1161,7 +1131,7 @@ struct IdentifiedBfFilterTracks { } PROCESS_SWITCH(IdentifiedBfFilterTracks, filterRecoWithoutPIDAmbiguous, "Track filtering without PID information with ambiguous tracks check", false) - void filterDetectorLevelWithoutPID(soa::Join const& collisions, IdBfFullTracksDetLevel const& tracks) + void filterDetectorLevelWithoutPID(soa::Join const& collisions, IdBfFullTracksDetLevel const& tracks, aod::McParticles const&) { filterTracks(collisions, tracks); } @@ -1358,30 +1328,6 @@ inline MatchRecoGenSpecies IdentifiedBfFilterTracks::IdentifyTrack(TrackObject c } } -template -MatchRecoGenSpecies IdentifiedBfFilterTracks::trackIdentification(TrackObject const& track) -{ - using namespace identifiedbffilter; - MatchRecoGenSpecies sp = kWrongSpecies; - if (recoIdMethod == 0) { - sp = kIdBfCharged; - } else if (recoIdMethod == 1) { - - if constexpr (framework::has_type_v || framework::has_type_v) { - sp = IdentifyTrack(track); - } else { - LOGF(fatal, "Track identification required but PID information not present"); - } - } else if (recoIdMethod == 2) { - if constexpr (framework::has_type_v) { - sp = IdentifyParticle(track.template mcParticle_as()); - } else { - LOGF(fatal, "Track identification required from MC particle but MC information not present"); - } - } - return sp; -} - /// \brief Accepts or not the passed track /// \param track the track of interest /// \return the internal track id, -1 if not accepted @@ -1404,17 +1350,33 @@ inline int8_t IdentifiedBfFilterTracks::AcceptTrack(TrackObject const& track) if (matchTrackType(track)) { if (ptlow < track.pt() && track.pt() < ptup && etalow < track.eta() && track.eta() < etaup) { fillTrackHistosAfterSelection(track, kIdBfCharged); - MatchRecoGenSpecies sp = trackIdentification(track); + MatchRecoGenSpecies sp = kWrongSpecies; + if (recoIdMethod == 0) { + sp = kIdBfCharged; + } else if (recoIdMethod == 1) { + + if constexpr (framework::has_type_v || framework::has_type_v) { + sp = IdentifyTrack(track); + } else { + LOGF(fatal, "Track identification required but PID information not present"); + } + } else if (recoIdMethod == 2) { + if constexpr (framework::has_type_v) { + sp = IdentifyParticle(track.template mcParticle_as()); + } else { + LOGF(fatal, "Track identification required from MC particle but MC information not present"); + } + } if (sp == kWrongSpecies) { return -1; } if (!(sp < 0)) { fillTrackHistosAfterSelection(track, sp); // 0) { + if (track.sign() > 0) { // if positive trkMultPos[sp]++; //<< Update Particle Multiplicity return speciesChargeValue1[sp]; } - if (track.sign() < 0) { + if (track.sign() < 0) { // if negative trkMultNeg[sp]++; //<< Update Particle Multiplicity return speciesChargeValue1[sp] + 1; } @@ -1428,7 +1390,7 @@ inline int8_t IdentifiedBfFilterTracks::AcceptTrack(TrackObject const& track) /// \param track the particle of interest /// \return `true` if the particle is accepted, `false` otherwise template -inline int8_t IdentifiedBfFilterTracks::AcceptParticle(ParticleObject& particle, MCCollisionObject const&) +inline int8_t IdentifiedBfFilterTracks::AcceptParticle(ParticleObject& particle, MCCollisionObject const& mccollision) { /* overall momentum cut */ if (!(overallminp < particle.p())) { @@ -1444,6 +1406,26 @@ inline int8_t IdentifiedBfFilterTracks::AcceptParticle(ParticleObject& particle, if (ptlow < particle.pt() && particle.pt() < ptup && etalow < particle.eta() && particle.eta() < etaup) { MatchRecoGenSpecies sp = IdentifyParticle(particle); + if (sp != kWrongSpecies) { + if (sp != kIdBfCharged) { + /* fill the charged particle histograms */ + fillParticleHistosAfterSelection(particle, mccollision, charge, kIdBfCharged); + /* update charged multiplicities */ + if (charge == 1) { + partMultPos[kIdBfCharged]++; + } else if (charge == -1) { + partMultNeg[kIdBfCharged]++; + } + } + /* fill the species histograms */ + fillParticleHistosAfterSelection(particle, mccollision, charge, sp); + /* update species multiplicities */ + if (charge == 1) { + partMultPos[sp]++; + } else if (charge == -1) { + partMultNeg[sp]++; + } + } if (charge == 1) { return speciesChargeValue1[sp]; diff --git a/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.h b/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.h index 392bcd73afe..6897cac98b4 100644 --- a/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.h +++ b/PWGCF/TwoParticleCorrelations/TableProducer/identifiedBfFilter.h @@ -34,8 +34,8 @@ namespace aod { using CollisionsEvSelCent = soa::Join; using CollisionEvSelCent = soa::Join::iterator; -using CollisionsEvSelRun2Cent = soa::Join; -using CollisionEvSelRun2Cent = soa::Join::iterator; +using CollisionsEvSelRun2Cent = soa::Join; +using CollisionEvSelRun2Cent = soa::Join::iterator; using CollisionsEvSel = soa::Join; using CollisionEvSel = soa::Join::iterator; using TrackData = soa::Join::iterator; @@ -523,38 +523,60 @@ inline float extractMultiplicity(CollisionObject const& collision, CentMultEstim ////////////////////////////////////////////////////////////////////////////////// /// \brief Centrality/multiplicity percentile template - requires(o2::aod::HasRun2Centrality) float getCentMultPercentile(CollisionObject collision) { - switch (fCentMultEstimator) { - case kV0M: - return collision.centRun2V0M(); - case kCL0: - return collision.centRun2CL0(); - case kCL1: - return collision.centRun2CL1(); - default: - return 105.0; - } -} + if constexpr (framework::has_type_v || + framework::has_type_v || + framework::has_type_v) { + switch (fCentMultEstimator) { + case kV0M: + return collision.centRun2V0M(); + break; + case kCL0: + if constexpr (framework::has_type_v) { + return collision.centRun2CL0(); + } else { + return 105.0; + } + break; -template - requires(o2::aod::HasCentrality) -float getCentMultPercentile(CollisionObject collision) -{ - switch (fCentMultEstimator) { - case kFV0A: - return collision.centFV0A(); - case kFT0M: - return collision.centFT0M(); - case kFT0A: - return collision.centFT0A(); - case kFT0C: - return collision.centFT0C(); - case kNTPV: - return collision.centNTPV(); - default: - return 105.0; + case kCL1: + if constexpr (framework::has_type_v) { + return collision.centRun2CL1(); + } else { + return 105.0; + } + break; + default: + return 105.0; + break; + } + } + if constexpr (framework::has_type_v || + framework::has_type_v || + framework::has_type_v || + framework::has_type_v || + framework::has_type_v) { + switch (fCentMultEstimator) { + case kFV0A: + return collision.centFV0A(); + break; + case kFT0M: + return collision.centFT0M(); + break; + case kFT0A: + return collision.centFT0A(); + break; + case kFT0C: + return collision.centFT0C(); + break; + case kNTPV: + return collision.centNTPV(); + break; + default: + return 105.0; + break; + } } } diff --git a/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx b/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx index d7187c49f0c..e6c13fe1318 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx @@ -9,6 +9,8 @@ // 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 "Common/DataModel/EventSelection.h" @@ -49,12 +51,12 @@ struct FillFlagsTable { auto tpcnsigma = (std::vector>){TPCnsigmacutsPi, TPCnsigmacutsKa, TPCnsigmacutsPr}; auto tofpt = (std::vector>){TOFpTrangesPi, TOFpTrangesKa, TOFpTrangesPr}; auto tofnsigma = (std::vector>){TOFnsigmacutsPi, TOFnsigmacutsKa, TOFnsigmacutsPr}; - for (int8_t i = 0; i < tpcpt[species].size(); i++) + for (std::size_t i = 0; i < tpcpt[species].size(); i++) if (trackpt < tpcpt[species][i]) { tpcindex = i; break; } - for (int8_t i = 0; i < tofpt[species].size(); i++) + for (std::size_t i = 0; i < tofpt[species].size(); i++) if (trackpt >= tofpt[species][i]) { tofindex = i; break; @@ -258,8 +260,8 @@ struct r2p24id { Configurable maxpT{"maxpT", 2.0, "Maximum pT"}; Configurable trackpartition{"trackpartition", 1.0, "where(in pT) to partition"}; - Configurable pid_particle1{"pid_particle1", 1, "Define particle1 type"}; // 1->Pion, 2->Kaon, 3->Proton - Configurable pid_particle2{"pid_particle2", 1, "Define particle2 type"}; + Configurable pid_particle1{"pid_particle1", 1, "Define particle1 type"}; // 1->Pion, 2->Kaon, 3->Proton + Configurable pid_particle2{"pid_particle2", 1, "Define particle2 type"}; Configurable iftrackpartition{"iftrackpartition", false, "If track partition is needed"}; Configurable ifpid{"ifpid", false, "If PID is needed"}; diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 283820693cf..8fc8f9fccd5 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -145,6 +145,15 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) cut->AddCut(GetAnalysisCut("electronPIDnsigmaMedium")); return cut; } + + if (!nameStr.compare("electronSelection1_idstoreh")) { // same as electronSelection1_ionut, but with kIsSPDAny -> kIsITSibAny + cut->AddCut(GetAnalysisCut("jpsiStandardKine")); + cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); + cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); + cut->AddCut(GetAnalysisCut("electronPIDnsigmaMedium")); + return cut; + } + if (!nameStr.compare("electronSelection1pos_ionut")) { cut->AddCut(GetAnalysisCut("posTrack")); cut->AddCut(GetAnalysisCut("jpsiStandardKine")); @@ -625,6 +634,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("kaonPID3_withDCA")) { // same as kaonPID3 but with cut on DCA and SPDAny->ITSAny + cut->AddCut(GetAnalysisCut("AssocKine")); // standard kine cuts usually are applied via Filter in the task + cut->AddCut(GetAnalysisCut("electronStandardQualityForO2MCdebug4")); + cut->AddCut(GetAnalysisCut("dcaCut1_ionut")); + cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); + return cut; + } + if (!nameStr.compare("kaonPID4")) { cut->AddCut(GetAnalysisCut("kaonPID_TPCnTOF")); return cut; @@ -2593,14 +2610,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - if (!nameStr.compare("muonQualityCuts3SigmaPDCA")) { - cut->AddCut(GetAnalysisCut("muonQualityCuts3SigmaPDCA")); + if (!nameStr.compare("muonQualityCuts5SigmaPDCA_Run3")) { + cut->AddCut(GetAnalysisCut("muonQualityCuts5SigmaPDCA_Run3")); return cut; } - if (!nameStr.compare("muonLowPt3SigmaPDCA")) { + if (!nameStr.compare("muonLowPt5SigmaPDCA_Run3")) { cut->AddCut(GetAnalysisCut("muonLowPt")); - cut->AddCut(GetAnalysisCut("muonQualityCuts3SigmaPDCA")); + cut->AddCut(GetAnalysisCut("muonQualityCuts5SigmaPDCA_Run3")); cut->AddCut(GetAnalysisCut("MCHMID")); return cut; } @@ -3385,6 +3402,34 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("eventStandardSel8PbPbQualityTightTrackOccupancyCollInTime")) { + cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); + cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoITSROFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); + cut->AddCut(VarManager::kIsGoodZvtxFT0vsPV, 0.5, 1.5); + cut->AddCut(VarManager::kCentFT0C, 0.0, 90.0); + cut->AddCut(VarManager::kTrackOccupancyInTimeRange, 0., 500); + cut->AddCut(VarManager::kNoCollInTimeRangeStandard, 0.5, 1.5); + + return cut; + } + + if (!nameStr.compare("eventStandardSel8PbPbQualityTightTrackOccupancyCollInTime")) { + cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); + cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoITSROFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); + cut->AddCut(VarManager::kIsGoodZvtxFT0vsPV, 0.5, 1.5); + cut->AddCut(VarManager::kCentFT0C, 0.0, 90.0); + cut->AddCut(VarManager::kTrackOccupancyInTimeRange, 0., 1000); + cut->AddCut(VarManager::kNoCollInTimeRangeStandard, 0.5, 1.5); + + return cut; + } + std::vector vecOccupancies = {0., 250., 500., @@ -5325,11 +5370,11 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("muonQualityCuts3SigmaPDCA")) { + if (!nameStr.compare("muonQualityCuts5SigmaPDCA_Run3")) { cut->AddCut(VarManager::kEta, -4.0, -2.5); cut->AddCut(VarManager::kMuonRAtAbsorberEnd, 17.6, 89.5); - cut->AddCut(VarManager::kMuonPDca, 0.0, 300.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); - cut->AddCut(VarManager::kMuonPDca, 0.0, 201.0, false, VarManager::kMuonRAtAbsorberEnd, 26.5, 89.5); + cut->AddCut(VarManager::kMuonPDca, 0.0, 500.0, false, VarManager::kMuonRAtAbsorberEnd, 17.6, 26.5); + cut->AddCut(VarManager::kMuonPDca, 0.0, 335.0, false, VarManager::kMuonRAtAbsorberEnd, 26.5, 89.5); cut->AddCut(VarManager::kMuonChi2, 0.0, 1e6); cut->AddCut(VarManager::kMuonChi2MatchMCHMID, 0.0, 1e6); // matching MCH-MID return cut; diff --git a/PWGDQ/Core/HistogramManager.cxx b/PWGDQ/Core/HistogramManager.cxx index f9ba930a0ec..19956da4496 100644 --- a/PWGDQ/Core/HistogramManager.cxx +++ b/PWGDQ/Core/HistogramManager.cxx @@ -179,7 +179,7 @@ void HistogramManager::AddHistogram(const char* histClass, const char* hname, co varVector.push_back(varX); // variables on each axis varVector.push_back(varY); varVector.push_back(varZ); - varVector.push_back(varT); // variable used for profiling in case of TProfile3D + varVector.push_back(varT); // variable used for profiling in case of TProfile3D varVector.push_back(isFillLabelx ? 1 : 0); // whether to fill with the x-axis labels std::list varList = fVariablesMap[histClass]; varList.push_back(varVector); @@ -389,7 +389,7 @@ void HistogramManager::AddHistogram(const char* histClass, const char* hname, co varVector.push_back(varX); // variables on each axis varVector.push_back(varY); varVector.push_back(varZ); - varVector.push_back(varT); // variable used for profiling in case of TProfile3D + varVector.push_back(varT); // variable used for profiling in case of TProfile3D varVector.push_back(isFillLabelx ? 1 : 0); // whether to fill with the x-axis labels std::list varList = fVariablesMap[histClass]; varList.push_back(varVector); @@ -795,9 +795,9 @@ void HistogramManager::FillHistClass(const char* className, Float_t* values) if (isProfile) { if (varW > kNothing) { if (isFillLabelx) { - (reinterpret_cast(h))->Fill(Form("%d", static_cast(values[varX])), values[varW]); + (reinterpret_cast(h))->Fill(Form("%d", static_cast(values[varX])), values[varY], values[varW]); } else { - (reinterpret_cast(h))->Fill(values[varX], values[varW]); + (reinterpret_cast(h))->Fill(values[varX], values[varY], values[varW]); } } else { if (isFillLabelx) { @@ -880,7 +880,7 @@ void HistogramManager::FillHistClass(const char* className, Float_t* values) } } } // end else - } // end loop over histograms + } // end loop over histograms } //____________________________________________________________________________________ diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index e23ef4549d8..bad53e0fd1b 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -93,6 +93,16 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MultTPC_MultFT0A", "MultTPC vs MultFT0A", false, 100, 0, 500.0, VarManager::kMultTPC, 100, 0, 200.0, VarManager::kMultFT0A); hm->AddHistogram(histClass, "MultTPC_MultFT0C", "MultTPC vs MultFT0C", false, 100, 0, 500.0, VarManager::kMultTPC, 100, 0, 300.0, VarManager::kMultFT0C); hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 200.0, VarManager::kMultFT0A, 100, 0, 300.0, VarManager::kMultFT0C); + hm->AddHistogram(histClass, "MultITSWithPV", "MultITSWithPV", false, 150, 0.0, 150.0, VarManager::kMultNTracksHasITS); + hm->AddHistogram(histClass, "MultTPCWithPV", "MultTPCWithPV", false, 150, 0.0, 150.0, VarManager::kMultNTracksHasTPC); + hm->AddHistogram(histClass, "MultITSTPCWithPV", "MultITSTPCWithPV", false, 150, 0.0, 150.0, VarManager::kMultNTracksITSTPC); + hm->AddHistogram(histClass, "MultITSOnly", "MultITSOnly", false, 150, 0.0, 150.0, VarManager::kMultNTracksITSOnly); + hm->AddHistogram(histClass, "MultITSWithPV_MultTPCWithPV", "MultITSWithPV_MultTPCWithPV", false, 150, 0.0, 150.0, VarManager::kMultNTracksHasITS, 150, 0.0, 150.0, VarManager::kMultNTracksHasTPC); + hm->AddHistogram(histClass, "MultITSWithPV_MultITSTPCWithPV", "MultITSWithPV_MultTPCWithPV", false, 150, 0.0, 150.0, VarManager::kMultNTracksHasITS, 150, 0.0, 150.0, VarManager::kMultNTracksITSTPC); + hm->AddHistogram(histClass, "MultITSWithPV_MultFT0C", "MultITSWithPV_MultFT0C", false, 150, 0.0, 150.0, VarManager::kMultNTracksHasITS, 250, 0.0, 2500.0, VarManager::kMultFT0C); + hm->AddHistogram(histClass, "MultITSWithPV_MultFT0A", "MultITSWithPV_MultFT0A", false, 150, 0.0, 150.0, VarManager::kMultNTracksHasITS, 250, 0.0, 2500.0, VarManager::kMultFT0A); + hm->AddHistogram(histClass, "MultITSTPCWithPV_MultFT0C", "MultITSTPCWithPV_MultFT0C", false, 150, 0.0, 150.0, VarManager::kMultNTracksITSTPC, 250, 0.0, 2500.0, VarManager::kMultFT0C); + hm->AddHistogram(histClass, "MultITSTPCWithPV_MultFT0A", "MultITSTPCWithPV_MultFT0A", false, 150, 0.0, 150.0, VarManager::kMultNTracksITSTPC, 250, 0.0, 2500.0, VarManager::kMultFT0A); } else { hm->AddHistogram(histClass, "MultTPC", "MultTPC", false, 200, 0.0, 50000.0, VarManager::kMultTPC); hm->AddHistogram(histClass, "MultTPC_vsTimeSOR", "MultTPC vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, 0.0, 50000.0, VarManager::kMultTPC); @@ -228,13 +238,18 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Psi2A", "", false, 100, -2.0, 2.0, VarManager::kPsi2A); hm->AddHistogram(histClass, "Psi2B", "", false, 100, -2.0, 2.0, VarManager::kPsi2B); hm->AddHistogram(histClass, "Psi2C", "", false, 100, -2.0, 2.0, VarManager::kPsi2C); - hm->AddHistogram(histClass, "Psi2A_CentFT0C", "", false, 18, 0.0, 90.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2A); - hm->AddHistogram(histClass, "Psi2B_CentFT0C", "", false, 18, 0.0, 90.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2B); - hm->AddHistogram(histClass, "Psi2C_CentFT0C", "", false, 18, 0.0, 90.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2C); - hm->AddHistogram(histClass, "centrFT0C_Corr2REF_ev", "", true, 18, 0.0, 90.0, VarManager::kCentFT0C, 500, -1.0, 1.0, VarManager::kCORR2REF, VarManager::kM11REF); - hm->AddHistogram(histClass, "centrFT0C_Corr4REF_ev", "", true, 18, 0.0, 90.0, VarManager::kCentFT0C, 500, -1.0, 1.0, VarManager::kCORR4REF, VarManager::kM1111REF); - hm->AddHistogram(histClass, "Corr2REFerrors", "", 4, std::array{VarManager::kCentFT0C, VarManager::kCORR2REFw, VarManager::kCORR2REFsquaredw, VarManager::kM11REF}.data(), std::array{18, 200, 200, 200}.data(), std::array{0.0, -40000.0, -10.0, 0.0}.data(), std::array{90.0, 40000.0, 1000.0, 7000000.0}.data(), nullptr, -1, true, true); - hm->AddHistogram(histClass, "Corr4REFerrors", "", 4, std::array{VarManager::kCentFT0C, VarManager::kCORR4REFw, VarManager::kCORR4REFsquaredw, VarManager::kM1111REF}.data(), std::array{18, 200, 200, 200}.data(), std::array{0.0, -90000000.0, -1000.0, 0.0}.data(), std::array{90.0, 90000000.0, 40000.0, 9000000000000.0}.data(), nullptr, -1, true, true); + hm->AddHistogram(histClass, "Psi2A_CentFT0C", "", false, 90, 0.0, 90.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2A); + 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); + hm->AddHistogram(histClass, "centrFT0C_Corr2REF_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 250, -1.0, 1.0, VarManager::kCORR2REF, VarManager::kM11REF); + hm->AddHistogram(histClass, "centrFT0C_Corr2REFetagap_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 250, -1.0, 1.0, VarManager::kCORR2REFetagap, VarManager::kM11REFetagap); + hm->AddHistogram(histClass, "centrFT0C_Corr4REF_ev", "", true, 100, 0.0, 100.0, VarManager::kCentFT0C, 250, -1.0, 1.0, VarManager::kCORR4REF, VarManager::kM1111REF); + hm->AddHistogram(histClass, "Run2_centrFT0C_Corr2REF_ev", "", true, 9, std::array{0.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0}.data(), VarManager::kCentFT0C, 250, std::array{-1.0, 1.0}.data(), VarManager::kCORR2REF, 0, nullptr, -1, "", "", "", VarManager::kCORR2REF, VarManager::kM11REF); + hm->AddHistogram(histClass, "Run2_centrFT0C_Corr2REFetagap_ev", "", true, 9, std::array{0.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0}.data(), VarManager::kCentFT0C, 250, std::array{-1.0, 1.0}.data(), VarManager::kCORR2REFetagap, 0, nullptr, -1, "", "", "", VarManager::kCORR2REFetagap, VarManager::kM11REFetagap); + hm->AddHistogram(histClass, "Run2_centrFT0C_Corr4REF_ev", "", true, 9, std::array{0.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0}.data(), VarManager::kCentFT0C, 250, std::array{-1.0, 1.0}.data(), VarManager::kCORR4REF, 0, nullptr, -1, "", "", "", VarManager::kCORR4REF, VarManager::kM1111REF); + hm->AddHistogram(histClass, "Corr2REFerrorsetagap", "", 4, std::array{VarManager::kCentFT0C, VarManager::kCORR2REFetagapw, VarManager::kCORR2REFetagapsquaredw, VarManager::kM11REFetagap}.data(), std::array{100, 5000, 5000, 5000}.data(), std::array{0.0, -5000.0, 0.0, 0.0}.data(), std::array{100.0, 5000.0, 100.0, 300000.0}.data(), nullptr, -1, true, true); + hm->AddHistogram(histClass, "Corr2REFerrors", "", 4, std::array{VarManager::kCentFT0C, VarManager::kCORR2REFw, VarManager::kCORR2REFsquaredw, VarManager::kM11REF}.data(), std::array{100, 10000, 10000, 10000}.data(), std::array{0.0, -40000.0, 0.0, 0.0}.data(), std::array{100.0, 40000.0, 100.0, 6000000.0}.data(), nullptr, -1, true, true); + hm->AddHistogram(histClass, "Corr4REFerrors", "", 4, std::array{VarManager::kCentFT0C, VarManager::kCORR4REFw, VarManager::kCORR4REFsquaredw, VarManager::kM1111REF}.data(), std::array{100, 100000, 100000, 100000}.data(), std::array{0.0, -30000000.0, 0.0, 0.0}.data(), std::array{100.0, 90000000.0, 40000.0, 9000000000000.0}.data(), nullptr, -1, true, true); if (subGroupStr.Contains("cross")) { hm->AddHistogram(histClass, "Q1ZNACXX_CentFT0C", "", false, 90, 0.0, 90.0, VarManager::kCentFT0C, 4000, -2, 2, VarManager::kQ1ZNACXX); hm->AddHistogram(histClass, "Q1ZNACYY_CentFT0C", "", false, 90, 0.0, 90.0, VarManager::kCentFT0C, 4000, -2, 2, VarManager::kQ1ZNACYY); @@ -720,8 +735,13 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MuonDcaX_vs_eta", "", false, 2000, -20.0, 20.0, VarManager::kMuonDCAx, 500, -5.0, 5.0, VarManager::kEta); hm->AddHistogram(histClass, "MuonDcaY_vs_eta", "", false, 2000, -20.0, 20.0, VarManager::kMuonDCAy, 500, -5.0, 5.0, VarManager::kEta); } else { + hm->AddHistogram(histClass, "Pt", "p_{T} distribution", false, 2000, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Eta", "#eta distribution", false, 500, -5.0, 5.0, VarManager::kEta); + hm->AddHistogram(histClass, "Phi", "#varphi distribution", false, 500, -2. * TMath::Pi(), 2. * TMath::Pi(), VarManager::kPhi); hm->AddHistogram(histClass, "AmbiguityInBunch", "", false, 10, 0.0, 10., VarManager::kMuonNAssocsInBunch); hm->AddHistogram(histClass, "AmbiguityOutOfBunch", "", false, 10, 0.0, 10., VarManager::kMuonNAssocsOutOfBunch); + hm->AddHistogram(histClass, "AmbiguityInBunch_pt", "in bunch collision ambiguity vs p_{T}", false, 50, 0.0, 10.0, VarManager::kPt, 10, 0., 10., VarManager::kMuonNAssocsInBunch); + hm->AddHistogram(histClass, "AmbiguityOutOfBunch_pt", "out of bunch collision ambiguity vs p_{T}", false, 50, 0.0, 10.0, VarManager::kPt, 10, 0., 10., VarManager::kMuonNAssocsOutOfBunch); } } @@ -730,8 +750,6 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "pdca_vs_p", "pDCA vs p", false, 2000, 0.0, 20.0, VarManager::kP, 200, 0.0, 1000., VarManager::kMuonPDca); hm->AddHistogram(histClass, "pdca_vs_pt", "pDCA vs pt", false, 2000, 0.0, 20.0, VarManager::kPt, 200, 0.0, 1000., VarManager::kMuonPDca); hm->AddHistogram(histClass, "pdca_vs_Rabs", "pDCA vs R_{abs}", false, 100, 0., 200., VarManager::kMuonRAtAbsorberEnd, 200, 0.0, 1000., VarManager::kMuonPDca); - hm->AddHistogram(histClass, "pdca_vs_Rabs_vs_p", "pDCA vs R_{abs} vs p", false, 2000, 0.0, 20.0, VarManager::kP, 100, 0., 200., VarManager::kMuonRAtAbsorberEnd, 200, 0.0, 1000., VarManager::kMuonPDca); - hm->AddHistogram(histClass, "pdca_vs_Rabs_vs_pt", "pDCA vs R_{abs} vs pt", false, 2000, 0.0, 20.0, VarManager::kPt, 100, 0., 200., VarManager::kMuonRAtAbsorberEnd, 200, 0.0, 1000., VarManager::kMuonPDca); } if (subGroupStr.Contains("mft-pid")) { hm->AddHistogram(histClass, "hMftTrackEtaVsPt", "", false, 100, -5.f, -2.f, VarManager::kEta, 100, 0.f, 20.f, VarManager::kPt); @@ -1065,23 +1083,41 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h double xmaxpT[5] = {5., 3., 100, 1., 4.0}; hm->AddHistogram(histClass, "Mass_Pt_Cent_cosThetaCS_Rap", "", 5, varsCSpbpb, binspT, xminpT, xmaxpT, 0, -1, kFALSE); } - if (subGroupStr.Contains("multiplicity-fvoa")) { + if (subGroupStr.Contains("dimuon-midmult-polarization-he")) { + int varsITSTPCMulHE[4] = {VarManager::kMass, VarManager::kMultNTracksITSTPC, VarManager::kCosThetaHE, VarManager::kPhiHE}; + int varsITSMulHE[4] = {VarManager::kMass, VarManager::kMultNTracksHasITS, VarManager::kCosThetaHE, VarManager::kPhiHE}; + int binsMul[4] = {100, 20, 20, 20}; + double xminMul[4] = {1., 0., -1., -3.14}; + double xmaxMul[4] = {5., 120., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_ITSTPCMult_cosThetaHE_phiHE", "", 4, varsITSTPCMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_ITSMult_cosThetaHE_phiHE", "", 4, varsITSMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + } + if (subGroupStr.Contains("dimuon-midmult-polarization-cs")) { + int varsITSTPCMulCS[4] = {VarManager::kMass, VarManager::kMultNTracksITSTPC, VarManager::kCosThetaCS, VarManager::kPhiCS}; + int varsITSMulCS[4] = {VarManager::kMass, VarManager::kMultNTracksHasITS, VarManager::kCosThetaCS, VarManager::kPhiCS}; + int binsMul[4] = {100, 20, 20, 20}; + double xminMul[4] = {1., 0., -1., -3.14}; + double xmaxMul[4] = {5., 120., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_ITSTPCMult_cosThetaCS_phiCS", "", 4, varsITSTPCMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_ITSMult_cosThetaCS_phiCS", "", 4, varsITSMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + } + if (subGroupStr.Contains("dimuon-fwdmult-polarization-he")) { + int varsFT0AMulHE[4] = {VarManager::kMass, VarManager::kMultFT0A, VarManager::kCosThetaHE, VarManager::kPhiHE}; int varsFV0AMulHE[4] = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int varsFV0AMulCS[4] = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; int binsMul[4] = {100, 20, 20, 20}; double xminMul[4] = {1., 0., -1., -3.14}; - double xmaxMul[4] = {5., 5000., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_MultFV0A_cosThetaHE_phiHE", "", 4, varsFV0AMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_MultFV0A_cosThetaCS_phiCS", "", 4, varsFV0AMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + double xmaxMul[4] = {5., 3000., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_FT0AMult_cosThetaHE_phiHE", "", 4, varsFT0AMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_FV0AMult_cosThetaHE_phiHE", "", 4, varsFV0AMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); } - if (subGroupStr.Contains("multiplicity-tpc")) { - int varsTPCMulHE[4] = {VarManager::kMass, VarManager::kMultTPC, VarManager::kCosThetaHE, VarManager::kPhiHE}; - int varsTPCMulCS[4] = {VarManager::kMass, VarManager::kMultTPC, VarManager::kCosThetaCS, VarManager::kPhiCS}; + if (subGroupStr.Contains("dimuon-fwdmult-polarization-cs")) { + int varsFT0AMulCS[4] = {VarManager::kMass, VarManager::kMultFT0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; + int varsFV0AMulCS[4] = {VarManager::kMass, VarManager::kMultFV0A, VarManager::kCosThetaCS, VarManager::kPhiCS}; int binsMul[4] = {100, 20, 20, 20}; double xminMul[4] = {1., 0., -1., -3.14}; - double xmaxMul[4] = {5., 2000., 1., +3.14}; - hm->AddHistogram(histClass, "Mass_MultTPC_cosThetaCS_phiCS", "", 4, varsTPCMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); - hm->AddHistogram(histClass, "Mass_MultTPC_cosThetaHE_phiHE", "", 4, varsTPCMulHE, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + double xmaxMul[4] = {5., 3000., 1., +3.14}; + hm->AddHistogram(histClass, "Mass_FT0AMult_cosThetaCS_phiCS", "", 4, varsFT0AMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); + hm->AddHistogram(histClass, "Mass_FV0AMult_cosThetaCS_phiCS", "", 4, varsFV0AMulCS, binsMul, xminMul, xmaxMul, 0, -1, kFALSE); } if (subGroupStr.Contains("vertexing-forward")) { hm->AddHistogram(histClass, "Lxyz", "", false, 100, 0.0, 10.0, VarManager::kVertexingLxyz); @@ -1161,8 +1197,8 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h } if (subGroupStr.Contains("correlation-emu")) { hm->AddHistogram(histClass, "DeltaPhiPair2", "", false, 600, -0.5 * TMath::Pi(), 1.5 * TMath::Pi(), VarManager::kDeltaPhiPair2); - hm->AddHistogram(histClass, "DeltaEtaPair2", "", false, 600, -1.0, 5.0, VarManager::kDeltaEtaPair2); - hm->AddHistogram(histClass, "DeltaPhiPair2_DeltaEtaPair2", "", false, 600, -0.5 * TMath::Pi(), 1.5 * TMath::Pi(), VarManager::kDeltaPhiPair2, 600, -1.0, 5.0, VarManager::kDeltaEtaPair2); + hm->AddHistogram(histClass, "DeltaEtaPair2", "", false, 350, 1.5, 5.0, VarManager::kDeltaEtaPair2); + hm->AddHistogram(histClass, "DeltaPhiPair2_DeltaEtaPair2", "", false, 600, -0.5 * TMath::Pi(), 1.5 * TMath::Pi(), VarManager::kDeltaPhiPair2, 350, 1.5, 5.0, VarManager::kDeltaEtaPair2); } if (subGroupStr.Contains("dielectrons")) { if (subGroupStr.Contains("prefilter")) { diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 6b9af9bb7cc..0f9892c6c2f 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -360,6 +360,8 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kMultNTracksITSTPC] = ""; fgVariableNames[kTrackOccupancyInTimeRange] = "track occupancy in TPC drift time (PV tracks)"; fgVariableUnits[kTrackOccupancyInTimeRange] = ""; + fgVariableNames[kNoCollInTimeRangeStandard] = "track occupancy in TPC drift standart time"; + fgVariableUnits[kNoCollInTimeRangeStandard] = ""; fgVariableNames[kMultAllTracksITSTPC] = "# ITS-TPC tracks"; fgVariableUnits[kMultAllTracksITSTPC] = ""; fgVariableNames[kMultAllTracksTPCOnly] = "# TPC only tracks"; @@ -755,18 +757,30 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kS31A] = ""; fgVariableNames[kM11REF] = "M_{11}^{REF} "; fgVariableUnits[kM11REF] = ""; + fgVariableNames[kM11REFetagap] = "M_{11}^{REF}-etagap "; + fgVariableUnits[kM11REFetagap] = ""; fgVariableNames[kM01POI] = "M^{'}_{01}^{POI} "; fgVariableUnits[kM01POI] = ""; fgVariableNames[kM1111REF] = "M_{1111}^{REF} "; fgVariableUnits[kM1111REF] = ""; + fgVariableNames[kM1111REFsmall] = "M_{1111}^{REF}small "; + fgVariableUnits[kM1111REFsmall] = ""; fgVariableNames[kM0111POI] = "M^{'}_{0111}^{POI} "; fgVariableUnits[kM0111POI] = ""; fgVariableNames[kCORR2REF] = "<2> "; fgVariableUnits[kCORR2REF] = ""; fgVariableNames[kCORR2REFw] = "<2w> "; fgVariableUnits[kCORR2REFw] = ""; + fgVariableNames[kCORR2REFsquared] = " "; + fgVariableUnits[kCORR2REFsquared] = ""; fgVariableNames[kCORR2REFsquaredw] = " "; fgVariableUnits[kCORR2REFsquaredw] = ""; + fgVariableNames[kCORR2REFetagap] = "<2-etagap> "; + fgVariableUnits[kCORR2REFetagap] = ""; + fgVariableNames[kCORR2REFetagapw] = "<2w-etagap> "; + fgVariableUnits[kCORR2REFetagapw] = ""; + fgVariableNames[kCORR2REFetagapsquaredw] = " "; + fgVariableUnits[kCORR2REFetagapsquaredw] = ""; fgVariableNames[kCORR2POI] = "<2'> "; fgVariableUnits[kCORR2POI] = ""; fgVariableNames[kCORR2POIw] = "<2'w> "; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index d676d0efcf5..0c5b49f5a7e 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -235,6 +235,7 @@ class VarManager : public TObject kMultNTracksTPCOnly, kMultNTracksITSTPC, kTrackOccupancyInTimeRange, + kNoCollInTimeRangeStandard, kMultAllTracksTPCOnly, kMultAllTracksITSTPC, kNTPCpileupContribA, @@ -619,12 +620,18 @@ class VarManager : public TObject kS13A, kS31A, kM11REF, + kM11REFetagap, kM01POI, kM1111REF, + kM1111REFsmall, kM0111POI, kCORR2REF, kCORR2REFw, + kCORR2REFsquared, kCORR2REFsquaredw, + kCORR2REFetagap, + kCORR2REFetagapw, + kCORR2REFetagapsquaredw, kCORR2POI, kCORR2POIw, kCORR2POIsquaredw, @@ -1347,6 +1354,12 @@ void VarManager::FillEvent(T const& event, float* values) if (fgUsedVars[kIsNoITSROFBorder]) { values[kIsNoITSROFBorder] = event.selection_bit(o2::aod::evsel::kNoITSROFrameBorder); } + if (fgUsedVars[kTrackOccupancyInTimeRange]) { + values[kTrackOccupancyInTimeRange] = event.trackOccupancyInTimeRange(); + } + if (fgUsedVars[kNoCollInTimeRangeStandard]) { + values[kNoCollInTimeRangeStandard] = event.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard); + } if (fgUsedVars[kIsNoTFBorder]) { values[kIsNoTFBorder] = event.selection_bit(o2::aod::evsel::kNoTimeFrameBorder); } @@ -1443,7 +1456,6 @@ void VarManager::FillEvent(T const& event, float* values) values[kMultNTracksITSOnly] = event.multNTracksITSOnly(); values[kMultNTracksTPCOnly] = event.multNTracksTPCOnly(); values[kMultNTracksITSTPC] = event.multNTracksITSTPC(); - values[kTrackOccupancyInTimeRange] = event.trackOccupancyInTimeRange(); values[kMultAllTracksTPCOnly] = event.multAllTracksTPCOnly(); values[kMultAllTracksITSTPC] = event.multAllTracksITSTPC(); if constexpr ((fillMap & ReducedEventMultExtra) > 0) { @@ -1470,6 +1482,9 @@ void VarManager::FillEvent(T const& event, float* values) if (fgUsedVars[kIsNoTFBorder]) { values[kIsNoTFBorder] = (event.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) > 0); } + if (fgUsedVars[kNoCollInTimeRangeStandard]) { + values[kNoCollInTimeRangeStandard] = (event.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) > 0); + } if (fgUsedVars[kIsNoSameBunch]) { values[kIsNoSameBunch] = (event.selection_bit(o2::aod::evsel::kNoSameBunchPileup) > 0); } @@ -1607,10 +1622,16 @@ void VarManager::FillEvent(T const& event, float* values) if constexpr ((fillMap & ReducedEventRefFlow) > 0) { values[kM1111REF] = event.m1111ref(); + values[kM1111REFsmall] = event.m1111ref(); values[kM11REF] = event.m11ref(); + values[kM11REFetagap] = event.m11ref(); values[kCORR2REF] = event.corr2ref(); + values[kCORR2REFsquared] = event.corr2ref(); values[kCORR2REFw] = event.corr2ref(); values[kCORR2REFsquaredw] = event.corr2ref(); + values[kCORR2REFetagap] = event.corr2ref(); + values[kCORR2REFetagapw] = event.corr2ref(); + values[kCORR2REFetagapsquaredw] = event.corr2ref(); values[kCORR4REF] = event.corr4ref(); values[kCORR4REFw] = event.corr4ref(); values[kCORR4REFsquaredw] = event.corr4ref(); @@ -3963,10 +3984,21 @@ void VarManager::FillQVectorFromGFW(C const& /*collision*/, A const& compA11, A values[kCORR2REF] = std::isnan(values[kCORR2REF]) || std::isinf(values[kCORR2REF]) ? 0 : values[kCORR2REF]; values[kCORR4REF] = std::isnan(values[kCORR4REF]) || std::isinf(values[kCORR4REF]) ? 0 : values[kCORR4REF]; values[kCORR2REFw] = values[kCORR2REF] * values[kM11REF]; + values[kCORR2REFsquared] = values[kCORR2REF] * values[kCORR2REF]; values[kCORR2REFsquaredw] = values[kCORR2REF] * values[kCORR2REF] * values[kM11REF]; values[kCORR4REFw] = values[kCORR4REF] * values[kM1111REF]; values[kCORR4REFsquaredw] = values[kCORR4REF] * values[kCORR4REF] * values[kM1111REF]; + // For cumulants: A = Full TPC, B = Negative TPC, C = Positive TPC + complex QA(values[kQ2X0A] * values[kS11A], values[kQ2Y0A] * values[kS11A]); + complex QB(values[kQ2X0B] * S11B, values[kQ2Y0B] * S11B); + complex QC(values[kQ2X0C] * S11C, values[kQ2Y0C] * S11C); + values[kM11REFetagap] = S11B * S11C; + values[kCORR2REFetagap] = ((QB * conj(QC)).real()) / values[kM11REFetagap]; + values[kCORR2REFetagap] = std::isnan(values[kCORR2REFetagap]) || std::isinf(values[kCORR2REFetagap]) ? 0 : values[kCORR2REFetagap]; + values[kCORR2REFetagapw] = values[kCORR2REFetagap] * values[kM11REFetagap]; + values[kCORR2REFetagapsquaredw] = values[kCORR2REFetagap] * values[kCORR2REFetagap] * values[kM11REFetagap]; + // TODO: provide different computations for R // Compute the R factor using the 2 sub-events technique for second and third harmonic // Compute event planes diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index 3be2d6ec906..f50c92dc5ec 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -398,6 +398,9 @@ 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); //! +DECLARE_SOA_INDEX_COLUMN(ReducedMCTrack, reducedMCTrack); //! +DECLARE_SOA_COLUMN(McMask, mcMask, uint16_t); //! +DECLARE_SOA_COLUMN(McReducedFlags, mcReducedFlags, uint16_t); //! } // namespace reducedmft // MFT track kinematics @@ -410,8 +413,13 @@ DECLARE_SOA_TABLE(ReducedMFTsExtra, "AOD", "RMFTEXTRA", //! reducedmft::MftClusterSizesAndTrackFlags, reducedmft::Sign, reducedmft::FwdDcaX, reducedmft::FwdDcaY, reducedmft::MftNClusters); +DECLARE_SOA_TABLE(ReducedMFTLabels, "AOD", "RTMFTLABELS", //! + reducedmft::ReducedMCTrackId, reducedmft::McMask, reducedmft::McReducedFlags); + // iterator using ReducedMFT = ReducedMFTs::iterator; +using ReducedMFTExtra = ReducedMFTsExtra::iterator; +using ReducedMFTLabel = ReducedMFTLabels::iterator; // muon quantities namespace reducedmuon @@ -833,17 +841,18 @@ DECLARE_SOA_TABLE(DitracksExtra, "AOD", "RTDITRKEXTRA", //! // 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); //! +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(McDecision, mcDecision, uint32_t); //! } // 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); + reducedmft::FwdDcaX, reducedmft::FwdDcaY, fwdtrack::Chi2MatchMCHMID, fwdtrack::Chi2MatchMCHMFT, fwdpid::McDecision); using FwdPidAll = FwdPidsAll::iterator; @@ -1069,6 +1078,30 @@ DECLARE_SOA_TABLE(ReducedMuonsDca, "AOD", "RTMUONDCA", muondca::Pz); using ReducedMuonDca = ReducedMuonsDca::iterator; + +//______________________________________________________ +namespace generatedquarkoniamc +{ +//______________________________________________________ +// Binned content for generated particles: derived data +DECLARE_SOA_COLUMN(GeneratedEtaC1S, generatedEtaC1S, std::vector); //! Eta(1S) binned generated data +DECLARE_SOA_COLUMN(GeneratedJPsi, generatedJPsi, std::vector); //! J/Psi binned generated data +DECLARE_SOA_COLUMN(GeneratedChiC0, generatedChiC0, std::vector); //! ChiC0(1P) binned generated data +DECLARE_SOA_COLUMN(GeneratedChiC1, generatedChiC1, std::vector); //! ChiC1(1P) binned generated data +DECLARE_SOA_COLUMN(GeneratedHC, generatedHC, std::vector); //! hC binned generated data +DECLARE_SOA_COLUMN(GeneratedChiC2, generatedChiC2, std::vector); //! ChiC2(1P) binned generated data +DECLARE_SOA_COLUMN(GeneratedEtaC2S, generatedEtaC2S, std::vector); //! EtaC(2S) binned generated data +DECLARE_SOA_COLUMN(GeneratedPsi2S, generatedPsi2S, std::vector); //! Psi(2S) binned generated data +} // namespace generatedquarkoniamc + +DECLARE_SOA_TABLE(GeEtaC1S, "AOD", "GEETAC1S", generatedquarkoniamc::GeneratedEtaC1S); +DECLARE_SOA_TABLE(GeJPsi, "AOD", "GEJPSI", generatedquarkoniamc::GeneratedJPsi); +DECLARE_SOA_TABLE(GeChiC0, "AOD", "GECHIC0", generatedquarkoniamc::GeneratedChiC0); +DECLARE_SOA_TABLE(GeChiC1, "AOD", "GECHIC1", generatedquarkoniamc::GeneratedChiC1); +DECLARE_SOA_TABLE(GeHC, "AOD", "GEHC", generatedquarkoniamc::GeneratedHC); +DECLARE_SOA_TABLE(GeChiC2, "AOD", "GECHIC2", generatedquarkoniamc::GeneratedChiC2); +DECLARE_SOA_TABLE(GeEtaC2S, "AOD", "GEETAC2S", generatedquarkoniamc::GeneratedEtaC2S); +DECLARE_SOA_TABLE(GePsi2S, "AOD", "GEPSI2S", generatedquarkoniamc::GeneratedPsi2S); } // namespace o2::aod #endif // PWGDQ_DATAMODEL_REDUCEDINFOTABLES_H_ diff --git a/PWGDQ/TableProducer/CMakeLists.txt b/PWGDQ/TableProducer/CMakeLists.txt index 81c2976b2e7..b8fd20d356d 100644 --- a/PWGDQ/TableProducer/CMakeLists.txt +++ b/PWGDQ/TableProducer/CMakeLists.txt @@ -38,3 +38,8 @@ o2physics_add_dpl_workflow(table-maker-muon-mch-trk-eff SOURCES tableMakerMuonMchTrkEfficiency.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(generated-quarkonia-mc + SOURCES generatedQuarkoniaMC.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase O2Physics::PWGDQCore + COMPONENT_NAME Analysis) diff --git a/PWGDQ/TableProducer/generatedQuarkoniaMC.cxx b/PWGDQ/TableProducer/generatedQuarkoniaMC.cxx new file mode 100644 index 00000000000..737faaaa6b2 --- /dev/null +++ b/PWGDQ/TableProducer/generatedQuarkoniaMC.cxx @@ -0,0 +1,242 @@ +// 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 task provides produces histograms containing +// the number of generated quarkonia per unit of +// percentile and per unit of pT +// It is meant to help with providing auxiliary information +// when dealing with derived data. + +#include +#include +#include +#include +#include +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "DCAFitter/DCAFitterN.h" +#include "ReconstructionDataFormats/Track.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Common/TableProducer/PID/pidTOFBase.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Qvectors.h" +#include "Framework/StaticFor.h" +#include "Common/DataModel/McCollisionExtra.h" +#include "PWGLF/DataModel/EPCalibrationTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +// simple bit checkers +#define bitset(var, nbit) ((var) |= (1 << (nbit))) +#define bitcheck(var, nbit) ((var) & (1 << (nbit))) + +struct generatedQuarkoniaMC { + SliceCache cache; + //__________________________________________________ + // Generated binned data + // this is a hack while the system does not do better + Produces geEtaC1S; + Produces geJPsi; + Produces geChiC0; + Produces geChiC1; + Produces geHC; + Produces geChiC2; + Produces geEtaC2S; + Produces gePsi2S; + + // histogram registry for bookkeeping + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + static constexpr int nSpecies = 8; + static constexpr int nParameters = 1; + static const std::vector particleNames; + static const std::vector particlePDGCodes; + static const std::vector parameterNames; + static const int defaultParameters[nSpecies][nParameters]; + static constexpr std::string_view particleNamesConstExpr[] = {"EtaC1S", "JPsi", "ChiC0", "ChiC1", + "hC", "ChiC2", "EtaC2S", "Psi2S"}; + + uint32_t enabledBits = 0; + + Configurable> enableGeneratedInfo{"enableGeneratedInfo", + {defaultParameters[0], nSpecies, + nParameters, particleNames, parameterNames}, + "Fill generated particle histograms for each species. 0: no, 1: yes"}; + + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "p_{T} (GeV/c)"}; + ConfigurableAxis axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, "Centrality"}; + + ConfigurableAxis axisNVertices{"axisNVertices", {10, -0.5f, 9.5f}, "N(vertices)"}; + + std::vector genEtaC1S; + std::vector genJPsi; + std::vector genChiC0; + std::vector genChiC1; + std::vector genHC; + std::vector genChiC2; + std::vector genEtaC2S; + std::vector genPsi2S; + + // Preslice + Preslice mcParticlePerMcCollision = o2::aod::mcparticle::mcCollisionId; + + void init(InitContext&) + { + // setup map for fast checking if enabled + static_for<0, nSpecies - 1>([&](auto i) { + constexpr int index = i.value; + int f = enableGeneratedInfo->get(particleNames[index].c_str(), "Enable"); + if (f == 1) { + bitset(enabledBits, index); + } + }); + + // Creation of histograms: MC generated + for (Int_t i = 0; i < nSpecies; i++) { + histos.add(Form("h2dGenerated%s", particleNames[i].data()), Form("h2dGenerated%s", particleNames[i].data()), kTH2D, {axisCentrality, axisPt}); + } + + histos.add("h2dNVerticesVsCentrality", "h2dNVerticesVsCentrality", kTH2D, {axisCentrality, axisNVertices}); + + // reserve space for generated vectors if that process enabled + auto hBinFinder = histos.get(HIST("h2dGeneratedEtaC1S")); + LOGF(info, "Binned generated processing enabled. Initialising with %i elements...", hBinFinder->GetNcells()); + genEtaC1S.resize(hBinFinder->GetNcells(), 0); + genJPsi.resize(hBinFinder->GetNcells(), 0); + genChiC0.resize(hBinFinder->GetNcells(), 0); + genChiC1.resize(hBinFinder->GetNcells(), 0); + genHC.resize(hBinFinder->GetNcells(), 0); + genChiC2.resize(hBinFinder->GetNcells(), 0); + genEtaC2S.resize(hBinFinder->GetNcells(), 0); + genPsi2S.resize(hBinFinder->GetNcells(), 0); + LOGF(info, "Binned generated processing: init done."); + } + + void processReconstructedSimulation(aod::McCollision const& /*mcCollision*/, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) + { + // this process function also checks if a given collision was reconstructed and checks explicitly for splitting, etc + // identify best-of collision + int biggestNContribs = -1; + float bestCentrality = 100.5; + for (auto& collision : collisions) { + if (biggestNContribs < collision.numContrib()) { + biggestNContribs = collision.numContrib(); + bestCentrality = collision.centFT0M(); + } + } + histos.fill(HIST("h2dNVerticesVsCentrality"), bestCentrality, collisions.size()); + + for (auto& mcp : mcParticles) { + 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)) { + histos.fill(HIST("h2dGenerated") + HIST(particleNamesConstExpr[index]), bestCentrality, mcp.pt()); + } + }); + } + } + } + + void processBinnedGenerated(soa::Join const& mcCollisions, aod::McParticles const& mcParticlesEntireTable) + { + // set to zero + std::fill(genEtaC1S.begin(), genEtaC1S.end(), 0); + std::fill(genJPsi.begin(), genJPsi.end(), 0); + std::fill(genChiC0.begin(), genChiC0.end(), 0); + std::fill(genChiC1.begin(), genChiC1.end(), 0); + std::fill(genHC.begin(), genHC.end(), 0); + std::fill(genChiC2.begin(), genChiC2.end(), 0); + std::fill(genEtaC2S.begin(), genEtaC2S.end(), 0); + std::fill(genPsi2S.begin(), genPsi2S.end(), 0); + + // this process function also checks if a given collision was reconstructed and checks explicitly for splitting, etc + for (auto& mcCollision : mcCollisions) { + const uint64_t mcCollIndex = mcCollision.globalIndex(); + + // use one of the generated histograms as the bin finder + auto hBinFinder = histos.get(HIST("h2dGeneratedEtaC1S")); + + auto mcParticles = mcParticlesEntireTable.sliceBy(mcParticlePerMcCollision, mcCollIndex); + for (auto& mcp : mcParticles) { + if (TMath::Abs(mcp.y()) < 0.5 /* && mcp.isPhysicalPrimary()*/) { + auto binNumber = hBinFinder->FindBin(mcCollision.bestCollisionCentFT0C(), mcp.pt()); // caution: pack + if (mcp.pdgCode() == 441) + genEtaC1S[binNumber]++; + if (mcp.pdgCode() == 443) + genJPsi[binNumber]++; + if (mcp.pdgCode() == 10441) + genChiC0[binNumber]++; + if (mcp.pdgCode() == 20443) + genChiC1[binNumber]++; + if (mcp.pdgCode() == 10443) + genHC[binNumber]++; + if (mcp.pdgCode() == 445) + genChiC2[binNumber]++; + if (mcp.pdgCode() == 100441) + genEtaC2S[binNumber]++; + if (mcp.pdgCode() == 100443) + genPsi2S[binNumber]++; + } + } + } + // at end of data frame + // -> pack information from this DF into a generated histogram, once / DF + geEtaC1S(genEtaC1S); + geJPsi(genJPsi); + geChiC0(genChiC0); + geChiC1(genChiC1); + geHC(genHC); + geChiC2(genChiC2); + geEtaC2S(genEtaC2S); + gePsi2S(genPsi2S); + } + + PROCESS_SWITCH(generatedQuarkoniaMC, processReconstructedSimulation, "Produce reco-ed simulated information", true); + PROCESS_SWITCH(generatedQuarkoniaMC, processBinnedGenerated, "Produce binned generated information", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} + +//__________________________________________________ +// do not over-populate general namespace, keep scope generatedQuarkoniaMC:: +const std::vector generatedQuarkoniaMC::particleNames{"EtaC1S", "JPsi", "ChiC0", "ChiC1", + "hC", "ChiC2", "EtaC2S", "Psi2S"}; +const std::vector generatedQuarkoniaMC::particlePDGCodes{441, 443, 10441, 20443, 10443, 445, 100441, 100443}; +const std::vector generatedQuarkoniaMC::parameterNames{"Enable"}; + +const int generatedQuarkoniaMC::defaultParameters[generatedQuarkoniaMC::nSpecies][generatedQuarkoniaMC::nParameters] = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}; diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 7c123b30959..5a6fc2f09a7 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -115,14 +115,6 @@ using MyMuonsColl = soa::Join; using ExtBCs = soa::Join; -namespace o2::aod -{ -DECLARE_SOA_TABLE(AmbiguousTracksMid, "AOD", "AMBIGUOUSTRACKU", //! Table for tracks which are not uniquely associated with a collision - o2::soa::Index<>, o2::aod::ambiguous::TrackId, o2::aod::ambiguous::BCIdSlice, o2::soa::Marker<2>); -DECLARE_SOA_TABLE(AmbiguousTracksFwd, "AOD", "AMBIGUOUSFWDTRU", //! Table for Fwd tracks which are not uniquely associated with a collision - o2::soa::Index<>, o2::aod::ambiguous::FwdTrackId, o2::aod::ambiguous::BCIdSlice, o2::soa::Marker<2>); -} // namespace o2::aod - constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision; constexpr static uint32_t gkEventFillMapWithMult = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::CollisionMultExtra; constexpr static uint32_t gkEventFillMapWithMultsAndEventFilter = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::CollisionMultExtra | VarManager::ObjTypes::EventFilter; @@ -1586,7 +1578,7 @@ struct TableMaker { } void processAssociatedMuonOnlyWithCov(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, - soa::Filtered const& tracksMuon, aod::AmbiguousTracksFwd const&, aod::FwdTrackAssoc const& fwdtrackIndices) + soa::Filtered const& tracksMuon, aod::AmbiguousFwdTracks const&, aod::FwdTrackAssoc const& fwdtrackIndices) { for (auto& collision : collisions) { auto muonIdsThisCollision = fwdtrackIndices.sliceBy(fwdtrackIndicesPerCollision, collision.globalIndex()); @@ -1595,7 +1587,7 @@ struct TableMaker { } void processAssociatedMuonOnlyWithCovAndCent(MyEventsWithCent const& collisions, aod::BCsWithTimestamps const& bcs, - soa::Filtered const& tracksMuon, aod::AmbiguousTracksFwd const&, aod::FwdTrackAssoc const& fwdtrackIndices) + soa::Filtered const& tracksMuon, aod::AmbiguousFwdTracks const&, aod::FwdTrackAssoc const& fwdtrackIndices) { for (auto& collision : collisions) { auto muonIdsThisCollision = fwdtrackIndices.sliceBy(fwdtrackIndicesPerCollision, collision.globalIndex()); @@ -1604,7 +1596,7 @@ struct TableMaker { } void processAssociatedMuonOnlyWithCovAndMults(MyEventsWithMults const& collisions, aod::BCsWithTimestamps const& bcs, - soa::Filtered const& tracksMuon, aod::AmbiguousTracksFwd const&, aod::FwdTrackAssoc const& fwdtrackIndices) + soa::Filtered const& tracksMuon, aod::AmbiguousFwdTracks const&, aod::FwdTrackAssoc const& fwdtrackIndices) { for (auto& collision : collisions) { auto muonIdsThisCollision = fwdtrackIndices.sliceBy(fwdtrackIndicesPerCollision, collision.globalIndex()); @@ -1613,7 +1605,7 @@ struct TableMaker { } void processAmbiguousMuonOnlyWithCov(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, - soa::Filtered const& tracksMuon, aod::AmbiguousTracksFwd const& ambiTracksFwd) + soa::Filtered const& tracksMuon, aod::AmbiguousFwdTracks const& ambiTracksFwd) { // Process orphan tracks if (fDoDetailedQA && fIsAmbiguous) { @@ -1637,7 +1629,7 @@ struct TableMaker { // Produce track tables only for ambiguous tracks studies ------------------------------------------------------------------------------------- void processAmbiguousBarrelOnly(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, - soa::Filtered const& tracksBarrel, aod::AmbiguousTracksMid const& ambiTracksMid) + soa::Filtered const& tracksBarrel, aod::AmbiguousTracks const& ambiTracksMid) { // Process orphan tracks if (fDoDetailedQA && fIsAmbiguous) { diff --git a/PWGDQ/TableProducer/tableMakerMC.cxx b/PWGDQ/TableProducer/tableMakerMC.cxx index bee0f0880a1..fde24653c03 100644 --- a/PWGDQ/TableProducer/tableMakerMC.cxx +++ b/PWGDQ/TableProducer/tableMakerMC.cxx @@ -79,19 +79,13 @@ using MyMuonsWithCov = soa::Join; using MyMuonsCollWithCov = soa::Join; +using MyMftTracks = soa::Join; + using MyEvents = soa::Join; using MyEventsWithMults = soa::Join; using MyEventsWithCent = soa::Join; using MyEventsWithCentAndMults = soa::Join; -namespace o2::aod -{ -DECLARE_SOA_TABLE(AmbiguousTracksMid, "AOD", "AMBIGUOUSTRACKU", //! Table for tracks which are not uniquely associated with a collision - o2::soa::Index<>, o2::aod::ambiguous::TrackId, o2::aod::ambiguous::BCIdSlice, o2::soa::Marker<2>); -DECLARE_SOA_TABLE(AmbiguousTracksFwd, "AOD", "AMBIGUOUSFWDTRU", //! Table for Fwd tracks which are not uniquely associated with a collision - o2::soa::Index<>, o2::aod::ambiguous::FwdTrackId, o2::aod::ambiguous::BCIdSlice, o2::soa::Marker<2>); -} // namespace o2::aod - constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision; constexpr static uint32_t gkEventFillMapWithMults = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult; constexpr static uint32_t gkEventFillMapWithCent = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionCent; @@ -105,6 +99,7 @@ constexpr static uint32_t gkMuonFillMapWithCov = VarManager::ObjTypes::Muon | Va constexpr static uint32_t gkMuonFillMapWithAmbi = VarManager::ObjTypes::Muon | VarManager::ObjTypes::AmbiMuon; constexpr static uint32_t gkMuonFillMapWithCovAmbi = VarManager::ObjTypes::Muon | VarManager::ObjTypes::MuonCov | VarManager::ObjTypes::AmbiMuon; constexpr static uint32_t gkTrackFillMapWithAmbi = VarManager::ObjTypes::Track | VarManager::ObjTypes::AmbiTrack; +constexpr static uint32_t gkMFTFillMap = VarManager::ObjTypes::TrackMFT; struct TableMakerMC { @@ -127,6 +122,9 @@ struct TableMakerMC { Produces muonExtra; Produces muonCov; Produces muonLabels; // TODO: enable this once we have fwdtrack labels + Produces trackMFT; + Produces trackMFTExtra; + Produces trackMFTLabels; // list of MCsignal objects std::vector fMCSignals; @@ -316,9 +314,9 @@ struct TableMakerMC { Preslice fwdtrackIndicesPerCollision = aod::track_association::collisionId; // Templated function instantianed for all of the process functions - template + template void fullSkimming(TEvent const& collisions, aod::BCsWithTimestamps const& /*bcs*/, TTracks const& tracksBarrel, TMuons const& tracksMuon, - aod::McCollisions const& /*mcEvents*/, aod::McParticles_001 const& mcTracks, TAmbiTracks const& ambiTracksMid, TAmbiMuons const& ambiTracksFwd) + aod::McCollisions const& /*mcEvents*/, aod::McParticles_001 const& mcTracks, TAmbiTracks const& ambiTracksMid, TAmbiMuons const& ambiTracksFwd, TMFTTracks const& mftTracks = nullptr) { // Loop over collisions and produce skimmed data tables for: // 1) all selected collisions @@ -652,6 +650,71 @@ struct TableMakerMC { } // end loop over reconstructed tracks } // end if constexpr (static_cast(TTrackFillMap)) + // Maps for the MFT-muon matching index + std::map newMFTTableSize; // key : oldMFTIndex, value: size of the table-1 at step key + std::map mftOffsets; // key: mftoldglobalindex, value: mft.offsets + + if constexpr (static_cast(TMFTFillMap)) { + trackMFT.reserve(mftTracks.size()); + trackMFTExtra.reserve(mftTracks.size()); + // TODO add cuts on the MFT tracks + // int nDel = 0; + for (auto& mft : mftTracks) { + if (false) // for now no cuts + { + // nDel++; + } else { // it passes the cuts and will be saved in the tables + newMFTTableSize[mft.index()] = trackMFT.lastIndex(); + } + + // Check MC matching + if (!mft.has_mcParticle()) { + continue; + } + auto mctrack = mft.template mcParticle_as(); + + mcflags = 0; + int i = 0; // runs over the MC signals + // check all the specified signals and fill histograms for MC truth matched tracks + for (auto& sig : fMCSignals) { + if (sig.CheckSignal(true, mctrack)) { + mcflags |= (uint16_t(1) << i); + } + i++; + } + + // if the MC truth particle corresponding to this reconstructed track is not already written, + // add it to the skimmed stack + if (!(fNewLabels.find(mctrack.globalIndex()) != fNewLabels.end())) { + fNewLabels[mctrack.globalIndex()] = fCounters[0]; + fNewLabelsReversed[fCounters[0]] = mctrack.globalIndex(); + fMCFlags[mctrack.globalIndex()] = mcflags; + fEventIdx[mctrack.globalIndex()] = fEventLabels.find(mcCollision.globalIndex())->second; + fCounters[0]++; + } + + 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(), dcaX, dcaY, mft.nClusters()); + trackMFTLabels(fNewLabels.find(mctrack.index())->second, mft.mcMask(), mcflags); + } // end of mft : mftTracks + + } // end if constexpr (TMFTFillMap) + if constexpr (static_cast(TMuonFillMap)) { // build the muon tables muonBasic.reserve(tracksMuon.size()); @@ -669,6 +732,7 @@ struct TableMakerMC { int idxPrev = -1; std::map newEntryNb; std::map newMatchIndex; + std::map newMFTMatchIndex; for (auto& muon : groupedMuons) { trackFilteringTag = uint64_t(0); @@ -792,9 +856,13 @@ struct TableMakerMC { if (static_cast(muon.trackType()) == 0 || static_cast(muon.trackType()) == 2) { // MCH-MFT or GLB track int matchIdx = muon.matchMCHTrackId() - muon.offsets(); + int matchMFTIdx = muon.matchMFTTrackId() - mftOffsets[muon.matchMFTTrackId()]; + + // first for MCH matching index if (newEntryNb.count(matchIdx) > 0) { // if the key exists which means the match will not get deleted newMatchIndex[muon.index()] = newEntryNb[matchIdx]; // update the match for this muon to the updated entry of the match newMatchIndex[muon.index()] += muonBasic.lastIndex() + 1 - newEntryNb[muon.index()]; // adding the offset of muons, muonBasic.lastIndex() start at -1 + if (static_cast(muon.trackType()) == 0) { // for now only do this to global tracks newMatchIndex[matchIdx] = newEntryNb[muon.index()]; // add the updated index of this muon as a match to mch track newMatchIndex[matchIdx] += muonBasic.lastIndex() + 1 - newEntryNb[muon.index()]; // adding the offset, muonBasic.lastIndex() start at -1 @@ -802,6 +870,14 @@ struct TableMakerMC { } else { newMatchIndex[muon.index()] = -1; } + + // then for MFT match index + if (newMFTTableSize.count(matchMFTIdx) > 0) { // if the key exists i.e the match will not get deleted + newMFTMatchIndex[muon.index()] = newMFTTableSize[matchMFTIdx] + 1; // adding the offset of mfts, newMFTTableSize start at -1 + } else { + newMFTMatchIndex[muon.index()] = -1; + } + } else if (static_cast(muon.trackType() == 4)) { // an MCH track // in this case the matches should be filled from the other types but we need to check if (newMatchIndex.count(muon.index()) == 0) { @@ -809,7 +885,7 @@ struct TableMakerMC { } } - muonBasic(event.lastIndex(), newMatchIndex.find(muon.index())->second, -1, trackFilteringTag, VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], muon.sign(), isAmbiguous); + muonBasic(event.lastIndex(), newMatchIndex.find(muon.index())->second, newMFTMatchIndex.find(muon.index())->second, trackFilteringTag, VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], muon.sign(), isAmbiguous); if constexpr (static_cast(TMuonFillMap & VarManager::ObjTypes::MuonCov)) { if (fPropMuon) { muonExtra(muon.nClusters(), VarManager::fgValues[VarManager::kMuonPDca], VarManager::fgValues[VarManager::kMuonRAtAbsorberEnd], @@ -1218,6 +1294,7 @@ struct TableMakerMC { int idxPrev = -1; std::map newEntryNb; std::map newMatchIndex; + std::map newMFTMatchIndex; for (auto& muonId : fwdtrackIdsThisCollision) { auto muon = muonId.template fwdtrack_as(); @@ -1529,14 +1606,14 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, soa::Filtered const& tracksMuon, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, tracksMuon, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, tracksMuon, mcEvents, mcTracks, nullptr, nullptr, nullptr); } void processFullWithCov(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksBarrel, soa::Filtered const& tracksMuon, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, tracksMuon, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, tracksMuon, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables ------------------------------------------------------------------------------------ @@ -1544,7 +1621,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables, with multiplicity ------------------------------------------------------------------------------------ @@ -1552,7 +1629,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables, with centrality ------------------------------------------------------------------------------------ @@ -1560,7 +1637,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables, with centrality and multiplicity ------------------------------------------------------------------- @@ -1568,7 +1645,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables, with cov matrix----------------------------------------------------------------------- @@ -1576,7 +1653,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables, with centrality, multiplicity and cov matrix ------------------------------------------------------------------- @@ -1584,7 +1661,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce barrel only tables, with cov matrix and dalitz bits----------------------------------------------------------------------- @@ -1592,7 +1669,7 @@ struct TableMakerMC { soa::Filtered const& tracksBarrel, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce muon only tables ------------------------------------------------------------------------------------ @@ -1600,21 +1677,28 @@ struct TableMakerMC { soa::Filtered const& tracksMuon, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce muon only tables, with centrality------------------------------------------------------------------------------- void processMuonOnlyWithCent(MyEventsWithCent const& collisions, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksMuon, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr, nullptr); } // Produce muon only tables, with cov matrix ------------------------------------------------------------------------------------ void processMuonOnlyWithCov(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksMuon, aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) { - fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr); + fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr, nullptr); + } + // Produce MFT tracks tables and muons ------------------------------------------------------------------------------------------------------------------ + void processMuonsAndMFT(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, + MyMftTracks const& tracksMft, MyMuonsWithCov const& tracksMuon, + aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks) + { + fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, nullptr, tracksMft); } // Produce muon tables only based on track-collision association tables -------------------------------------------------------------------------------------- void processAssociatedMuonOnly(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, @@ -1647,24 +1731,24 @@ struct TableMakerMC { // Produce muon tables only for ambiguous tracks studies -------------------------------------------------------------------------------------- void processAmbiguousMuonOnly(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksMuon, - aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks, aod::AmbiguousTracksFwd const& ambiTracksFwd) + aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks, aod::AmbiguousFwdTracks const& ambiTracksFwd) { - fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, ambiTracksFwd); + fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, ambiTracksFwd, nullptr); } void processAmbiguousMuonOnlyWithCov(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksMuon, - aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks, aod::AmbiguousTracksFwd const& ambiTracksFwd) + aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks, aod::AmbiguousFwdTracks const& ambiTracksFwd) { - fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, ambiTracksFwd); + fullSkimming(collisions, bcs, nullptr, tracksMuon, mcEvents, mcTracks, nullptr, ambiTracksFwd, nullptr); } // Produce track tables only for ambiguous tracks studies ------------------------------------------------------------------------------------- void processAmbiguousBarrelOnly(MyEvents const& collisions, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksBarrel, - aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks, aod::AmbiguousTracksMid const& ambiTracksMid) + aod::McCollisions const& mcEvents, aod::McParticles_001 const& mcTracks, aod::AmbiguousTracks const& ambiTracksMid) { - fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, ambiTracksMid, nullptr); + fullSkimming(collisions, bcs, tracksBarrel, nullptr, mcEvents, mcTracks, ambiTracksMid, nullptr, nullptr); } // Process the BCs and store stats for luminosity retrieval ----------------------------------------------------------------------------------- void processOnlyBCs(soa::Join::iterator const& bc) @@ -1688,6 +1772,7 @@ struct TableMakerMC { PROCESS_SWITCH(TableMakerMC, processBarrelOnlyWithDalitzBits, "Produce barrel skims, and dalitz bits", false); PROCESS_SWITCH(TableMakerMC, processMuonOnly, "Produce muon skims", false); PROCESS_SWITCH(TableMakerMC, processMuonOnlyWithCov, "Produce muon skims, with muon covariance matrix", false); + PROCESS_SWITCH(TableMakerMC, processMuonsAndMFT, "Produce muon and MFT skims", false); PROCESS_SWITCH(TableMakerMC, processMuonOnlyWithCent, "Produce muon skims, w/ centrality", false); PROCESS_SWITCH(TableMakerMC, processOnlyBCs, "Analyze the BCs to store sampled lumi", false); PROCESS_SWITCH(TableMakerMC, processAssociatedMuonOnly, "Produce muon skims using track-collision association tables", false); diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index e51d0959116..d475c222f61 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -69,6 +69,7 @@ using namespace o2::aod; Zorro zorro; +// Declaration of various Joins used in the different process functions // TODO: Since DCA depends on which collision the track is associated to, we should remove writing and subscribing to DCA tables, to optimize on CPU / memory using MyBarrelTracks = soa::Join; using ExtBCs = soa::Join; -namespace o2::aod -{ -DECLARE_SOA_TABLE(AmbiguousTracksMid, "AOD", "AMBIGUOUSTRACKU", //! Table for tracks which are not uniquely associated with a collision - o2::soa::Index<>, o2::aod::ambiguous::TrackId, o2::aod::ambiguous::BCIdSlice, o2::soa::Marker<2>); -DECLARE_SOA_TABLE(AmbiguousTracksFwd, "AOD", "AMBIGUOUSFWDTRU", //! Table for Fwd tracks which are not uniquely associated with a collision - o2::soa::Index<>, o2::aod::ambiguous::FwdTrackId, o2::aod::ambiguous::BCIdSlice, o2::soa::Marker<2>); -} // namespace o2::aod - +// Declaration of various bit maps containing information on which tables are included in a Join +// These are used as template arguments and checked at compile time // constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision; // constexpr static uint32_t gkEventFillMapWithFilter = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::EventFilter; - constexpr static uint32_t gkEventFillMapWithMults = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult; constexpr static uint32_t gkEventFillMapWithMultsZdc = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::Zdc; constexpr static uint32_t gkEventFillMapWithMultsAndEventFilter = VarManager::ObjTypes::BC | VarManager::ObjTypes::Collision | VarManager::ObjTypes::CollisionMult | VarManager::ObjTypes::CollisionMultExtra | VarManager::ObjTypes::EventFilter; @@ -136,6 +130,16 @@ constexpr static uint32_t gkMuonFillMapWithCov = VarManager::ObjTypes::Muon | Va // constexpr static uint32_t gkTrackFillMapWithAmbi = VarManager::ObjTypes::Track | VarManager::ObjTypes::AmbiTrack; constexpr static uint32_t gkMFTFillMap = VarManager::ObjTypes::TrackMFT; +// Enum containing the ordering of statistics histograms to be written in the QA file +enum SkimStatsHists { + kStatsEvent = 0, + kStatsTracks, + kStatsMuons, + kStatsOrphanTracks, + kStatsZorroInfo, + kStatsZorroSel +}; + struct TableMaker { Produces event; @@ -166,68 +170,83 @@ struct TableMaker { HistogramManager* fHistMan; // Event and track AnalysisCut configurables - Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; - Configurable fConfigTrackCuts{"cfgBarrelTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; - Configurable fConfigMuonCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; - Configurable fConfigRunZorro{"cfgRunZorro", false, "Enable event selection with zorro [WARNING: under debug, do not enable!]"}; - Configurable fConfigZorroTrigMask{"cfgZorroTriggerMask", "fDiMuon", "DQ Trigger masks: fSingleE,fLMeeIMR,fLMeeHMR,fDiElectron,fSingleMuLow,fSingleMuHigh,fDiMuon"}; - Configurable fConfigRunZorroSel{"cfgRunZorroSel", false, "Select events with trigger mask"}; + struct : ConfigurableGroup { + Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; + Configurable fConfigTrackCuts{"cfgBarrelTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigMuonCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; + } fConfigCuts; + + // Zorro selection + struct : ConfigurableGroup { + Configurable fConfigRunZorro{"cfgRunZorro", false, "Enable event selection with zorro [WARNING: under debug, do not enable!]"}; + Configurable fConfigZorroTrigMask{"cfgZorroTriggerMask", "fDiMuon", "DQ Trigger masks: fSingleE,fLMeeIMR,fLMeeHMR,fDiElectron,fSingleMuLow,fSingleMuHigh,fDiMuon"}; + Configurable fConfigRunZorroSel{"cfgRunZorroSel", false, "Select events with trigger mask"}; + } fConfigZorro; // Steer QA output - Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; - Configurable fConfigDetailedQA{"cfgDetailedQA", false, "If true, include more QA histograms (BeforeCuts classes)"}; - Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; - Configurable fConfigAddMuonHistogram{"cfgAddMuonHistogram", "", "Comma separated list of histograms"}; + struct : ConfigurableGroup { + Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; + Configurable fConfigDetailedQA{"cfgDetailedQA", false, "If true, include more QA histograms (BeforeCuts classes)"}; + Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddMuonHistogram{"cfgAddMuonHistogram", "", "Comma separated list of histograms"}; + } fConfigHistOutput; - // Selections to be applied as Filter on the Track and FwdTrack Configurable fIsRun2{"cfgIsRun2", false, "Whether we analyze Run-2 or Run-3 data"}; - Configurable fConfigBarrelTrackMaxAbsEta{"cfgBarrelMaxAbsEta", 0.9f, "Eta absolute value cut for tracks in the barrel"}; - Configurable fConfigBarrelTrackMinPt{"cfgBarrelMinPt", 0.5f, "Minimum pt for tracks in the barrel"}; - Configurable fConfigBarrelRequireTPC{"cfgBarrelRequireTPC", true, "Require TPC for tracks in the barrel"}; - Configurable fConfigBarrelMinTPCncls{"cfgBarrelMinTPCncls", 50.0f, "Minimum TPC cls for tracks in the barrel"}; - Configurable fConfigBarrelMaxTPCchi2{"cfgBarrelMaxTPCchi2", 10.0f, "Maximum TPC chi2/ndf for tracks in the barrel"}; - Configurable fConfigBarrelRequireITS{"cfgBarrelRequireITS", true, "Require ITS for tracks in the barrel"}; - Configurable fConfigBarrelMaxITSchi2{"cfgBarrelMaxITSchi2", 36.0f, "Maximum ITS chi2/ndf for tracks in the barrel"}; - Configurable fConfigMuonPtLow{"cfgMuonLowPt", 1.0f, "Low pt cut for muons"}; + + // Selections to be applied as Filter on the Track and FwdTrack + /*struct : ConfigurableGroup { + Configurable fConfigBarrelTrackMaxAbsEta{"cfgBarrelMaxAbsEta", 0.9f, "Eta absolute value cut for tracks in the barrel"}; + Configurable fConfigBarrelTrackMinPt{"cfgBarrelMinPt", 0.5f, "Minimum pt for tracks in the barrel"}; + Configurable fConfigBarrelRequireTPC{"cfgBarrelRequireTPC", true, "Require TPC for tracks in the barrel"}; + Configurable fConfigBarrelMinTPCncls{"cfgBarrelMinTPCncls", 50.0f, "Minimum TPC cls for tracks in the barrel"}; + Configurable fConfigBarrelMaxTPCchi2{"cfgBarrelMaxTPCchi2", 10.0f, "Maximum TPC chi2/ndf for tracks in the barrel"}; + Configurable fConfigBarrelRequireITS{"cfgBarrelRequireITS", true, "Require ITS for tracks in the barrel"}; + Configurable fConfigBarrelMaxITSchi2{"cfgBarrelMaxITSchi2", 36.0f, "Maximum ITS chi2/ndf for tracks in the barrel"}; + Configurable fConfigMuonPtLow{"cfgMuonLowPt", 1.0f, "Low pt cut for muons"}; + } fConfigFilter;*/ // CCDB connection configurables - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; - Configurable fConfigCcdbPathZorro{"ccdb-path-zorro", "/Users/m/mpuccio/EventFiltering/OTS/", "base path to the ccdb object for zorro"}; - Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable grpmagPathRun2{"grpmagPathRun2", "GLO/GRP/GRP", "CCDB path of the GRPObject (Usage for Run 2)"}; + struct : ConfigurableGroup { + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbPathZorro{"ccdb-path-zorro", "/Users/m/mpuccio/EventFiltering/OTS/Chunked/", "base path to the ccdb object for zorro"}; + Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable fConfigGrpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable fConfigGrpMagPathRun2{"grpmagPathRun2", "GLO/GRP/GRP", "CCDB path of the GRPObject (Usage for Run 2)"}; + } fConfigCCDB; // TPC postcalibration related options - Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas(electrons, pions, protons)"}; - Configurable fConfigComputeTPCpostCalibKaon{"cfgTPCpostCalibKaon", false, "If true, compute TPC post-calibrated n-sigmas for kaons"}; - Configurable fConfigIsOnlyforMaps{"cfgIsforMaps", false, "If true, run for postcalibration maps only"}; - Configurable fConfigSaveElectronSample{"cfgSaveElectronSample", false, "If true, only save electron sample"}; - Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; - Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; - - // Track related options - Configurable fPropTrack{"cfgPropTrack", true, "Propagate tracks to associated collision to recalculate DCA and momentum vector"}; - - // Muon related options - Configurable fPropMuon{"cfgPropMuon", true, "Propagate muon tracks through absorber (do not use if applying pairing)"}; - Configurable fRefitGlobalMuon{"cfgRefitGlobalMuon", true, "Correct global muon parameters"}; - Configurable fMuonMatchEtaMin{"cfgMuonMatchEtaMin", -4.0f, "Definition of the acceptance of muon tracks to be matched with MFT"}; - Configurable fMuonMatchEtaMax{"cfgMuonMatchEtaMax", -2.5f, "Definition of the acceptance of muon tracks to be matched with MFT"}; + struct : ConfigurableGroup { + Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas(electrons, pions, protons)"}; + Configurable fConfigComputeTPCpostCalibKaon{"cfgTPCpostCalibKaon", false, "If true, compute TPC post-calibrated n-sigmas for kaons"}; + Configurable fConfigIsOnlyforMaps{"cfgIsforMaps", false, "If true, run for postcalibration maps only"}; + Configurable fConfigSaveElectronSample{"cfgSaveElectronSample", false, "If true, only save electron sample"}; + Configurable fConfigDummyRunlist{"cfgDummyRunlist", false, "If true, use dummy runlist"}; + Configurable fConfigInitRunNumber{"cfgInitRunNumber", 543215, "Initial run number used in run by run checks"}; + } fConfigPostCalibTPC; + + struct : ConfigurableGroup { + // Track related options + Configurable fPropTrack{"cfgPropTrack", true, "Propagate tracks to associated collision to recalculate DCA and momentum vector"}; + // Muon related options + Configurable fPropMuon{"cfgPropMuon", true, "Propagate muon tracks through absorber (do not use if applying pairing)"}; + Configurable fRefitGlobalMuon{"cfgRefitGlobalMuon", true, "Correct global muon parameters"}; + Configurable fMuonMatchEtaMin{"cfgMuonMatchEtaMin", -4.0f, "Definition of the acceptance of muon tracks to be matched with MFT"}; + Configurable fMuonMatchEtaMax{"cfgMuonMatchEtaMax", -2.5f, "Definition of the acceptance of muon tracks to be matched with MFT"}; + } fConfigVariousOptions; Service fCCDB; + o2::ccdb::CcdbApi fCCDBApi; - o2::parameters::GRPObject* grpmagrun2 = nullptr; // for run 2, we access the GRPObject from GLO/GRP/GRP - o2::parameters::GRPMagField* grpmag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField + o2::parameters::GRPObject* fGrpMagRun2 = nullptr; // for run 2, we access the GRPObject from GLO/GRP/GRP + o2::parameters::GRPMagField* fGrpMag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField AnalysisCompositeCut* fEventCut; //! Event selection cut std::vector fTrackCuts; //! Barrel track cuts std::vector fMuonCuts; //! Muon track cuts - Service ccdb; - o2::ccdb::CcdbApi fCCDBApi; bool fDoDetailedQA = false; // Bool to set detailed QA true, if QA is set true int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. @@ -243,12 +262,12 @@ struct TableMaker { // our own Filtered tracks. If the filter is very selective, then it may be worth to run the association in this workflow // using the Common/CollisionAssociation class /*Filter barrelSelectedTracks = ifnode(fIsRun2.node() == true, track::trackType == uint8_t(track::Run2Track), track::trackType == uint8_t(track::Track)) - && track::pt > fConfigBarrelTrackMinPt - && nabs(track::eta) <= fConfigBarrelTrackMaxAbsEta - && ifnode(fConfigBarrelRequireITS.node() == true, track::itsChi2NCl < fConfigBarrelMaxITSchi2, true) - && ifnode(fConfigBarrelRequireTPC.node() == true, track::tpcNClsFound > fConfigBarrelMinTPCncls && track::tpcChi2NCl < fConfigBarrelMaxTPCchi2, true); + && track::pt > fConfigFilter.fConfigBarrelTrackMinPt + && nabs(track::eta) <= fConfigFilter.fConfigBarrelTrackMaxAbsEta + && ifnode(fConfigFilter.fConfigBarrelRequireITS.node() == true, track::itsChi2NCl < fConfigFilter.fConfigBarrelMaxITSchi2, true) + && ifnode(fConfigFilter.fConfigBarrelRequireTPC.node() == true, track::tpcNClsFound > fConfigFilter.fConfigBarrelMinTPCncls && track::tpcChi2NCl < fConfigFilter.fConfigBarrelMaxTPCchi2, true); - Filter muonFilter = o2::aod::fwdtrack::pt >= fConfigMuonPtLow;*/ + Filter muonFilter = o2::aod::fwdtrack::pt >= fConfigFilter.fConfigMuonPtLow;*/ Preslice trackIndicesPerCollision = aod::track_association::collisionId; Preslice fwdtrackIndicesPerCollision = aod::track_association::collisionId; @@ -256,93 +275,105 @@ struct TableMaker { void init(o2::framework::InitContext& context) { - DefineCuts(); - ccdb->setURL(fConfigCcdbUrl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); + // CCDB configuration + if (fConfigPostCalibTPC.fConfigComputeTPCpostCalib) { + fCCDB->setURL(fConfigCCDB.fConfigCcdbUrl.value); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + // Not later than now objects + fCCDB->setCreatedNotAfter(fConfigCCDB.fConfigNoLaterThan.value); + } + fCCDBApi.init(fConfigCCDB.fConfigCcdbUrl.value); + if (!o2::base::GeometryManager::isGeometryLoaded()) { - ccdb->get(geoPath); + fCCDB->get(fConfigCCDB.fConfigGeoPath); } + // Define the event, track and muon cuts + DefineCuts(); + + // Initialize the histogram manager VarManager::SetDefaultVarNames(); fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); fHistMan->SetUseDefaultVariableNames(kTRUE); fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); // Only use detailed QA when QA is set true - if (fConfigQA && fConfigDetailedQA) { + if (fConfigHistOutput.fConfigQA && fConfigHistOutput.fConfigDetailedQA) { fDoDetailedQA = true; } // Create the histogram class names to be added to the histogram manager + // The histogram class names are added into a string and then passed to the DefineHistograms() function which + // actually configures the HistogramManager + // Histograms are defined as histogram classes / groups and filled at specific points in the analysis flow TString histClasses = ""; + // Event-wise histograms, before selection cuts if (fDoDetailedQA) { histClasses += "Event_BeforeCuts;"; } - if (fConfigQA) { + // Event-wise histograms, after selection cuts + if (fConfigHistOutput.fConfigQA) { histClasses += "Event_AfterCuts;"; } + // Check whether we have to define barrel or muon histograms bool enableBarrelHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterBarrelOnly") || context.mOptions.get("processPPBarrelOnly") || context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbBarrelOnly") || context.mOptions.get("processPbPbBarrelOnlyWithV0Bits")); + bool enableMuonHistos = (context.mOptions.get("processPPWithFilter") || context.mOptions.get("processPPWithFilterMuonOnly") || context.mOptions.get("processPPWithFilterMuonMFT") || context.mOptions.get("processPPMuonOnly") || context.mOptions.get("processPPMuonMFT") || context.mOptions.get("processPbPb") || context.mOptions.get("processPbPbMuonOnly") || context.mOptions.get("processPbPbMuonMFT")); if (enableBarrelHistos) { + // Barrel track histograms, before selections if (fDoDetailedQA) { histClasses += "TrackBarrel_BeforeCuts;"; } - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { + // Barrel track histograms after selections; one histogram directory for each user specified selection for (auto& cut : fTrackCuts) { histClasses += Form("TrackBarrel_%s;", cut.GetName()); } } - if (fConfigIsOnlyforMaps) { + // Barrel histograms for clean samples of V0 legs used for post-calibration + if (fConfigPostCalibTPC.fConfigIsOnlyforMaps) { histClasses += "TrackBarrel_PostCalibElectron;"; histClasses += "TrackBarrel_PostCalibPion;"; histClasses += "TrackBarrel_PostCalibProton;"; } } if (enableMuonHistos) { + // Muon tracks before cuts and MFT tracks if (fDoDetailedQA) { histClasses += "Muons_BeforeCuts;"; histClasses += "MftTracks;"; } - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { + // Muon tracks after selections; one directory per selection for (auto& muonCut : fMuonCuts) { histClasses += Form("Muons_%s;", muonCut.GetName()); } } } - if (fConfigDummyRunlist) { - VarManager::SetDummyRunlist(fConfigInitRunNumber); + if (fConfigPostCalibTPC.fConfigDummyRunlist) { + VarManager::SetDummyRunlist(fConfigPostCalibTPC.fConfigInitRunNumber); } DefineHistograms(histClasses); // define all histograms VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); - - // CCDB configuration - if (fConfigComputeTPCpostCalib) { - fCCDB->setURL(fConfigCcdbUrl.value); - fCCDB->setCaching(true); - fCCDB->setLocalObjectValidityChecking(); - // Not later than now objects - fCCDB->setCreatedNotAfter(fConfigNoLaterThan.value); - } - fCCDBApi.init(fConfigCcdbUrl.value); } void DefineCuts() { // Event cuts fEventCut = new AnalysisCompositeCut(true); - TString eventCutStr = fConfigEventCuts.value; + TString eventCutStr = fConfigCuts.fConfigEventCuts.value; fEventCut->AddCut(dqcuts::GetAnalysisCut(eventCutStr.Data())); // Barrel track cuts - TString cutNamesStr = fConfigTrackCuts.value; + TString cutNamesStr = fConfigCuts.fConfigTrackCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { @@ -351,7 +382,7 @@ struct TableMaker { } // Muon cuts - cutNamesStr = fConfigMuonCuts.value; + cutNamesStr = fConfigCuts.fConfigMuonCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); for (int icut = 0; icut < objArray->GetEntries(); ++icut) { @@ -364,15 +395,16 @@ struct TableMaker { void DefineHistograms(TString histClasses) { + // Create histograms via HistogramManager std::unique_ptr objArray(histClasses.Tokenize(";")); for (Int_t iclass = 0; iclass < objArray->GetEntries(); ++iclass) { TString classStr = objArray->At(iclass)->GetName(); - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { fHistMan->AddHistClass(classStr.Data()); } // fill the THn histograms - if (fConfigIsOnlyforMaps) { + if (fConfigPostCalibTPC.fConfigIsOnlyforMaps) { if (classStr.Contains("PostCalibElectron")) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", "postcalib_electron"); } @@ -384,43 +416,42 @@ struct TableMaker { } } - TString histEventName = fConfigAddEventHistogram.value; + TString histEventName = fConfigHistOutput.fConfigAddEventHistogram.value; if (classStr.Contains("Event")) { - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "event", histEventName); } } - TString histTrackName = fConfigAddTrackHistogram.value; + TString histTrackName = fConfigHistOutput.fConfigAddTrackHistogram.value; if (classStr.Contains("Track")) { - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histTrackName); } } - TString histMuonName = fConfigAddMuonHistogram.value; + TString histMuonName = fConfigHistOutput.fConfigAddMuonHistogram.value; if (classStr.Contains("Muons")) { - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histMuonName); } } - TString histMftName = fConfigAddMuonHistogram.value; + TString histMftName = fConfigHistOutput.fConfigAddMuonHistogram.value; if (classStr.Contains("Mft")) { - if (fConfigDetailedQA) { + if (fConfigHistOutput.fConfigDetailedQA) { dqhistograms::DefineHistograms(fHistMan, objArray->At(iclass)->GetName(), "track", histMftName); } } } - // create statistics histograms - // 0: Event statistics - // 1: Track statistics - // 2: Muon statistics - // 3: Orphan track statistics - // 4: Zorro information - // 5: Zorro trigger selection - // NOTE: Please keep the order of the histograms in the list + // Create statistics histograms which will be stored in the QA output + // Event statistics: kStatsEvent + // Track statistics: kStatsTracks + // Muon statistics: kStatsMuons + // Orphan track statistics: kStatsOrphanTracks + // Zorro information: kStatsZorroInfo + // Zorro trigger selection: kStatsZorroSel fStatsList.setObject(new TList()); fStatsList->SetOwner(kTRUE); std::vector eventLabels{"BCs", "Collisions before filtering", "Before cuts", "After cuts"}; @@ -433,7 +464,7 @@ struct TableMaker { histEvents->GetYaxis()->SetBinLabel(ib, o2::aod::evsel::selectionLabels[ib - 1]); } histEvents->GetYaxis()->SetBinLabel(o2::aod::evsel::kNsel + 1, "Total"); - fStatsList->Add(histEvents); // At index 0 + fStatsList->AddAt(histEvents, kStatsEvent); // Track statistics: one bin for each track selection and 5 bins for V0 tags (gamma, K0s, Lambda, anti-Lambda, Omega) TH1D* histTracks = new TH1D("TrackStats", "Track statistics", fTrackCuts.size() + 5.0, -0.5, fTrackCuts.size() - 0.5 + 5.0); @@ -445,23 +476,25 @@ struct TableMaker { for (ib = 0; ib < 5; ib++) { histTracks->GetXaxis()->SetBinLabel(fTrackCuts.size() + 1 + ib, v0TagNames[ib]); } - fStatsList->Add(histTracks); // At index 1 + fStatsList->AddAt(histTracks, kStatsTracks); + TH1D* histMuons = new TH1D("MuonStats", "Muon statistics", fMuonCuts.size(), -0.5, fMuonCuts.size() - 0.5); ib = 1; for (auto cut = fMuonCuts.begin(); cut != fMuonCuts.end(); cut++, ib++) { histMuons->GetXaxis()->SetBinLabel(ib, (*cut).GetName()); } - fStatsList->Add(histMuons); // At index 2 + fStatsList->AddAt(histMuons, kStatsMuons); + TH1D* histOrphanTracks = new TH1D("histOrphanTracks", "Orphan Track statistics", 2, -1, 1); histOrphanTracks->GetXaxis()->SetBinLabel(1, "Track w/o collision ID"); histOrphanTracks->GetXaxis()->SetBinLabel(2, "Track with +ve collision ID"); - fStatsList->Add(histOrphanTracks); // At index 3 + fStatsList->AddAt(histOrphanTracks, kStatsOrphanTracks); TH2D* histZorroInfo = new TH2D("ZorroInfo", "Zorro information", 1, -0.5, 0.5, 1, -0.5, 0.5); - fStatsList->Add(histZorroInfo); // At index 4 + fStatsList->AddAt(histZorroInfo, kStatsZorroInfo); TH2D* histZorroSel = new TH2D("ZorroSel", "trigger of interested", 1, -0.5, 0.5, 1, -0.5, 0.5); - fStatsList->Add(histZorroSel); // At index 5 + fStatsList->AddAt(histZorroSel, kStatsZorroSel); } template @@ -469,7 +502,7 @@ struct TableMaker { TTrackAssoc const& trackAssocs, TTracks const& tracks) { // Skim collisions - // NOTE: So far, collisions are filtered based on the user specified analysis cuts and the filterPP event filter. + // NOTE: So far, collisions are filtered based on the user specified analysis cuts AND the filterPP or Zorro event filter. // The collision-track associations which point to an event that is not selected for writing are discarded! fCollIndexMap.clear(); @@ -490,10 +523,10 @@ struct TableMaker { for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(0)))->Fill(1.0, static_cast(i)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(1.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(1.0, static_cast(o2::aod::evsel::kNsel)); // apply the event filter computed by filter-PP if constexpr ((TEventFillMap & VarManager::ObjTypes::EventFilter) > 0) { @@ -536,20 +569,20 @@ struct TableMaker { // fill stats information, before selections for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(0)))->Fill(2.0, static_cast(i)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(2.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(2.0, static_cast(o2::aod::evsel::kNsel)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(2.0, static_cast(o2::aod::evsel::kNsel)); - if (fConfigRunZorro) { - zorro.setBaseCCDBPath(fConfigCcdbPathZorro.value); - zorro.initCCDB(fCCDB.service, fCurrentRun, bc.timestamp(), fConfigZorroTrigMask.value); - zorro.populateExternalHists(fCurrentRun, reinterpret_cast(fStatsList->At(4)), reinterpret_cast(fStatsList->At(5))); - bool zorroSel = zorro.isSelected(bc.globalBC(), 100UL, reinterpret_cast(fStatsList->At(5))); + if (fConfigZorro.fConfigRunZorro) { + zorro.setBaseCCDBPath(fConfigCCDB.fConfigCcdbPathZorro.value); + zorro.initCCDB(fCCDB.service, fCurrentRun, bc.timestamp(), fConfigZorro.fConfigZorroTrigMask.value); + zorro.populateExternalHists(fCurrentRun, reinterpret_cast(fStatsList->At(kStatsZorroInfo)), reinterpret_cast(fStatsList->At(kStatsZorroSel))); + bool zorroSel = zorro.isSelected(bc.globalBC(), 100UL, reinterpret_cast(fStatsList->At(kStatsZorroSel))); if (zorroSel) { tag |= (static_cast(true) << 56); // the same bit is used for this zorro selections from ccdb } - if (fConfigRunZorroSel && (!zorroSel || !fEventCut->IsSelected(VarManager::fgValues))) { + if (fConfigZorro.fConfigRunZorroSel && (!zorroSel || !fEventCut->IsSelected(VarManager::fgValues))) { continue; } } else { @@ -561,10 +594,10 @@ struct TableMaker { // fill stats information, after selections for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (collision.selection_bit(i)) { - (reinterpret_cast(fStatsList->At(0)))->Fill(3.0, static_cast(i)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(3.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(3.0, static_cast(o2::aod::evsel::kNsel)); fHistMan->FillHistClass("Event_AfterCuts", VarManager::fgValues); @@ -621,22 +654,23 @@ struct TableMaker { // Tracks are written only once, even if they constribute to more than one association uint64_t trackFilteringTag = static_cast(0); - uint64_t trackTempFilterMap = uint8_t(0); + uint32_t trackTempFilterMap = static_cast(0); // material correction for track propagation + // TODO: Do we need a configurable to switch between different material correction options? // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; for (const auto& assoc : assocs) { - // get track + // get the track auto track = assoc.template track_as(); trackFilteringTag = static_cast(0); - trackTempFilterMap = uint8_t(0); + trackTempFilterMap = static_cast(0); VarManager::FillTrack(track); // compute quantities which depend on the associated collision, such as DCA - if (fPropTrack && (track.collisionId() != collision.globalIndex())) { + if (fConfigVariousOptions.fPropTrack && (track.collisionId() != collision.globalIndex())) { VarManager::FillTrackCollisionMatCorr(track, collision, noMatCorr, o2::base::Propagator::Instance()); } @@ -648,13 +682,13 @@ struct TableMaker { int i = 0; for (auto cut = fTrackCuts.begin(); cut != fTrackCuts.end(); cut++, i++) { if ((*cut).IsSelected(VarManager::fgValues)) { - trackTempFilterMap |= (uint8_t(1) << i); - // NOTE: the QA is filled here for every (collision,track) association since the results of the track cuts can be different depending on which collision is associated (e.g. DCA cuts) - // TODO: create a statistics histograms with unique tracks - if (fConfigQA) { + trackTempFilterMap |= (static_cast(1) << i); + // NOTE: the QA is filled here just for the first occurence of this track. + // So if there are histograms of quantities which depend on the collision association, these will not be accurate + if (fConfigHistOutput.fConfigQA && (fTrackIndexMap.find(track.globalIndex()) == fTrackIndexMap.end())) { fHistMan->FillHistClass(Form("TrackBarrel_%s", (*cut).GetName()), VarManager::fgValues); } - (reinterpret_cast(fStatsList->At(1)))->Fill(static_cast(i)); + (reinterpret_cast(fStatsList->At(kStatsTracks)))->Fill(static_cast(i)); } } if (!trackTempFilterMap) { @@ -666,10 +700,10 @@ struct TableMaker { trackFilteringTag |= static_cast(track.pidbit()); for (int iv0 = 0; iv0 < 5; iv0++) { if (track.pidbit() & (uint8_t(1) << iv0)) { - (reinterpret_cast(fStatsList->At(1)))->Fill(fTrackCuts.size() + static_cast(iv0)); + (reinterpret_cast(fStatsList->At(kStatsTracks)))->Fill(fTrackCuts.size() + static_cast(iv0)); } } - if (fConfigIsOnlyforMaps) { + if (fConfigPostCalibTPC.fConfigIsOnlyforMaps) { if (trackFilteringTag & (static_cast(1) << VarManager::kIsConversionLeg)) { // for electron fHistMan->FillHistClass("TrackBarrel_PostCalibElectron", VarManager::fgValues); } @@ -683,7 +717,7 @@ struct TableMaker { fHistMan->FillHistClass("TrackBarrel_PostCalibProton", VarManager::fgValues); } } - if (fConfigSaveElectronSample) { // only save electron sample + if (fConfigPostCalibTPC.fConfigSaveElectronSample) { // only save electron sample if (!(trackFilteringTag & (static_cast(1) << VarManager::kIsConversionLeg))) { continue; } @@ -695,25 +729,28 @@ struct TableMaker { trackFilteringTag |= (static_cast(trackTempFilterMap) << VarManager::kBarrelUserCutsBits); // BIT13-...: user track filters if constexpr (static_cast(TTrackFillMap & VarManager::ObjTypes::TrackPID)) { - if (fConfigComputeTPCpostCalib) { + if (fConfigPostCalibTPC.fConfigComputeTPCpostCalib) { trackFilteringTag |= (static_cast(1) << VarManager::kIsTPCPostcalibrated); } } // write the track global index in the map for skimming (to make sure we have it just once) if (fTrackIndexMap.find(track.globalIndex()) == fTrackIndexMap.end()) { - // NOTE: The collision ID that is written in the table is the one found in the first association for this track. - // However, in data analysis one should loop over associations, so this one should not be used. - // In the case of Run2-like analysis, there will be no associations, so this ID will be the one originally assigned in the AO2Ds (updated for the skims) - // reducedEventIdx = fCollIndexMap[collision.globalIndex()]; // This gives the first collision form the table // Calculating the percentage of orphan tracks i.e., tracks which have no collisions associated to it if (!track.has_collision()) { - (reinterpret_cast(fStatsList->At(3)))->Fill(static_cast(-1)); + (reinterpret_cast(fStatsList->At(kStatsOrphanTracks)))->Fill(static_cast(-1)); } else { - (reinterpret_cast(fStatsList->At(3)))->Fill(0.9); + (reinterpret_cast(fStatsList->At(kStatsOrphanTracks)))->Fill(0.9); } - // Protection against crash, where the original collision IDs of tracks were removed by pp-filter or zorro selection and hence the track is now orphaned + // NOTE: The collision ID written in the table is the one of the original collision assigned in the AO2D. + // The reason is that the time associated to the track is wrt that collision. + // If new associations are done with the skimmed data, the track time wrt new collision can then be recomputed based on the + // relative difference in time between the original and the new collision. + + // If the original collision of this track was not selected for skimming, then we skip this track. + // Normally, the filter-pp is selecting all collisions which contain the tracks which contributed to the triggering + // of an event, so this is rejecting possibly a few tracks originally associated with collisions distant in time. if (fCollIndexMap.find(track.collisionId()) == fCollIndexMap.end()) { continue; } @@ -736,10 +773,10 @@ struct TableMaker { track.c1PtY(), track.c1PtZ(), track.c1PtSnp(), track.c1PtTgl(), track.c1Pt21Pt2()); } if constexpr (static_cast(TTrackFillMap & VarManager::ObjTypes::TrackPID)) { - float nSigmaEl = (fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaEl_Corr] : track.tpcNSigmaEl()); - float nSigmaPi = (fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPi_Corr] : track.tpcNSigmaPi()); - float nSigmaKa = ((fConfigComputeTPCpostCalib && fConfigComputeTPCpostCalibKaon) ? VarManager::fgValues[VarManager::kTPCnSigmaKa_Corr] : track.tpcNSigmaKa()); - float nSigmaPr = (fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPr_Corr] : track.tpcNSigmaPr()); + float nSigmaEl = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaEl_Corr] : track.tpcNSigmaEl()); + float nSigmaPi = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPi_Corr] : track.tpcNSigmaPi()); + float nSigmaKa = ((fConfigPostCalibTPC.fConfigComputeTPCpostCalib && fConfigPostCalibTPC.fConfigComputeTPCpostCalibKaon) ? VarManager::fgValues[VarManager::kTPCnSigmaKa_Corr] : track.tpcNSigmaKa()); + float nSigmaPr = (fConfigPostCalibTPC.fConfigComputeTPCpostCalib ? VarManager::fgValues[VarManager::kTPCnSigmaPr_Corr] : track.tpcNSigmaPr()); trackBarrelPID(track.tpcSignal(), nSigmaEl, track.tpcNSigmaMu(), nSigmaPi, nSigmaKa, nSigmaPr, track.beta(), track.tofNSigmaEl(), track.tofNSigmaMu(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), @@ -761,7 +798,7 @@ struct TableMaker { for (const auto& assoc : mftAssocs) { auto track = assoc.template mfttrack_as(); - if (fConfigQA) { + if (fConfigHistOutput.fConfigQA) { VarManager::FillTrack(track); fHistMan->FillHistClass("MftTracks", VarManager::fgValues); } @@ -787,8 +824,10 @@ struct TableMaker { // Muons are written only once, even if they constribute to more than one association, // which means that in the case of multiple associations, the track parameters are wrong and should be computed again at analysis time. - uint8_t trackFilteringTag = uint8_t(0); - uint8_t trackTempFilterMap = uint8_t(0); + // TODO: Currently, the TMFTFillMap is not used in this function. Is it needed ? + + uint8_t trackFilteringTag = static_cast(0); + uint8_t trackTempFilterMap = static_cast(0); fFwdTrackIndexMapReversed.clear(); uint32_t offset = muonBasic.lastIndex(); @@ -797,22 +836,25 @@ struct TableMaker { // get the muon auto muon = assoc.template fwdtrack_as(); - trackFilteringTag = uint8_t(0); - trackTempFilterMap = uint8_t(0); + trackFilteringTag = static_cast(0); + trackTempFilterMap = static_cast(0); VarManager::FillTrack(muon); - // NOTE: If a muon is associated to multiple collisions, depending on the selections, + // NOTE: Muons are propagated to the current associated collisions. + // So if a muon is associated to multiple collisions, depending on the selections, // it may be accepted for some associations and rejected for other - if (fPropMuon) { + if (fConfigVariousOptions.fPropMuon) { VarManager::FillPropagateMuon(muon, collision); } - // recalculte pDca and global muon kinematics - if (static_cast(muon.trackType()) < 2 && fRefitGlobalMuon) { + // recalculate pDca and global muon kinematics + if (static_cast(muon.trackType()) < 2 && fConfigVariousOptions.fRefitGlobalMuon) { auto muontrack = muon.template matchMCHTrack_as(); - if (muontrack.eta() < fMuonMatchEtaMin || muontrack.eta() > fMuonMatchEtaMax) { + if (muontrack.eta() < fConfigVariousOptions.fMuonMatchEtaMin || muontrack.eta() > fConfigVariousOptions.fMuonMatchEtaMax) { continue; } - auto mfttrack = muon.template matchMFTTrack_as(); VarManager::FillTrackCollision(muontrack, collision); + // NOTE: the MFT track originally associated to the MUON track is currently used in the global muon refit + // Should MUON - MFT time ambiguities be taken into account ? + auto mfttrack = muon.template matchMFTTrack_as(); VarManager::FillGlobalMuonRefit(muontrack, mfttrack, collision); } else { VarManager::FillTrackCollision(muon, collision); @@ -825,11 +867,14 @@ struct TableMaker { int i = 0; for (auto cut = fMuonCuts.begin(); cut != fMuonCuts.end(); cut++, i++) { if ((*cut).IsSelected(VarManager::fgValues)) { - trackTempFilterMap |= (uint8_t(1) << i); - if (fConfigQA) { + trackTempFilterMap |= (static_cast(1) << i); + // NOTE: the QA is filled here just for the first occurence of this muon, which means the current association + // will be skipped from histograms if this muon was already filled in the skimming map. + // So if there are histograms of quantities which depend on the collision association, these histograms will not be completely accurate + if (fConfigHistOutput.fConfigQA && (fFwdTrackIndexMap.find(muon.globalIndex()) == fFwdTrackIndexMap.end())) { fHistMan->FillHistClass(Form("Muons_%s", (*cut).GetName()), VarManager::fgValues); } - (reinterpret_cast(fStatsList->At(2)))->Fill(static_cast(i)); + (reinterpret_cast(fStatsList->At(kStatsMuons)))->Fill(static_cast(i)); } } @@ -864,13 +909,13 @@ struct TableMaker { // get the muon auto muon = muons.rawIteratorAt(origIdx); uint32_t reducedEventIdx = fCollIndexMap[collision.globalIndex()]; - // NOTE: Currently, one writes the original AO2D momentum-vector (pt, eta and phi) in the tables because we write only one instance of the muon track, - // while multiple collision associations (and multiple mom vectors can exist) + // NOTE: Currently, one writes in the tables the momentum-vector (pt, eta and phi) of the first collision association for this muon, + // while multiple collision associations (and multiple mom vectors can exist). // The momentum can be recomputed at the analysis time based on the associations written in the skims // So all the information which pertains to collision association or MFT associations should not be taken from the skimmed data, but recomputed at analysis time. uint32_t mchIdx = -1; uint32_t mftIdx = -1; - if (muon.trackType() == uint8_t(0) || muon.trackType() == uint8_t(2)) { // MCH-MID (2) or global (0) + if (muon.trackType() == static_cast(0) || muon.trackType() == static_cast(2)) { // MCH-MID (2) or global (0) if (fFwdTrackIndexMap.find(muon.matchMCHTrackId()) != fFwdTrackIndexMap.end()) { mchIdx = fFwdTrackIndexMap[muon.matchMCHTrackId()]; } @@ -879,11 +924,11 @@ struct TableMaker { } } VarManager::FillTrack(muon); - if (fPropMuon) { + if (fConfigVariousOptions.fPropMuon) { VarManager::FillPropagateMuon(muon, collision); } // recalculte pDca and global muon kinematics - if (static_cast(muon.trackType()) < 2 && fRefitGlobalMuon) { + if (static_cast(muon.trackType()) < 2 && fConfigVariousOptions.fRefitGlobalMuon) { auto muontrack = muon.template matchMCHTrack_as(); auto mfttrack = muon.template matchMFTTrack_as(); VarManager::FillTrackCollision(muontrack, collision); @@ -918,28 +963,28 @@ struct TableMaker { { if (bcs.size() > 0 && fCurrentRun != bcs.begin().runNumber()) { - if (fConfigComputeTPCpostCalib) { - auto calibList = fCCDB->getForTimeStamp(fConfigCcdbPathTPC.value, bcs.begin().timestamp()); + if (fConfigPostCalibTPC.fConfigComputeTPCpostCalib) { + auto calibList = fCCDB->getForTimeStamp(fConfigCCDB.fConfigCcdbPathTPC.value, bcs.begin().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) { + if (fConfigPostCalibTPC.fConfigComputeTPCpostCalibKaon) { VarManager::SetCalibrationObject(VarManager::kTPCKaonMean, calibList->FindObject("mean_map_kaon")); VarManager::SetCalibrationObject(VarManager::kTPCKaonSigma, calibList->FindObject("sigma_map_kaon")); } } if (fIsRun2 == true) { - grpmagrun2 = ccdb->getForTimeStamp(grpmagPathRun2, bcs.begin().timestamp()); - if (grpmagrun2 != nullptr) { - o2::base::Propagator::initFieldFromGRP(grpmagrun2); + fGrpMagRun2 = fCCDB->getForTimeStamp(fConfigCCDB.fConfigGrpMagPathRun2, bcs.begin().timestamp()); + if (fGrpMagRun2 != nullptr) { + o2::base::Propagator::initFieldFromGRP(fGrpMagRun2); } } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, bcs.begin().timestamp()); - if (grpmag != nullptr) { - o2::base::Propagator::initFieldFromGRP(grpmag); + fGrpMag = fCCDB->getForTimeStamp(fConfigCCDB.fConfigGrpMagPath, bcs.begin().timestamp()); + if (fGrpMag != nullptr) { + o2::base::Propagator::initFieldFromGRP(fGrpMag); } } std::map metadataRCT, header; @@ -949,7 +994,7 @@ struct TableMaker { VarManager::SetSORandEOR(sor, eor); fCurrentRun = bcs.begin().runNumber(); - } + } // end updating the CCDB quantities at change of run // skim collisions event.reserve(collisions.size()); @@ -988,18 +1033,20 @@ struct TableMaker { muonAssoc.reserve(muons.size()); } - // loop over selected collisions and select the tracks and fwd tracks to be skimmed + // loop over selected collisions, group the compatible associations, and run the skimming for (auto const& [origIdx, skimIdx] : fCollIndexMap) { auto collision = collisions.rawIteratorAt(origIdx); - // group the tracks and muons for this collision + // group the barrel track associations for this collision if constexpr (static_cast(TTrackFillMap)) { auto groupedTrackIndices = trackAssocs.sliceBy(trackIndicesPerCollision, origIdx); skimTracks(collision, bcs, tracksBarrel, groupedTrackIndices); } + // group the MFT associations for this collision if constexpr (static_cast(TMFTFillMap)) { auto groupedMFTIndices = mftAssocs.sliceBy(mfttrackIndicesPerCollision, origIdx); skimMFT(collision, bcs, mftTracks, groupedMFTIndices); } + // group the muon associations for this collision if constexpr (static_cast(TMuonFillMap)) { if constexpr (static_cast(TMFTFillMap)) { auto groupedMuonIndices = fwdTrackAssocs.sliceBy(fwdtrackIndicesPerCollision, origIdx); @@ -1010,6 +1057,10 @@ struct TableMaker { } } } // end loop over skimmed collisions + + LOG(info) << "Skims in this TF: " << fCollIndexMap.size() << " collisions; " << trackBasic.lastIndex() << " barrel tracks; " + << muonBasic.lastIndex() << " muon tracks; " << mftTrack.lastIndex() << " MFT tracks; "; + LOG(info) << " " << trackBarrelAssoc.lastIndex() << " barrel assocs; " << muonAssoc.lastIndex() << " muon assocs; " << mftAssoc.lastIndex() << " MFT assoc"; } // produce the full DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), subscribe to the DQ event filter (filter-pp or filter-PbPb) @@ -1027,10 +1078,6 @@ struct TableMaker { MyBarrelTracksWithCov const& tracksBarrel, TrackAssoc const& trackAssocs) { - /*const int& a = 0; - MFTTracks const& mftTracks = 0; - FwdTrackAssoc const& fwdTrackAssocs = 0; - MFTTrackAssoc const& mftAssocs = 0;*/ fullSkimming(collisions, bcs, zdcs, tracksBarrel, nullptr, nullptr, trackAssocs, nullptr, nullptr); } @@ -1059,7 +1106,7 @@ struct TableMaker { // produce the muon-only DQ skimmed data model typically for pp/p-Pb or UPC Pb-Pb (no centrality), meant to run on skimmed data void processPPMuonOnly(MyEventsWithMults const& collisions, BCsWithTimestamps const& bcs, - MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs, MFTTracks const& /*mftTracks*/) + MyMuonsWithCov const& muons, FwdTrackAssoc const& fwdTrackAssocs) { fullSkimming(collisions, bcs, nullptr, nullptr, muons, nullptr, nullptr, fwdTrackAssocs, nullptr); } @@ -1118,10 +1165,10 @@ struct TableMaker { { for (int i = 0; i < o2::aod::evsel::kNsel; i++) { if (bc.selection_bit(i) > 0) { - (reinterpret_cast(fStatsList->At(0)))->Fill(0.0, static_cast(i)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(0.0, static_cast(i)); } } - (reinterpret_cast(fStatsList->At(0)))->Fill(0.0, static_cast(o2::aod::evsel::kNsel)); + (reinterpret_cast(fStatsList->At(kStatsEvent)))->Fill(0.0, static_cast(o2::aod::evsel::kNsel)); } PROCESS_SWITCH(TableMaker, processPPWithFilter, "Build full DQ skimmed data model typically for pp/p-Pb and UPC Pb-Pb, w/ event filtering", false); diff --git a/PWGDQ/Tasks/CMakeLists.txt b/PWGDQ/Tasks/CMakeLists.txt index 8807aad7200..3d7f53faeba 100644 --- a/PWGDQ/Tasks/CMakeLists.txt +++ b/PWGDQ/Tasks/CMakeLists.txt @@ -107,4 +107,9 @@ o2physics_add_dpl_workflow(task-muon-mid-eff o2physics_add_dpl_workflow(task-fwd-track-pid SOURCES taskFwdTrackPid.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(quarkonia-to-hyperons + SOURCES quarkoniaToHyperons.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGDQ/Tasks/dqCorrelation.cxx b/PWGDQ/Tasks/dqCorrelation.cxx index 353a7fbf575..d2fa3a0dd4b 100644 --- a/PWGDQ/Tasks/dqCorrelation.cxx +++ b/PWGDQ/Tasks/dqCorrelation.cxx @@ -116,7 +116,7 @@ struct DqCumulantFlow { ConfigurableAxis axisEta{"axisEta", {40, -6.0, 1.5}, "eta axis for histograms"}; ConfigurableAxis axisPt{"axisPt", {100, 0, 20}, "pt axis for histograms"}; ConfigurableAxis axisMass{"axisMass", {40, 2, 4}, "mass axis for histograms"}; - Configurable fConfigNPow{"cfgNPow", 0, "Power of weights for Q vector"}; + Configurable fConfigNPow{"cfgNPow", 0, "Power of weights for Q vector"}; // Configurables for the reference flow Configurable fConfigTrackCuts{"cfgLeptonCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable fConfigCutPtMin{"cfgCutPtMin", 1.0f, "Minimal pT for tracks"}; diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 03faa87837e..82f7d64569b 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -538,8 +538,8 @@ struct AnalysisTrackSelection { } } } // end loop over cuts - } // end loop over MC signals - } // end if (filterMap > 0) + } // end loop over MC signals + } // end if (filterMap > 0) // count the number of associations per track if (filterMap > 0) { @@ -811,7 +811,7 @@ struct AnalysisMuonSelection { } } } // end loop over cuts - } // end loop over MC signals + } // end loop over MC signals // count the number of associations per track if (event.isEventSelected_bit(1)) { @@ -1236,7 +1236,7 @@ struct AnalysisSameEventPairing { // NOTE: In the numbering scheme for the map key, we use the number of barrel cuts in the barrel-track selection task fTrackHistNames[fNCutsBarrel + icut * fNPairCuts + iPairCut] = names; } // end loop (pair cuts) - } // end if (pair cuts) + } // end if (pair cuts) // assign hist directories for the MC matched pairs for each (track cut,MCsignal) combination if (!sigNamesStr.IsNull()) { @@ -1314,7 +1314,7 @@ struct AnalysisSameEventPairing { histNames += Form("%s;%s;%s;", names[0].Data(), names[1].Data(), names[2].Data()); fMuonHistNames[fNCutsMuon + icut * fNCutsMuon + iPairCut] = names; } // end loop (pair cuts) - } // end if (pair cuts) + } // end if (pair cuts) // assign hist directories for pairs matched to MC signals for each (muon cut, MCrec signal) combination if (!sigNamesStr.IsNull()) { @@ -1343,7 +1343,7 @@ struct AnalysisSameEventPairing { } } } // end loop over cuts - } // end if (muonCutsStr) + } // end if (muonCutsStr) // Add histogram classes for each specified MCsignal at the generator level // TODO: create a std::vector of hist classes to be used at Fill time, to avoid using Form in the process function @@ -1739,8 +1739,8 @@ struct AnalysisSameEventPairing { } // end loop (pair cuts) } } // end loop (cuts) - } // end loop over pairs of track associations - } // end loop over events + } // end loop over pairs of track associations + } // end loop over events } // Preslice perReducedMcEvent = aod::reducedtrackMC::reducedMCeventId; @@ -1789,8 +1789,8 @@ struct AnalysisSameEventPairing { fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig.GetName()), VarManager::fgValues); } } // end loop over MC signals - } // end loop over pairs - } // end loop over events + } // end loop over pairs + } // end loop over events } } // end runMCGen @@ -1954,6 +1954,12 @@ struct AnalysisDileptonTrack { if (objArraySingleCuts->FindObject(fConfigTrackCut.value.data()) == nullptr) { LOG(fatal) << " Track cut chosen for the correlation task was not computed in the single-track task! Check it out!"; } + for (int icut = 0; icut < objArraySingleCuts->GetEntries(); ++icut) { + TString tempStr = objArraySingleCuts->At(icut)->GetName(); + if (tempStr.CompareTo(fConfigTrackCut.value.data()) == 0) { + fTrackCutBit = icut; // the bit corresponding to the track to be combined with dileptons + } + } // get the cuts employed for same-event pairing string tempCutsPair; if (isBarrel) { @@ -1965,8 +1971,8 @@ struct AnalysisDileptonTrack { if (!tempCutsSingleStr.IsNull() && !tempCutsPairStr.IsNull()) { std::unique_ptr objArray(tempCutsPairStr.Tokenize(",")); fNCuts = objArray->GetEntries(); - for (int icut = 0; icut < objArraySingleCuts->GetEntries(); ++icut) { - TString tempStr = objArraySingleCuts->At(icut)->GetName(); + for (int icut = 0; icut < objArray->GetEntries(); ++icut) { + TString tempStr = objArray->At(icut)->GetName(); if (objArray->FindObject(tempStr.Data()) != nullptr) { fHistNamesDileptonTrack[icut] = Form("DileptonTrack_%s_%s", tempStr.Data(), fConfigTrackCut.value.data()); fHistNamesDileptons[icut] = Form("DileptonsSelected_%s", tempStr.Data()); @@ -1975,13 +1981,10 @@ struct AnalysisDileptonTrack { std::vector mcHistNames; for (auto& sig : fRecMCSignals) { mcHistNames.push_back(Form("DileptonTrackMCMatched_%s_%s_%s", tempStr.Data(), fConfigTrackCut.value.data(), sig.GetName())); - DefineHistograms(fHistMan, mcHistNames[mcHistNames.size() - 1], ""); + DefineHistograms(fHistMan, mcHistNames[mcHistNames.size() - 1], fConfigHistogramSubgroups.value.data()); } fHistNamesDileptonTrackMCmatched[icut] = mcHistNames; } - if (tempStr.CompareTo(fConfigTrackCut.value.data()) == 0) { - fTrackCutBit = icut; // the bit corresponding to the track to be combined with dileptons - } } } // Add histogram classes for each specified MCsignal at the generator level diff --git a/PWGDQ/Tasks/dqFlow.cxx b/PWGDQ/Tasks/dqFlow.cxx index 36293babf41..b29efd014b8 100644 --- a/PWGDQ/Tasks/dqFlow.cxx +++ b/PWGDQ/Tasks/dqFlow.cxx @@ -117,7 +117,7 @@ struct DQEventQvector { Configurable fConfigCutTPCNClMin{"cfgCutTPCNclMin", 0, "Min requirement for number of TPC clusters"}; Configurable fConfigEtaLimitMin{"cfgEtaLimitMin", -0.4f, "Eta gap min separation, only if using subEvents"}; Configurable fConfigEtaLimitMax{"cfgEtaLimitMax", 0.4f, "Eta gap max separation, only if using subEvents"}; - // Configurable fConfigNPow{"cfgNPow", 0, "Power of weights for Q vector"}; + // Configurable fConfigNPow{"cfgNPow", 0, "Power of weights for Q vector"}; // Configurable cfgGFWBinning{"cfgGFWBinning", {40, 16, 72, 300, 0, 3000, 0.2, 10.0, 0.2, 3.0, {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}}, "Configuration for binning"}; // Access to the efficiencies and acceptances from CCDB diff --git a/PWGDQ/Tasks/quarkoniaToHyperons.cxx b/PWGDQ/Tasks/quarkoniaToHyperons.cxx new file mode 100644 index 00000000000..62ba3f9c9d8 --- /dev/null +++ b/PWGDQ/Tasks/quarkoniaToHyperons.cxx @@ -0,0 +1,2004 @@ +// 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 "CommonConstants/PhysicsConstants.h" +#include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessMLTables.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 "PWGUD/Core/SGSelector.h" +#include "Tools/ML/MlResponse.h" +#include "Tools/ML/model.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; + +using dauTracks = soa::Join; +using dauMCTracks = soa::Join; +using v0Candidates = soa::Join; +// using v0MCCandidates = soa::Join; +using v0MCCandidates = soa::Join; + +using cascadeCandidates = soa::Join; +using cascadeMCCandidates = soa::Join; + +// simple checkers, but ensure 64 bit integers +#define bitset(var, nbit) ((var) |= (static_cast(1) << static_cast(nbit))) +#define bitcheck(var, nbit) ((var) & (static_cast(1) << static_cast(nbit))) + +struct quarkoniaToHyperons { + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // master analysis switches + Configurable isPP{"isPP", true, "If running on pp collision, switch it on true"}; + + Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + + Configurable buildLaLaBarPairs{"buildLaLaBarPairs", false, "Build Lambda antiLambda from charmonia decay"}; + Configurable buildXiXiBarPairs{"buildXiXiBarPairs", false, "Build Xi antiXi from charmonia decay"}; + Configurable buildOmOmBarPairs{"buildOmOmBarPairs", false, "Build Omega antiOmega from charmonia decay"}; + + // fast check on occupancy + Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + + // rapidity cut on the hyperon-antiHyperon pair + Configurable rapidityCut{"rapidityCut", 0.5, "rapidity cut on the hyp-antiHyp pair"}; + + struct : ConfigurableGroup { + Configurable v0TypeSelection{"v0Selections.v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; + + // Selection criteria: acceptance + Configurable rapidityCut{"v0Selections.rapidityCut", 0.5, "rapidity"}; + Configurable daughterEtaCut{"v0Selections.daughterEtaCut", 0.8, "max eta for daughters"}; + + // Standard 6 topological criteria + Configurable v0cospa{"v0Selections.v0cospa", 0.97, "min V0 CosPA"}; + Configurable dcav0dau{"v0Selections.dcav0dau", 1.0, "max DCA V0 Daughters (cm)"}; + Configurable dcav0topv{"v0Selections.dcav0topv", .05, "min DCA V0 to PV (cm)"}; + Configurable dcapiontopv{"v0Selections.dcapiontopv", .05, "min DCA Pion To PV (cm)"}; + Configurable dcaprotontopv{"v0Selections.dcaprotontopv", .05, "min DCA Proton To PV (cm)"}; + Configurable v0radius{"v0Selections.v0radius", 1.2, "minimum V0 radius (cm)"}; + Configurable v0radiusMax{"v0Selections.v0radiusMax", 1E5, "maximum V0 radius (cm)"}; + + // invariant mass selection + Configurable v0MassWindow{"v0Selections.v0MassWindow", 0.008, "#Lambda mass (GeV/#it{c}^{2})"}; + Configurable compMassRejection{"v0Selections.compMassRejection", 0.008, "Competing mass rejection (GeV/#it{c}^{2})"}; + + // Additional selection on the AP plot (exclusive for K0Short) + // original equation: lArmPt*5>TMath::Abs(lArmAlpha) + Configurable armPodCut{"v0Selections.armPodCut", 5.0f, "pT * (cut) > |alpha|, AP cut. Negative: no cut"}; + + // Track quality + Configurable minTPCrows{"v0Selections.minTPCrows", 70, "minimum TPC crossed rows"}; + Configurable minITSclusters{"v0Selections.minITSclusters", -1, "minimum ITS clusters"}; + Configurable skipTPConly{"v0Selections.skipTPConly", false, "skip V0s comprised of at least one TPC only prong"}; + Configurable requirePosITSonly{"v0Selections.requirePosITSonly", false, "require that positive track is ITSonly (overrides TPC quality)"}; + Configurable requireNegITSonly{"v0Selections.requireNegITSonly", false, "require that negative track is ITSonly (overrides TPC quality)"}; + + // PID (TPC/TOF) + Configurable TpcPidNsigmaCut{"v0Selections.TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; + Configurable TofPidNsigmaCutLaPr{"v0Selections.TofPidNsigmaCutLaPr", 1e+6, "TofPidNsigmaCutLaPr"}; + Configurable TofPidNsigmaCutLaPi{"v0Selections.TofPidNsigmaCutLaPi", 1e+6, "TofPidNsigmaCutLaPi"}; + Configurable TofPidNsigmaCutK0Pi{"v0Selections.TofPidNsigmaCutK0Pi", 1e+6, "TofPidNsigmaCutK0Pi"}; + + // PID (TOF) + Configurable maxDeltaTimeProton{"v0Selections.maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimePion{"v0Selections.maxDeltaTimePion", 1e+9, "check maximum allowed time"}; + } v0Selections; + + struct : ConfigurableGroup { + // Selection criteria: acceptance + Configurable rapidityCut{"cascSelections.rapidityCut", 0.5, "rapidity"}; + Configurable daughterEtaCut{"cascSelections.daughterEtaCut", 0.8, "max eta for daughters"}; + + // Standard 6 topological criteria on V0 + Configurable v0cospa{"cascSelections.v0cospa", 0.97, "min V0 CosPA"}; + Configurable dcav0dau{"cascSelections.dcav0dau", 1.0, "max DCA V0 Daughters (cm)"}; + Configurable dcav0topv{"cascSelections.dcav0topv", .05, "min DCA V0 to PV (cm)"}; + Configurable dcapiontopv{"cascSelections.dcapiontopv", .05, "min DCA Pion To PV (cm)"}; + Configurable dcaprotontopv{"cascSelections.dcaprotontopv", .05, "min DCA Proton To PV (cm)"}; + Configurable v0radius{"cascSelections.v0radius", 1.2, "minimum V0 radius (cm)"}; + Configurable v0radiusMax{"cascSelections.v0radiusMax", 1E5, "maximum V0 radius (cm)"}; + + // Standard 6 topological criteria on cascades + Configurable casccospa{"cascSelections.casccospa", 0.97, "min Cascade CosPA"}; + Configurable dcacascdau{"cascSelections.dcacascdau", 1.0, "max DCA Cascade Daughters (cm)"}; + Configurable dcaxybachbaryontopv{"cascSelections.dcaxybachbaryontopv", -1, "DCAxy Bachelor-Baryon to PV (cm)"}; + Configurable bachbaryoncospa{"cascSelections.bachbaryoncospa", -1, "Bachelor-Baryon CosPA"}; + Configurable dcabachtopv{"cascSelections.dcabachtopv", .05, "min DCA Bachelor To PV (cm)"}; + Configurable cascradius{"cascSelections.cascradius", 0.5, "minimum Cascade radius (cm)"}; + Configurable cascradiusMax{"cascSelections.cascradiusMax", 1E5, "maximum Cascade radius (cm)"}; + Configurable cascProperLifeTime{"cascSelections.cascProperLifeTime", 3, "maximum lifetime (ctau)"}; + + // invariant mass selection + Configurable v0MassWindow{"cascSelections.v0MassWindow", 0.008, "#Lambda mass (GeV/#it{c}^{2})"}; + Configurable cascMassWindow{"cascSelections.cascMassWindow", 0.008, "#Lambda mass (GeV/#it{c}^{2})"}; + Configurable compMassRejection{"cascSelections.compMassRejection", 0.008, "Competing mass rejection (GeV/#it{c}^{2})"}; + + // Track quality + Configurable minTPCrows{"cascSelections.minTPCrows", 70, "minimum TPC crossed rows"}; + Configurable minITSclusters{"cascSelections.minITSclusters", -1, "minimum ITS clusters"}; + Configurable skipTPConly{"cascSelections.skipTPConly", false, "skip V0s comprised of at least one TPC only prong"}; + Configurable requireBachITSonly{"cascSelections.requireBachITSonly", false, "require that bachelor track is ITSonly (overrides TPC quality)"}; + Configurable requirePosITSonly{"cascSelections.requirePosITSonly", false, "require that positive track is ITSonly (overrides TPC quality)"}; + Configurable requireNegITSonly{"cascSelections.requireNegITSonly", false, "require that negative track is ITSonly (overrides TPC quality)"}; + + // PID (TPC/TOF) + Configurable TpcPidNsigmaCut{"cascSelections.TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; + Configurable TofPidNsigmaCutLaPr{"cascSelections.TofPidNsigmaCutLaPr", 1e+6, "TofPidNsigmaCutLaPr"}; + Configurable TofPidNsigmaCutLaPi{"cascSelections.TofPidNsigmaCutLaPi", 1e+6, "TofPidNsigmaCutLaPi"}; + Configurable TofPidNsigmaCutXiPi{"cascSelections.TofPidNsigmaCutXiPi", 1e+6, "TofPidNsigmaCutXiPi"}; + Configurable TofPidNsigmaCutOmKa{"cascSelections.TofPidNsigmaCutOmKa", 1e+6, "TofPidNsigmaCutOmKa"}; + + // PID (TOF) + Configurable maxDeltaTimeProton{"cascSelections.maxDeltaTimeProton", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimePion{"cascSelections.maxDeltaTimePion", 1e+9, "check maximum allowed time"}; + Configurable maxDeltaTimeKaon{"cascSelections.maxDeltaTimeKaon", 1e+9, "check maximum allowed time"}; + } cascSelections; + + Configurable qaCentrality{"qaCentrality", false, "qa centrality flag: check base raw values"}; + + // for MC + Configurable doMCAssociation{"doMCAssociation", true, "if MC, do MC association"}; + + // UPC selections + SGSelector sgSelector; + struct : ConfigurableGroup { + Configurable FV0cut{"upcCuts.FV0cut", 100., "FV0A threshold"}; + Configurable FT0Acut{"upcCuts.FT0Acut", 200., "FT0A threshold"}; + Configurable FT0Ccut{"upcCuts.FT0Ccut", 100., "FT0C threshold"}; + Configurable ZDCcut{"upcCuts.ZDCcut", 10., "ZDC threshold"}; + // Configurable gapSel{"upcCuts.gapSel", 2, "Gap selection"}; + } upcCuts; + + // Machine learning evaluation for pre-selection and corresponding information generation + o2::ml::OnnxModel mlCustomModelK0Short; + o2::ml::OnnxModel mlCustomModelLambda; + o2::ml::OnnxModel mlCustomModelAntiLambda; + o2::ml::OnnxModel mlCustomModelGamma; + + struct : ConfigurableGroup { + // ML classifiers: master flags to control whether we should use custom ML classifiers or the scores in the derived data + Configurable useK0ShortScores{"mlConfigurations.useK0ShortScores", false, "use ML scores to select K0Short"}; + Configurable useLambdaScores{"mlConfigurations.useLambdaScores", false, "use ML scores to select Lambda"}; + Configurable useAntiLambdaScores{"mlConfigurations.useAntiLambdaScores", false, "use ML scores to select AntiLambda"}; + + Configurable calculateK0ShortScores{"mlConfigurations.calculateK0ShortScores", false, "calculate K0Short ML scores"}; + Configurable calculateLambdaScores{"mlConfigurations.calculateLambdaScores", false, "calculate Lambda ML scores"}; + Configurable calculateAntiLambdaScores{"mlConfigurations.calculateAntiLambdaScores", false, "calculate AntiLambda ML scores"}; + + // ML input for ML calculation + Configurable customModelPathCCDB{"mlConfigurations.customModelPathCCDB", "", "Custom ML Model path in CCDB"}; + Configurable timestampCCDB{"mlConfigurations.timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + Configurable loadCustomModelsFromCCDB{"mlConfigurations.loadCustomModelsFromCCDB", false, "Flag to enable or disable the loading of custom models from CCDB"}; + Configurable enableOptimizations{"mlConfigurations.enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; + + // Local paths for test purposes + Configurable localModelPathLambda{"mlConfigurations.localModelPathLambda", "Lambda_BDTModel.onnx", "(std::string) Path to the local .onnx file."}; + Configurable localModelPathAntiLambda{"mlConfigurations.localModelPathAntiLambda", "AntiLambda_BDTModel.onnx", "(std::string) Path to the local .onnx file."}; + Configurable localModelPathK0Short{"mlConfigurations.localModelPathK0Short", "KZeroShort_BDTModel.onnx", "(std::string) Path to the local .onnx file."}; + + // Thresholds for choosing to populate V0Cores tables with pre-selections + Configurable thresholdLambda{"mlConfigurations.thresholdLambda", -1.0f, "Threshold to keep Lambda candidates"}; + Configurable thresholdAntiLambda{"mlConfigurations.thresholdAntiLambda", -1.0f, "Threshold to keep AntiLambda candidates"}; + Configurable thresholdK0Short{"mlConfigurations.thresholdK0Short", -1.0f, "Threshold to keep K0Short candidates"}; + } mlConfigurations; + + // CCDB options + struct : ConfigurableGroup { + Configurable ccdburl{"ccdbConfigurations.ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"ccdbConfigurations.grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"ccdbConfigurations.grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"ccdbConfigurations.lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable geoPath{"ccdbConfigurations.geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable mVtxPath{"ccdbConfigurations.mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + } ccdbConfigurations; + + o2::ccdb::CcdbApi ccdbApi; + int mRunNumber; + std::map metadata; + + 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.2f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.4f, 1.6f, 1.8f, 2.0f, 2.4f, 2.8f, 3.2f, 3.6f, 4.0f, 4.8f, 5.6f, 6.5f, 7.5f, 9.0f, 11.0f, 13.0f, 15.0f, 19.0f, 23.0f, 30.0f, 40.0f, 50.0f}, "pt axis for analysis"}; + ConfigurableAxis axisQuarkoniumMass{"axisQuarkoniumMass", {500, 2.600f, 4.000f}, "M (hyp. #bar{hyp.} ) (GeV/#it{c}^{2})"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}, "Centrality"}; + ConfigurableAxis axisNch{"axisNch", {500, 0.0f, +5000.0f}, "Number of charged particles"}; + + ConfigurableAxis axisRawCentrality{"axisRawCentrality", {VARIABLE_WIDTH, 0.000f, 52.320f, 75.400f, 95.719f, 115.364f, 135.211f, 155.791f, 177.504f, 200.686f, 225.641f, 252.645f, 281.906f, 313.850f, 348.302f, 385.732f, 426.307f, 470.146f, 517.555f, 568.899f, 624.177f, 684.021f, 748.734f, 818.078f, 892.577f, 973.087f, 1058.789f, 1150.915f, 1249.319f, 1354.279f, 1465.979f, 1584.790f, 1710.778f, 1844.863f, 1985.746f, 2134.643f, 2291.610f, 2456.943f, 2630.653f, 2813.959f, 3006.631f, 3207.229f, 3417.641f, 3637.318f, 3865.785f, 4104.997f, 4354.938f, 4615.786f, 4885.335f, 5166.555f, 5458.021f, 5762.584f, 6077.881f, 6406.834f, 6746.435f, 7097.958f, 7462.579f, 7839.165f, 8231.629f, 8635.640f, 9052.000f, 9484.268f, 9929.111f, 10389.350f, 10862.059f, 11352.185f, 11856.823f, 12380.371f, 12920.401f, 13476.971f, 14053.087f, 14646.190f, 15258.426f, 15890.617f, 16544.433f, 17218.024f, 17913.465f, 18631.374f, 19374.983f, 20136.700f, 20927.783f, 21746.796f, 22590.880f, 23465.734f, 24372.274f, 25314.351f, 26290.488f, 27300.899f, 28347.512f, 29436.133f, 30567.840f, 31746.818f, 32982.664f, 34276.329f, 35624.859f, 37042.588f, 38546.609f, 40139.742f, 41837.980f, 43679.429f, 45892.130f, 400000.000f}, "raw centrality signal"}; // for QA + + ConfigurableAxis axisOccupancy{"axisOccupancy", {VARIABLE_WIDTH, 0.0f, 250.0f, 500.0f, 750.0f, 1000.0f, 1500.0f, 2000.0f, 3000.0f, 4500.0f, 6000.0f, 8000.0f, 10000.0f, 50000.0f}, "Occupancy"}; + + // 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 axisDCAV0ToPV{"axisDCAV0ToPV", {20, 0.0f, 2.0f}, "DCA (cm)"}; + ConfigurableAxis axisPointingAngle{"axisPointingAngle", {20, 0.0f, 2.0f}, "pointing angle (rad)"}; + ConfigurableAxis axisRadius{"axisRadius", {20, 0.0f, 60.0f}, "Decay radius (cm)"}; + ConfigurableAxis axisProperLifeTime{"axisV0ProperLifeTime", {100, 0.0f, 50.0f}, "ProperLifeTime 2D radius (cm)"}; + ConfigurableAxis axisMassWindow{"axisMassWindow", {40, -0.020f, 0.020f}, "Inv. mass - PDG mass (GeV/#it{c}^{2})"}; + ConfigurableAxis axisK0Mass{"axisK0Mass", {500, 0.400f, 0.600f}, "K0Short mass (GeV/#it{c}^{2})"}; + ConfigurableAxis axisLambdaMass{"axisLambdaMass", {500, 1.098f, 1.198f}, "Lambda mass (GeV/#it{c}^{2})"}; + ConfigurableAxis axisXiMass{"axisXiMass", {500, 1.318f, 1.370f}, "Xi mass (GeV/#it{c}^{2})"}; + ConfigurableAxis axisOmegaMass{"axisOmegaMass", {500, 1.670f, 1.675f}, "Omega mass (GeV/#it{c}^{2})"}; + ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {200, -10.0f, 10.0f}, "N sigma TPC"}; + + // Track quality axes + ConfigurableAxis axisTPCrows{"axisTPCrows", {160, 0.0f, 160.0f}, "N TPC rows"}; + ConfigurableAxis axisITSclus{"axisITSclus", {7, 0.0f, 7.0f}, "N ITS Clusters"}; + + // UPC axes + ConfigurableAxis axisSelGap{"axisSelGap", {4, -1.5, 2.5}, "Gap side"}; + + // PDG database + Service pdgDB; + + // For manual sliceBy + PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; + + enum selection : uint64_t { selCosPA = 0, + selRadius, + selRadiusMax, + selDCANegToPV, + selDCAPosToPV, + selDCAV0ToPV, + selDCAV0Dau, + selK0ShortRapidity, + selLambdaRapidity, + selK0ShortMassWindow, + selLambdaMassWindow, + selAntiLambdaMassWindow, + selK0ShortMassRejection, + selLambdaMassRejection, + selTPCPIDPositivePion, + selTPCPIDNegativePion, + selTPCPIDPositiveProton, + selTPCPIDNegativeProton, + selTOFDeltaTPositiveProtonLambda, + selTOFDeltaTPositivePionLambda, + selTOFDeltaTPositivePionK0Short, + selTOFDeltaTNegativeProtonLambda, + selTOFDeltaTNegativePionLambda, + selTOFDeltaTNegativePionK0Short, + selTOFNSigmaPositiveProtonLambda, // Nsigma + selTOFNSigmaPositivePionLambda, // Nsigma + selTOFNSigmaPositivePionK0Short, // Nsigma + selTOFNSigmaNegativeProtonLambda, // Nsigma + selTOFNSigmaNegativePionLambda, // Nsigma + selTOFNSigmaNegativePionK0Short, // Nsigma + selK0ShortCTau, + selLambdaCTau, + selK0ShortArmenteros, + selPosGoodTPCTrack, // at least min # TPC rows + selNegGoodTPCTrack, // at least min # TPC rows + selPosGoodITSTrack, // at least min # ITS clusters + selNegGoodITSTrack, // at least min # ITS clusters + selPosItsOnly, + selNegItsOnly, + selPosNotTPCOnly, + selNegNotTPCOnly, + selConsiderK0Short, // for mc tagging + selConsiderLambda, // for mc tagging + selConsiderAntiLambda, // for mc tagging + selPhysPrimK0Short, // for mc tagging + selPhysPrimLambda, // for mc tagging + selPhysPrimAntiLambda, // for mc tagging + }; + + uint64_t maskTopological; + uint64_t maskTopoNoV0Radius; + uint64_t maskTopoNoDCANegToPV; + uint64_t maskTopoNoDCAPosToPV; + uint64_t maskTopoNoCosPA; + uint64_t maskTopoNoDCAV0Dau; + uint64_t maskTopoNoDCAV0ToPV; + uint64_t maskTrackProperties; + + uint64_t maskK0ShortSpecific; + uint64_t maskLambdaSpecific; + uint64_t maskAntiLambdaSpecific; + + uint64_t maskSelectionK0Short; + uint64_t maskSelectionLambda; + uint64_t maskSelectionAntiLambda; + + uint64_t secondaryMaskSelectionLambda; + uint64_t secondaryMaskSelectionAntiLambda; + + void init(InitContext const&) + { + // initialise bit masks + maskTopological = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); + maskTopoNoV0Radius = (uint64_t(1) << selCosPA) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); + maskTopoNoDCANegToPV = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); + maskTopoNoDCAPosToPV = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); + maskTopoNoCosPA = (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); + maskTopoNoDCAV0Dau = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0ToPV) | (uint64_t(1) << selRadiusMax); + maskTopoNoDCAV0ToPV = (uint64_t(1) << selCosPA) | (uint64_t(1) << selRadius) | (uint64_t(1) << selDCANegToPV) | (uint64_t(1) << selDCAPosToPV) | (uint64_t(1) << selDCAV0Dau) | (uint64_t(1) << selRadiusMax); + + maskK0ShortSpecific = (uint64_t(1) << selK0ShortRapidity) | (uint64_t(1) << selK0ShortCTau) | (uint64_t(1) << selK0ShortArmenteros) | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selK0ShortMassWindow) | (uint64_t(1) << selLambdaMassRejection); + maskLambdaSpecific = (uint64_t(1) << selLambdaRapidity) | (uint64_t(1) << selLambdaCTau) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selLambdaMassWindow) | (uint64_t(1) << selK0ShortMassRejection); + maskAntiLambdaSpecific = (uint64_t(1) << selLambdaRapidity) | (uint64_t(1) << selLambdaCTau) | (uint64_t(1) << selConsiderAntiLambda) | (uint64_t(1) << selAntiLambdaMassWindow) | (uint64_t(1) << selK0ShortMassRejection); + + // ask for specific TPC/TOF PID selections + maskTrackProperties = 0; + if (v0Selections.requirePosITSonly) { + maskTrackProperties = maskTrackProperties | (uint64_t(1) << selPosItsOnly) | (uint64_t(1) << selPosGoodITSTrack); + } else { + maskTrackProperties = maskTrackProperties | (uint64_t(1) << selPosGoodTPCTrack) | (uint64_t(1) << selPosGoodITSTrack); + // TPC signal is available: ask for positive track PID + if (v0Selections.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTPCPIDPositivePion); + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTPCPIDPositiveProton); + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTPCPIDPositivePion); + } + // TOF PID + if (v0Selections.TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaPositivePionK0Short) | (uint64_t(1) << selTOFDeltaTPositivePionK0Short); + if (v0Selections.TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaPositiveProtonLambda) | (uint64_t(1) << selTOFDeltaTPositiveProtonLambda); + if (v0Selections.TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaPositivePionLambda) | (uint64_t(1) << selTOFDeltaTPositivePionLambda); + } + if (v0Selections.requireNegITSonly) { + maskTrackProperties = maskTrackProperties | (uint64_t(1) << selNegItsOnly) | (uint64_t(1) << selNegGoodITSTrack); + } else { + maskTrackProperties = maskTrackProperties | (uint64_t(1) << selNegGoodTPCTrack) | (uint64_t(1) << selNegGoodITSTrack); + // TPC signal is available: ask for negative track PID + if (v0Selections.TpcPidNsigmaCut < 1e+5) { // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTPCPIDNegativePion); + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTPCPIDNegativePion); + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTPCPIDNegativeProton); + } + // TOF PID + if (v0Selections.TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut + maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaNegativePionK0Short) | (uint64_t(1) << selTOFDeltaTNegativePionK0Short); + if (v0Selections.TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda); + if (v0Selections.TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativeProtonLambda) | (uint64_t(1) << selTOFDeltaTNegativeProtonLambda); + } + + if (v0Selections.skipTPConly) { + maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selPosNotTPCOnly) | (uint64_t(1) << selNegNotTPCOnly); + maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selPosNotTPCOnly) | (uint64_t(1) << selNegNotTPCOnly); + maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selPosNotTPCOnly) | (uint64_t(1) << selNegNotTPCOnly); + } + + // Primary particle selection, central to analysis + maskSelectionK0Short = maskTopological | maskTrackProperties | maskK0ShortSpecific; + maskSelectionLambda = maskTopological | maskTrackProperties | maskLambdaSpecific; + maskSelectionAntiLambda = maskTopological | maskTrackProperties | maskAntiLambdaSpecific; + + // No primary requirement for feeddown matrix + secondaryMaskSelectionLambda = maskTopological | maskTrackProperties | maskLambdaSpecific; + secondaryMaskSelectionAntiLambda = maskTopological | maskTrackProperties | maskAntiLambdaSpecific; + + // Event Counters + histos.add("hEventSelection", "hEventSelection", kTH1F, {{20, -0.5f, +19.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.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "Above max occup."); + + histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); + histos.add("hCentralityVsNch", "hCentralityVsNch", kTH2F, {axisCentrality, axisNch}); + + histos.add("hEventOccupancy", "hEventOccupancy", kTH1F, {axisOccupancy}); + histos.add("hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH2F, {axisCentrality, axisOccupancy}); + + if (!isPP) { + histos.add("hGapSide", "Gap side; Entries", kTH1F, {{5, -0.5, 4.5}}); + histos.add("hSelGapSide", "Selected gap side; Entries", kTH1F, {axisSelGap}); + histos.add("hEventCentralityVsSelGapSide", ";Centrality (%); Selected gap side", kTH2F, {{100, 0.0f, +100.0f}, axisSelGap}); + } + + // for QA and test purposes + auto hRawCentrality = histos.add("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality}); + + for (int ii = 1; ii < 101; ii++) { + float value = 100.5f - static_cast(ii); + hRawCentrality->SetBinContent(ii, value); + } + + // histograms versus mass + if (buildLaLaBarPairs) { + histos.add("LaLaBar/h3dMassLaLabar", "h3dMassLaLabar", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + if (!isPP) { + // Non-UPC info + histos.add("LaLaBar/h3dMassLaLabarHadronic", "h3dMassLaLabarHadronic", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + // UPC info + histos.add("LaLaBar/h3dMassLaLabarSGA", "h3dMassLaLabarSGA", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dMassLaLabarSGC", "h3dMassLaLabarSGC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dMassLaLabarDG", "h3dMassLaLabarDG", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + histos.add("LaLaBar/h2dNbrOfK0ShortVsCentrality", "h2dNbrOfK0ShortVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + histos.add("LaLaBar/h2dNbrOfLambdaVsCentrality", "h2dNbrOfLambdaVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + histos.add("LaLaBar/h2dNbrOfAntiLambdaVsCentrality", "h2dNbrOfAntiLambdaVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + // QA plot + // Candidates after Lambda selections + histos.add("LaLaBar/Lambda/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("LaLaBar/Lambda/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("LaLaBar/Lambda/hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {axisDCAdau}); + histos.add("LaLaBar/Lambda/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("LaLaBar/Lambda/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("LaLaBar/Lambda/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("LaLaBar/Lambda/hV0DecayLength", "hDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("LaLaBar/Lambda/hV0InvMassWindow", "hInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("LaLaBar/Lambda/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisLambdaMass, axisK0Mass}); + histos.add("LaLaBar/Lambda/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("LaLaBar/Lambda/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("LaLaBar/Lambda/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("LaLaBar/Lambda/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + + // Candidates after AntiLambda selections + histos.add("LaLaBar/AntiLambda/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("LaLaBar/AntiLambda/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("LaLaBar/AntiLambda/hDCAV0Daughters", "hDCADaughters", kTH1F, {axisDCAdau}); + histos.add("LaLaBar/AntiLambda/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("LaLaBar/AntiLambda/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("LaLaBar/AntiLambda/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("LaLaBar/AntiLambda/hV0DecayLength", "hDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("LaLaBar/AntiLambda/hV0InvMassWindow", "hInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("LaLaBar/AntiLambda/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisLambdaMass, axisK0Mass}); + histos.add("LaLaBar/AntiLambda/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("LaLaBar/AntiLambda/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("LaLaBar/AntiLambda/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("LaLaBar/AntiLambda/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + if (doMCAssociation) { + histos.add("LaLaBar/h3dInvMassTrueEtaC1S", "h3dInvMassTrueEtaC1S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTrueJPsi", "h3dInvMassTrueJPsi", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTrueChiC0", "h3dInvMassTrueChiC0", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTrueChiC1", "h3dInvMassTrueChiC1", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTrueHC", "h3dInvMassTrueHC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTrueChiC2", "h3dInvMassTrueChiC2", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTrueEtaC2S", "h3dInvMassTrueEtaC2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("LaLaBar/h3dInvMassTruePsi2S", "h3dInvMassTruePsi2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + } + if (buildXiXiBarPairs) { + histos.add("XiXiBar/h3dMassXiXibar", "h3dMassXiXibar", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + if (!isPP) { + // Non-UPC info + histos.add("XiXiBar/h3dMassXiXibarHadronic", "h3dMassXiXibarHadronic", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + // UPC info + histos.add("XiXiBar/h3dMassXiXibarSGA", "h3dMassXiXibarSGA", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dMassXiXibarSGC", "h3dMassXiXibarSGC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dMassXiXibarDG", "h3dMassXiXibarDG", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + histos.add("XiXiBar/h2dNbrOfXiVsCentrality", "h2dNbrOfXiVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + histos.add("XiXiBar/h2dNbrOfAntiXiVsCentrality", "h2dNbrOfAntiXiVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + // QA plot + // Candidates after Xi selections + histos.add("XiXiBar/Xi/hBachDCAToPV", "hBachDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("XiXiBar/Xi/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("XiXiBar/Xi/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("XiXiBar/Xi/hDCACascDaughters", "hDCACascDaughters", kTH1F, {axisDCAdau}); + histos.add("XiXiBar/Xi/hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {axisDCAdau}); + histos.add("XiXiBar/Xi/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("XiXiBar/Xi/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("XiXiBar/Xi/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("XiXiBar/Xi/hCascPointingAngle", "hCascPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("XiXiBar/Xi/hCascRadius", "hCascRadius", kTH1F, {axisRadius}); + histos.add("XiXiBar/Xi/hCascDecayLength", "hCascDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("XiXiBar/Xi/hV0InvMassWindow", "hV0InvMassWindow", kTH1F, {axisMassWindow}); + histos.add("XiXiBar/Xi/hCascInvMassWindow", "hCascInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("XiXiBar/Xi/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisXiMass, axisOmegaMass}); + histos.add("XiXiBar/Xi/hBachTPCNsigma", "hBachTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("XiXiBar/Xi/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("XiXiBar/Xi/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("XiXiBar/Xi/h2dBachelorITSvsTPCpts", "h2dBachelorITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("XiXiBar/Xi/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("XiXiBar/Xi/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + // Candidates after AntiXi selections + histos.add("XiXiBar/AntiXi/hBachDCAToPV", "hBachDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("XiXiBar/AntiXi/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("XiXiBar/AntiXi/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("XiXiBar/AntiXi/hDCACascDaughters", "hDCACascDaughters", kTH1F, {axisDCAdau}); + histos.add("XiXiBar/AntiXi/hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {axisDCAdau}); + histos.add("XiXiBar/AntiXi/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("XiXiBar/AntiXi/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("XiXiBar/AntiXi/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("XiXiBar/AntiXi/hCascPointingAngle", "hCascPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("XiXiBar/AntiXi/hCascRadius", "hCascRadius", kTH1F, {axisRadius}); + histos.add("XiXiBar/AntiXi/hCascDecayLength", "hCascDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("XiXiBar/AntiXi/hV0InvMassWindow", "hV0InvMassWindow", kTH1F, {axisMassWindow}); + histos.add("XiXiBar/AntiXi/hCascInvMassWindow", "hCascInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("XiXiBar/AntiXi/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisXiMass, axisOmegaMass}); + histos.add("XiXiBar/AntiXi/hBachTPCNsigma", "hBachTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("XiXiBar/AntiXi/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("XiXiBar/AntiXi/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("XiXiBar/AntiXi/h2dBachelorITSvsTPCpts", "h2dBachelorITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("XiXiBar/AntiXi/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("XiXiBar/AntiXi/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + if (doMCAssociation) { + histos.add("XiXiBar/h3dInvMassTrueEtaC1S", "h3dInvMassTrueEtaC1S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTrueJPsi", "h3dInvMassTrueJPsi", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTrueChiC0", "h3dInvMassTrueChiC0", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTrueChiC1", "h3dInvMassTrueChiC1", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTrueHC", "h3dInvMassTrueHC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTrueChiC2", "h3dInvMassTrueChiC2", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTrueEtaC2S", "h3dInvMassTrueEtaC2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("XiXiBar/h3dInvMassTruePsi2S", "h3dInvMassTruePsi2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + } + if (buildOmOmBarPairs) { + histos.add("OmOmBar/h3dMassOmOmbar", "h3dMassOmOmbar", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + if (!isPP) { + // Non-UPC info + histos.add("OmOmBar/h3dMassOmOmbarHadronic", "h3dMassOmOmbarHadronic", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + // UPC info + histos.add("OmOmBar/h3dMassOmOmbarSGA", "h3dMassOmOmbarSGA", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("OmOmBar/h3dMassOmOmbarSGC", "h3dMassOmOmbarSGC", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("OmOmBar/h3dMassOmOmbarDG", "h3dMassOmOmbarDG", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + histos.add("OmOmBar/h2dNbrOfOmegaVsCentrality", "h2dNbrOfOmegaVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + histos.add("OmOmBar/h2dNbrOfAntiOmegaVsCentrality", "h2dNbrOfAntiOmegaVsCentrality", kTH2F, {axisCentrality, {10, -0.5f, 9.5f}}); + // QA plot + // Candidates after Omega selections + histos.add("OmOmBar/Omega/hBachDCAToPV", "hBachDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("OmOmBar/Omega/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("OmOmBar/Omega/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("OmOmBar/Omega/hDCACascDaughters", "hDCACascDaughters", kTH1F, {axisDCAdau}); + histos.add("OmOmBar/Omega/hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {axisDCAdau}); + histos.add("OmOmBar/Omega/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("OmOmBar/Omega/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("OmOmBar/Omega/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("OmOmBar/Omega/hCascPointingAngle", "hCascPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("OmOmBar/Omega/hCascRadius", "hCascRadius", kTH1F, {axisRadius}); + histos.add("OmOmBar/Omega/hCascDecayLength", "hCascDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("OmOmBar/Omega/hV0InvMassWindow", "hV0InvMassWindow", kTH1F, {axisMassWindow}); + histos.add("OmOmBar/Omega/hCascInvMassWindow", "hCascInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("OmOmBar/Omega/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisXiMass, axisOmegaMass}); + histos.add("OmOmBar/Omega/hBachTPCNsigma", "hBachTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("OmOmBar/Omega/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("OmOmBar/Omega/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("OmOmBar/Omega/h2dBachelorITSvsTPCpts", "h2dBachelorITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("OmOmBar/Omega/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("OmOmBar/Omega/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + // Candidates after AntiOmega selections + histos.add("OmOmBar/AntiOmega/hBachDCAToPV", "hBachDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("OmOmBar/AntiOmega/hPosDCAToPV", "hPosDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("OmOmBar/AntiOmega/hNegDCAToPV", "hNegDCAToPV", kTH1F, {axisDCAtoPV}); + histos.add("OmOmBar/AntiOmega/hDCACascDaughters", "hDCACascDaughters", kTH1F, {axisDCAdau}); + histos.add("OmOmBar/AntiOmega/hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {axisDCAdau}); + histos.add("OmOmBar/AntiOmega/hDCAV0ToPV", "hDCAV0ToPV", kTH1F, {axisDCAV0ToPV}); + histos.add("OmOmBar/AntiOmega/hV0PointingAngle", "hV0PointingAngle", kTH1F, {axisPointingAngle}); + histos.add("OmOmBar/AntiOmega/hV0Radius", "hV0Radius", kTH1F, {axisRadius}); + histos.add("OmOmBar/AntiOmega/hCascPointingAngle", "hCascPointingAngle", kTH1F, {axisPointingAngle}); + histos.add("OmOmBar/AntiOmega/hCascRadius", "hCascRadius", kTH1F, {axisRadius}); + histos.add("OmOmBar/AntiOmega/hCascDecayLength", "hCascDecayLength", kTH1F, {axisProperLifeTime}); + histos.add("OmOmBar/AntiOmega/hV0InvMassWindow", "hV0InvMassWindow", kTH1F, {axisMassWindow}); + histos.add("OmOmBar/AntiOmega/hCascInvMassWindow", "hCascInvMassWindow", kTH1F, {axisMassWindow}); + histos.add("OmOmBar/AntiOmega/h2dCompetingMassRej", "h2dCompetingMassRej", kTH2F, {axisXiMass, axisOmegaMass}); + histos.add("OmOmBar/AntiOmega/hBachTPCNsigma", "hBachTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("OmOmBar/AntiOmega/hPosTPCNsigma", "hPosTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("OmOmBar/AntiOmega/hNegTPCNsigma", "hNegTPCNsigma", kTH1F, {axisNsigmaTPC}); + histos.add("OmOmBar/AntiOmega/h2dBachelorITSvsTPCpts", "h2dBachelorITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("OmOmBar/AntiOmega/h2dPositiveITSvsTPCpts", "h2dPositiveITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + histos.add("OmOmBar/AntiOmega/h2dNegativeITSvsTPCpts", "h2dNegativeITSvsTPCpts", kTH2F, {axisTPCrows, axisITSclus}); + if (doMCAssociation) { + histos.add("OmOmBar/h3dInvMassTrueEtaC2S", "h3dInvMassTrueEtaC2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + histos.add("OmOmBar/h3dInvMassTruePsi2S", "h3dInvMassTruePsi2S", kTH3F, {axisCentrality, axisPt, axisQuarkoniumMass}); + } + } + // inspect histogram sizes, please + histos.print(); + } + + template // TCollision should be of the type: soa::Join::iterator or so + void initCCDB(TCollision const& collision) + { + if (mRunNumber == collision.runNumber()) { + return; + } + + mRunNumber = collision.runNumber(); + + // machine learning initialization if requested + if (mlConfigurations.calculateK0ShortScores || + mlConfigurations.calculateLambdaScores || + mlConfigurations.calculateAntiLambdaScores) { + int64_t timeStampML = collision.timestamp(); + if (mlConfigurations.timestampCCDB.value != -1) + timeStampML = mlConfigurations.timestampCCDB.value; + LoadMachines(timeStampML); + } + } + + // function to load models for ML-based classifiers + void LoadMachines(int64_t timeStampML) + { + if (mlConfigurations.loadCustomModelsFromCCDB) { + ccdbApi.init(ccdbConfigurations.ccdburl); + LOG(info) << "Fetching models for timestamp: " << timeStampML; + + if (mlConfigurations.calculateLambdaScores) { + bool retrieveSuccessLambda = ccdbApi.retrieveBlob(mlConfigurations.customModelPathCCDB, ".", metadata, timeStampML, false, mlConfigurations.localModelPathLambda.value); + if (retrieveSuccessLambda) { + mlCustomModelLambda.initModel(mlConfigurations.localModelPathLambda.value, mlConfigurations.enableOptimizations.value); + } else { + LOG(fatal) << "Error encountered while fetching/loading the Lambda model from CCDB! Maybe the model doesn't exist yet for this runnumber/timestamp?"; + } + } + + if (mlConfigurations.calculateAntiLambdaScores) { + bool retrieveSuccessAntiLambda = ccdbApi.retrieveBlob(mlConfigurations.customModelPathCCDB, ".", metadata, timeStampML, false, mlConfigurations.localModelPathAntiLambda.value); + if (retrieveSuccessAntiLambda) { + mlCustomModelAntiLambda.initModel(mlConfigurations.localModelPathAntiLambda.value, mlConfigurations.enableOptimizations.value); + } else { + LOG(fatal) << "Error encountered while fetching/loading the AntiLambda model from CCDB! Maybe the model doesn't exist yet for this runnumber/timestamp?"; + } + } + + if (mlConfigurations.calculateK0ShortScores) { + bool retrieveSuccessKZeroShort = ccdbApi.retrieveBlob(mlConfigurations.customModelPathCCDB, ".", metadata, timeStampML, false, mlConfigurations.localModelPathK0Short.value); + if (retrieveSuccessKZeroShort) { + mlCustomModelK0Short.initModel(mlConfigurations.localModelPathK0Short.value, mlConfigurations.enableOptimizations.value); + } else { + LOG(fatal) << "Error encountered while fetching/loading the K0Short model from CCDB! Maybe the model doesn't exist yet for this runnumber/timestamp?"; + } + } + } else { + if (mlConfigurations.calculateLambdaScores) + mlCustomModelLambda.initModel(mlConfigurations.localModelPathLambda.value, mlConfigurations.enableOptimizations.value); + if (mlConfigurations.calculateAntiLambdaScores) + mlCustomModelAntiLambda.initModel(mlConfigurations.localModelPathAntiLambda.value, mlConfigurations.enableOptimizations.value); + if (mlConfigurations.calculateK0ShortScores) + mlCustomModelK0Short.initModel(mlConfigurations.localModelPathK0Short.value, mlConfigurations.enableOptimizations.value); + } + LOG(info) << "ML Models loaded."; + } + + template + bool IsEventAccepted(TCollision collision, bool fillHists) + // check whether the collision passes our collision selections + { + if (fillHists) + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + if (requireSel8 && !collision.sel8()) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + + if (std::abs(collision.posZ()) > 10.f) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); + + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); + + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + + if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 5 /* Contains at least one ITS-TPC track */); + + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 6 /* PV position consistency check */); + + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 7 /* PV with at least one contributor matched with TOF */); + + if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TRD */); + + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 9 /* Not at same bunch pile-up */); + + if (requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 10 /* No other collision within +/- 10 microseconds */); + + if (requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 4 microseconds */); + + if (minOccupancy > 0 && collision.trackOccupancyInTimeRange() < minOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 12 /* Below min occupancy */); + if (maxOccupancy > 0 && collision.trackOccupancyInTimeRange() > maxOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 13 /* Above max occupancy */); + + return true; + } + + template + void fillEventHistograms(TCollision collision, float& centrality, int& selGapSide) + { + if (isPP) { // + centrality = collision.centFT0M(); + + if (qaCentrality) { + auto hRawCentrality = histos.get(HIST("hRawCentrality")); + centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0A() + collision.multFT0C())); + } + } else { + centrality = collision.centFT0C(); + + if (qaCentrality) { + auto hRawCentrality = histos.get(HIST("hRawCentrality")); + centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); + } + } + + // in case we want to push the analysis to Pb-Pb UPC + int gapSide = collision.gapSide(); + if (!isPP) { + // -1 --> Hadronic + // 0 --> Single Gap - A side + // 1 --> Single Gap - C side + // 2 --> Double Gap - both A & C sides + selGapSide = sgSelector.trueGap(collision, upcCuts.FV0cut, upcCuts.FT0Acut, upcCuts.FT0Ccut, upcCuts.ZDCcut); + histos.fill(HIST("hGapSide"), gapSide); + histos.fill(HIST("hSelGapSide"), selGapSide); + histos.fill(HIST("hEventCentralityVsSelGapSide"), centrality, selGapSide <= 2 ? selGapSide : -1); + } + + histos.fill(HIST("hEventCentrality"), centrality); + + histos.fill(HIST("hCentralityVsNch"), centrality, collision.multNTracksPVeta1()); + + histos.fill(HIST("hEventOccupancy"), collision.trackOccupancyInTimeRange()); + histos.fill(HIST("hCentralityVsOccupancy"), centrality, collision.trackOccupancyInTimeRange()); + + return; + } + + template + uint64_t computeReconstructionBitmap(TV0 v0, TCollision collision, float rapidityLambda, float rapidityK0Short, float /*pT*/) + // precalculate this information so that a check is one mask operation, not many + { + uint64_t bitMap = 0; + + // + // Base topological variables + // + + // v0 radius min/max selections + if (v0.v0radius() > v0Selections.v0radius) + bitset(bitMap, selRadius); + if (v0.v0radius() < v0Selections.v0radiusMax) + bitset(bitMap, selRadiusMax); + // DCA proton and pion to PV for Lambda and AntiLambda decay hypotheses + if (TMath::Abs(v0.dcapostopv()) > v0Selections.dcaprotontopv && + TMath::Abs(v0.dcanegtopv()) > v0Selections.dcapiontopv) { + bitset(bitMap, selDCAPosToPV); + bitset(bitMap, selDCANegToPV); + } else if (TMath::Abs(v0.dcapostopv()) > v0Selections.dcapiontopv && + TMath::Abs(v0.dcanegtopv()) > v0Selections.dcaprotontopv) { + bitset(bitMap, selDCAPosToPV); + bitset(bitMap, selDCANegToPV); + } + // V0 cosine of pointing angle + if (v0.v0cosPA() > v0Selections.v0cospa) + bitset(bitMap, selCosPA); + // DCA between v0 daughters + if (v0.dcaV0daughters() < v0Selections.dcav0dau) + bitset(bitMap, selDCAV0Dau); + // DCA V0 to prim vtx + if (v0.dcav0topv() > v0Selections.dcav0topv) + bitset(bitMap, selDCAV0ToPV); + + // + // rapidity + // + if (TMath::Abs(rapidityLambda) < v0Selections.rapidityCut) + bitset(bitMap, selLambdaRapidity); + if (TMath::Abs(rapidityK0Short) < v0Selections.rapidityCut) + bitset(bitMap, selK0ShortRapidity); + + // + // invariant mass window + // + if (TMath::Abs(v0.mK0Short() - pdgDB->Mass(310)) < v0Selections.v0MassWindow) + bitset(bitMap, selK0ShortMassWindow); + if (TMath::Abs(v0.mLambda() - pdgDB->Mass(3122)) < v0Selections.v0MassWindow) + bitset(bitMap, selLambdaMassWindow); + if (TMath::Abs(v0.mAntiLambda() - pdgDB->Mass(3122)) < v0Selections.v0MassWindow) + bitset(bitMap, selAntiLambdaMassWindow); + + // + // competing mass rejection + // + if (TMath::Abs(v0.mK0Short() - pdgDB->Mass(310)) > v0Selections.compMassRejection) + bitset(bitMap, selK0ShortMassRejection); + if (TMath::Abs(v0.mLambda() - pdgDB->Mass(3122)) > v0Selections.compMassRejection) + bitset(bitMap, selLambdaMassRejection); + + auto posTrackExtra = v0.template posTrackExtra_as(); + auto negTrackExtra = v0.template negTrackExtra_as(); + + // + // ITS quality flags + // + if (posTrackExtra.itsNCls() >= v0Selections.minITSclusters) + bitset(bitMap, selPosGoodITSTrack); + if (negTrackExtra.itsNCls() >= v0Selections.minITSclusters) + bitset(bitMap, selNegGoodITSTrack); + + // + // TPC quality flags + // + if (posTrackExtra.tpcCrossedRows() >= v0Selections.minTPCrows) + bitset(bitMap, selPosGoodTPCTrack); + if (negTrackExtra.tpcCrossedRows() >= v0Selections.minTPCrows) + bitset(bitMap, selNegGoodTPCTrack); + + // + // TPC PID + // + if (fabs(posTrackExtra.tpcNSigmaPi()) < v0Selections.TpcPidNsigmaCut) + bitset(bitMap, selTPCPIDPositivePion); + if (fabs(posTrackExtra.tpcNSigmaPr()) < v0Selections.TpcPidNsigmaCut) + bitset(bitMap, selTPCPIDPositiveProton); + if (fabs(negTrackExtra.tpcNSigmaPi()) < v0Selections.TpcPidNsigmaCut) + bitset(bitMap, selTPCPIDNegativePion); + if (fabs(negTrackExtra.tpcNSigmaPr()) < v0Selections.TpcPidNsigmaCut) + bitset(bitMap, selTPCPIDNegativeProton); + + // + // TOF PID in DeltaT + // Positive track + if (fabs(v0.posTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) + bitset(bitMap, selTOFDeltaTPositiveProtonLambda); + if (fabs(v0.posTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) + bitset(bitMap, selTOFDeltaTPositivePionLambda); + if (fabs(v0.posTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) + bitset(bitMap, selTOFDeltaTPositivePionK0Short); + // Negative track + if (fabs(v0.negTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) + bitset(bitMap, selTOFDeltaTNegativeProtonLambda); + if (fabs(v0.negTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) + bitset(bitMap, selTOFDeltaTNegativePionLambda); + if (fabs(v0.negTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) + bitset(bitMap, selTOFDeltaTNegativePionK0Short); + + // + // TOF PID in NSigma + // Positive track + if (fabs(v0.tofNSigmaLaPr()) < v0Selections.TofPidNsigmaCutLaPr) + bitset(bitMap, selTOFNSigmaPositiveProtonLambda); + if (fabs(v0.tofNSigmaALaPi()) < v0Selections.TofPidNsigmaCutLaPi) + bitset(bitMap, selTOFNSigmaPositivePionLambda); + if (fabs(v0.tofNSigmaK0PiPlus()) < v0Selections.TofPidNsigmaCutK0Pi) + bitset(bitMap, selTOFNSigmaPositivePionK0Short); + // Negative track + if (fabs(v0.tofNSigmaALaPr()) < v0Selections.TofPidNsigmaCutLaPr) + bitset(bitMap, selTOFNSigmaNegativeProtonLambda); + if (fabs(v0.tofNSigmaLaPi()) < v0Selections.TofPidNsigmaCutLaPi) + bitset(bitMap, selTOFNSigmaNegativePionLambda); + if (fabs(v0.tofNSigmaK0PiMinus()) < v0Selections.TofPidNsigmaCutK0Pi) + bitset(bitMap, selTOFNSigmaNegativePionK0Short); + + // + // ITS only tag + if (posTrackExtra.tpcCrossedRows() < 1) + bitset(bitMap, selPosItsOnly); + if (negTrackExtra.tpcCrossedRows() < 1) + bitset(bitMap, selNegItsOnly); + + // + // TPC only tag + if (posTrackExtra.detectorMap() != o2::aod::track::TPC) + bitset(bitMap, selPosNotTPCOnly); + if (negTrackExtra.detectorMap() != o2::aod::track::TPC) + bitset(bitMap, selNegNotTPCOnly); + + // + // 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() * v0Selections.armPodCut > TMath::Abs(v0.alpha()) || v0Selections.armPodCut < 1e-4) + bitset(bitMap, selK0ShortArmenteros); + + return bitMap; + } + + template + bool isCascadeSelected(TCascade casc, TCollision collision, float rapidity, bool isXi) + // precalculate this information so that a check is one mask operation, not many + { + // + // Base topological variables + // + + // v0 radius min/max selections + if (casc.v0radius() < cascSelections.v0radius) + return false; + if (casc.v0radius() > cascSelections.v0radiusMax) + return false; + // DCA proton and pion to PV for Lambda and AntiLambda decay hypotheses + if (casc.sign() < 0) { // Xi- or Omega- --> positive/negative daughter = proton/pion + if (TMath::Abs(casc.dcapostopv()) < cascSelections.dcaprotontopv) + return false; + if (TMath::Abs(casc.dcanegtopv()) < cascSelections.dcapiontopv) + return false; + } else { // Xi+ or Omega+ --> positive/negative daughter = pion/proton + if (TMath::Abs(casc.dcapostopv()) < cascSelections.dcapiontopv) + return false; + if (TMath::Abs(casc.dcanegtopv()) < cascSelections.dcaprotontopv) + return false; + } + // V0 cosine of pointing angle + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascSelections.v0cospa) + return false; + // DCA between v0 daughters + if (casc.dcaV0daughters() > cascSelections.dcav0dau) + return false; + // DCA V0 to prim vtx + if (casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < cascSelections.dcav0topv) + return false; + + // casc radius min/max selections + if (casc.cascradius() < cascSelections.cascradius) + return false; + if (casc.cascradius() > cascSelections.cascradiusMax) + return false; + // DCA bachelor selection + if (TMath::Abs(casc.dcabachtopv()) < cascSelections.dcabachtopv) + return false; + // Bachelor-baryon cosPA selection + if (casc.bachBaryonCosPA() < cascSelections.bachbaryoncospa) + return false; + // DCA bachelor-baryon selection + if (TMath::Abs(casc.bachBaryonDCAxyToPV()) < cascSelections.dcaxybachbaryontopv) + return false; + // casc cosine of pointing angle + if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascSelections.casccospa) + return false; + // DCA between casc daughters + if (casc.dcacascdaughters() > cascSelections.dcacascdau) + return false; + + // + // rapidity + // + if (TMath::Abs(rapidity) > cascSelections.rapidityCut) + return false; + + // + // invariant mass window + // + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > cascSelections.v0MassWindow) + return false; + if (isXi && TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > cascSelections.cascMassWindow) + return false; + if (!isXi && TMath::Abs(casc.mOmega() - pdgDB->Mass(3334)) > cascSelections.cascMassWindow) + return false; + + // + // competing mass rejection + // + if (isXi && TMath::Abs(casc.mOmega() - pdgDB->Mass(3334)) < cascSelections.compMassRejection) + return false; + if (!isXi && TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) < cascSelections.compMassRejection) + return false; + + auto bachTrackExtra = casc.template bachTrackExtra_as(); + auto posTrackExtra = casc.template posTrackExtra_as(); + auto negTrackExtra = casc.template negTrackExtra_as(); + + // + // ITS quality flags + // + if (bachTrackExtra.itsNCls() < cascSelections.minITSclusters) + return false; + if (posTrackExtra.itsNCls() < cascSelections.minITSclusters) + return false; + if (negTrackExtra.itsNCls() < cascSelections.minITSclusters) + return false; + + // + // TPC quality flags + // + if (bachTrackExtra.tpcCrossedRows() < cascSelections.minTPCrows) + return false; + if (posTrackExtra.tpcCrossedRows() < cascSelections.minTPCrows) + return false; + if (negTrackExtra.tpcCrossedRows() < cascSelections.minTPCrows) + return false; + + // + // TPC PID + // + if (isXi && fabs(bachTrackExtra.tpcNSigmaPi()) > cascSelections.TpcPidNsigmaCut) + return false; + if (!isXi && fabs(bachTrackExtra.tpcNSigmaKa()) > cascSelections.TpcPidNsigmaCut) + return false; + if (casc.sign() < 0) { // Xi- or Omega- --> positive/negative daughter = proton/pion + if (fabs(posTrackExtra.tpcNSigmaPr()) > cascSelections.TpcPidNsigmaCut) + return false; + if (fabs(negTrackExtra.tpcNSigmaPi()) > cascSelections.TpcPidNsigmaCut) + return false; + } else { // Xi+ or Omega+ --> positive/negative daughter = pion/proton + if (fabs(posTrackExtra.tpcNSigmaPi()) > cascSelections.TpcPidNsigmaCut) + return false; + if (fabs(negTrackExtra.tpcNSigmaPr()) > cascSelections.TpcPidNsigmaCut) + return false; + } + + // + // TOF PID in DeltaT + // Bachelor track + if (bachTrackExtra.hasTOF()) { + if (isXi && fabs(casc.bachTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) + return false; + if (!isXi && fabs(casc.bachTOFDeltaTOmKa()) > cascSelections.maxDeltaTimeKaon) + return false; + } + // Positive track + if (posTrackExtra.hasTOF()) { + if (casc.sign() < 0) { // Xi- or Omega- --> positive daughter = proton + if (isXi && fabs(casc.posTOFDeltaTXiPr()) > cascSelections.maxDeltaTimeProton) + return false; + if (!isXi && fabs(casc.posTOFDeltaTOmPr()) > cascSelections.maxDeltaTimeProton) + return false; + } else { // Xi+ or Omega+ --> positive daughter = pion + if (isXi && fabs(casc.posTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) + return false; + if (!isXi && fabs(casc.posTOFDeltaTOmPi()) > cascSelections.maxDeltaTimePion) + return false; + } + } + // Negative track + if (negTrackExtra.hasTOF()) { + if (casc.sign() < 0) { // Xi- or Omega- --> negative daughter = pion + if (isXi && fabs(casc.negTOFDeltaTXiPi()) > cascSelections.maxDeltaTimePion) + return false; + if (!isXi && fabs(casc.negTOFDeltaTOmPi()) > cascSelections.maxDeltaTimePion) + return false; + } else { // Xi+ or Omega+ --> negative daughter = proton + if (isXi && fabs(casc.negTOFDeltaTXiPr()) > cascSelections.maxDeltaTimeProton) + return false; + if (!isXi && fabs(casc.negTOFDeltaTOmPr()) > cascSelections.maxDeltaTimeProton) + return false; + } + } + + // + // TOF PID in NSigma + // Bachelor track + if (bachTrackExtra.hasTOF()) { + if (isXi && fabs(casc.tofNSigmaXiPi()) > cascSelections.TofPidNsigmaCutXiPi) + return false; + if (!isXi && fabs(casc.tofNSigmaOmKa()) > cascSelections.TofPidNsigmaCutOmKa) + return false; + } + // Positive track + if (posTrackExtra.hasTOF()) { + if (casc.sign() < 0) { // Xi- or Omega- --> positive daughter = proton + if (isXi && fabs(casc.tofNSigmaXiLaPr()) > cascSelections.TofPidNsigmaCutLaPr) + return false; + if (!isXi && fabs(casc.tofNSigmaOmLaPr()) > cascSelections.TofPidNsigmaCutLaPr) + return false; + } else { // Xi+ or Omega+ --> positive daughter = pion + if (isXi && fabs(casc.tofNSigmaXiLaPi()) > cascSelections.TofPidNsigmaCutLaPi) + return false; + if (!isXi && fabs(casc.tofNSigmaOmLaPi()) > cascSelections.TofPidNsigmaCutLaPi) + return false; + } + } + // Negative track + if (negTrackExtra.hasTOF()) { + if (casc.sign() < 0) { // Xi- or Omega- --> negative daughter = pion + if (isXi && fabs(casc.tofNSigmaXiLaPr()) > cascSelections.TofPidNsigmaCutLaPi) + return false; + if (!isXi && fabs(casc.tofNSigmaOmLaPr()) > cascSelections.TofPidNsigmaCutLaPi) + return false; + } else { // Xi+ or Omega+ --> negative daughter = proton + if (isXi && fabs(casc.tofNSigmaXiLaPi()) > cascSelections.TofPidNsigmaCutLaPr) + return false; + if (!isXi && fabs(casc.tofNSigmaOmLaPi()) > cascSelections.TofPidNsigmaCutLaPr) + return false; + } + } + + // + // proper lifetime + float distOverTotMom = std::sqrt(std::pow(casc.x() - collision.posX(), 2) + std::pow(casc.y() - collision.posY(), 2) + std::pow(casc.z() - collision.posZ(), 2)) / (casc.p() + 1E-10); + if (isXi && distOverTotMom * o2::constants::physics::MassXiMinus / ctauXiPDG > cascSelections.cascProperLifeTime) + return false; + if (!isXi && distOverTotMom * o2::constants::physics::MassOmegaMinus / ctauOmegaPDG > cascSelections.cascProperLifeTime) + return false; + + // + // MC association (if asked) + if (doMCAssociation) { + if constexpr (requires { casc.template cascMCCore_as>(); }) { // check if MC information is available + auto cascMC = casc.template cascMCCore_as>(); + + if (isXi) { + if (casc.sign() < 0) { + if (cascMC.pdgCode() != 3312 || cascMC.pdgCodePositive() != 2212 || cascMC.pdgCodeNegative() != -211 || cascMC.pdgCodeBachelor() != -211) + return false; + } else { + if (cascMC.pdgCode() != -3312 || cascMC.pdgCodePositive() != 211 || cascMC.pdgCodeNegative() != -2212 || cascMC.pdgCodeBachelor() != 211) + return false; + } + } else { + if (casc.sign() < 0) { + if (cascMC.pdgCode() != 3334 || cascMC.pdgCodePositive() != 2212 || cascMC.pdgCodeNegative() != -211 || cascMC.pdgCodeBachelor() != -321) + return false; + } else { + if (cascMC.pdgCode() != -3334 || cascMC.pdgCodePositive() != 211 || cascMC.pdgCodeNegative() != -2212 || cascMC.pdgCodeBachelor() != 321) + return false; + } + } + } + } + + return true; + } + + template + uint64_t computeMCAssociation(TV0 v0) + // precalculate this information so that a check is one mask operation, not many + { + uint64_t bitMap = 0; + // check for specific particle species + + if (v0.pdgCode() == 310 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -211) { + bitset(bitMap, selConsiderK0Short); + if (v0.isPhysicalPrimary()) + bitset(bitMap, selPhysPrimK0Short); + } + if (v0.pdgCode() == 3122 && v0.pdgCodePositive() == 2212 && v0.pdgCodeNegative() == -211) { + bitset(bitMap, selConsiderLambda); + if (v0.isPhysicalPrimary()) + bitset(bitMap, selPhysPrimLambda); + } + if (v0.pdgCode() == -3122 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -2212) { + bitset(bitMap, selConsiderAntiLambda); + if (v0.isPhysicalPrimary()) + bitset(bitMap, selPhysPrimAntiLambda); + } + return bitMap; + } + + bool verifyMask(uint64_t bitmap, uint64_t mask) + { + return (bitmap & mask) == mask; + } + + template + void analyseV0Candidate(TV0 v0, float pt, float /*centrality*/, uint64_t selMap, std::vector& selK0ShortIndices, std::vector& selLambdaIndices, std::vector& selAntiLambdaIndices, int v0TableOffset) + // precalculate this information so that a check is one mask operation, not many + { + bool passK0ShortSelections = false; + bool passLambdaSelections = false; + bool passAntiLambdaSelections = false; + + // machine learning is on, go for calculation of thresholds + // FIXME THIS NEEDS ADJUSTING + std::vector inputFeatures{pt, 0.0f, 0.0f, v0.v0radius(), v0.v0cosPA(), v0.dcaV0daughters(), v0.dcapostopv(), v0.dcanegtopv()}; + + if (mlConfigurations.useK0ShortScores) { + float k0shortScore = -1; + if (mlConfigurations.calculateK0ShortScores) { + // evaluate machine-learning scores + float* k0shortProbability = mlCustomModelK0Short.evalModel(inputFeatures); + k0shortScore = k0shortProbability[1]; + } else { + k0shortScore = v0.k0ShortBDTScore(); + } + if (k0shortScore > mlConfigurations.thresholdK0Short.value) { + passK0ShortSelections = true; + } + } else { + passK0ShortSelections = verifyMask(selMap, maskSelectionK0Short); + } + if (mlConfigurations.useLambdaScores) { + float lambdaScore = -1; + if (mlConfigurations.calculateLambdaScores) { + // evaluate machine-learning scores + float* lambdaProbability = mlCustomModelLambda.evalModel(inputFeatures); + lambdaScore = lambdaProbability[1]; + } else { + lambdaScore = v0.lambdaBDTScore(); + } + if (lambdaScore > mlConfigurations.thresholdK0Short.value) { + passLambdaSelections = true; + } + } else { + passLambdaSelections = verifyMask(selMap, maskSelectionLambda); + } + if (mlConfigurations.useLambdaScores) { + float antiLambdaScore = -1; + if (mlConfigurations.calculateAntiLambdaScores) { + // evaluate machine-learning scores + float* antilambdaProbability = mlCustomModelAntiLambda.evalModel(inputFeatures); + antiLambdaScore = antilambdaProbability[1]; + } else { + antiLambdaScore = v0.antiLambdaBDTScore(); + } + if (antiLambdaScore > mlConfigurations.thresholdK0Short.value) { + passAntiLambdaSelections = true; + } + } else { + passAntiLambdaSelections = verifyMask(selMap, maskSelectionAntiLambda); + } + + // need local index because of the grouping of collisions + selK0ShortIndices[v0.globalIndex() - v0TableOffset] = passK0ShortSelections; + selLambdaIndices[v0.globalIndex() - v0TableOffset] = passLambdaSelections; + selAntiLambdaIndices[v0.globalIndex() - v0TableOffset] = passAntiLambdaSelections; + } + + template + void fillQAplot(TCollision collision, THyperon hyperon, THyperon antiHyperon, int type) + { // fill QA information about hyperon - antihyperon pair + if (type == 0) { + if constexpr (requires { hyperon.mK0Short(); antiHyperon.mK0Short(); }) { // check if v0 information is available + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + + float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassLambda0 / (hyperon.p() + 1E-10); + float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassLambda0 / (antiHyperon.p() + 1E-10); + + // Candidates after Xi selections + histos.fill(HIST("LaLaBar/Lambda/hPosDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("LaLaBar/Lambda/hNegDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("LaLaBar/Lambda/hDCAV0Daughters"), hyperon.dcaV0daughters()); + histos.fill(HIST("LaLaBar/Lambda/hDCAV0ToPV"), hyperon.dcav0topv()); + histos.fill(HIST("LaLaBar/Lambda/hV0PointingAngle"), hyperon.v0cosPA()); + histos.fill(HIST("LaLaBar/Lambda/hV0Radius"), hyperon.v0radius()); + histos.fill(HIST("LaLaBar/Lambda/hV0DecayLength"), hyperonDecayLength); + histos.fill(HIST("LaLaBar/Lambda/hV0InvMassWindow"), hyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("LaLaBar/Lambda/h2dCompetingMassRej"), hyperon.mLambda(), hyperon.mK0Short()); + histos.fill(HIST("LaLaBar/Lambda/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPr()); + histos.fill(HIST("LaLaBar/Lambda/hNegTPCNsigma"), negTrackExtraHyperon.tpcNSigmaPi()); + histos.fill(HIST("LaLaBar/Lambda/h2dPositiveITSvsTPCpts"), posTrackExtraHyperon.tpcCrossedRows(), posTrackExtraHyperon.itsNCls()); + histos.fill(HIST("LaLaBar/Lambda/h2dNegativeITSvsTPCpts"), negTrackExtraHyperon.tpcCrossedRows(), negTrackExtraHyperon.itsNCls()); + // Candidates after AntiXi selections + histos.fill(HIST("LaLaBar/AntiLambda/hPosDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("LaLaBar/AntiLambda/hNegDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("LaLaBar/AntiLambda/hDCAV0Daughters"), antiHyperon.dcaV0daughters()); + histos.fill(HIST("LaLaBar/AntiLambda/hDCAV0ToPV"), antiHyperon.dcav0topv()); + histos.fill(HIST("LaLaBar/AntiLambda/hV0PointingAngle"), antiHyperon.v0cosPA()); + histos.fill(HIST("LaLaBar/AntiLambda/hV0Radius"), antiHyperon.v0radius()); + histos.fill(HIST("LaLaBar/AntiLambda/hV0DecayLength"), antiHyperonDecayLength); + histos.fill(HIST("LaLaBar/AntiLambda/hV0InvMassWindow"), antiHyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("LaLaBar/AntiLambda/h2dCompetingMassRej"), antiHyperon.mLambda(), antiHyperon.mK0Short()); + histos.fill(HIST("LaLaBar/AntiLambda/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); + histos.fill(HIST("LaLaBar/AntiLambda/hNegTPCNsigma"), negTrackExtraAntiHyperon.tpcNSigmaPr()); + histos.fill(HIST("LaLaBar/AntiLambda/h2dPositiveITSvsTPCpts"), posTrackExtraAntiHyperon.tpcCrossedRows(), posTrackExtraAntiHyperon.itsNCls()); + histos.fill(HIST("LaLaBar/AntiLambda/h2dNegativeITSvsTPCpts"), negTrackExtraAntiHyperon.tpcCrossedRows(), negTrackExtraAntiHyperon.itsNCls()); + } + } + if (type == 1) { + if constexpr (requires { hyperon.dcabachtopv(); antiHyperon.dcabachtopv(); }) { // check if Cascade information is available + auto bachTrackExtraHyperon = hyperon.template bachTrackExtra_as(); + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + + auto bachTrackExtraAntiHyperon = antiHyperon.template bachTrackExtra_as(); + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + + float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassXiMinus / (hyperon.p() + 1E-10); + float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassXiMinus / (antiHyperon.p() + 1E-10); + + // Candidates after Xi selections + histos.fill(HIST("XiXiBar/Xi/hBachDCAToPV"), hyperon.dcabachtopv()); + histos.fill(HIST("XiXiBar/Xi/hPosDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("XiXiBar/Xi/hNegDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("XiXiBar/Xi/hDCACascDaughters"), hyperon.dcacascdaughters()); + histos.fill(HIST("XiXiBar/Xi/hDCAV0Daughters"), hyperon.dcaV0daughters()); + histos.fill(HIST("XiXiBar/Xi/hDCAV0ToPV"), hyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("XiXiBar/Xi/hV0PointingAngle"), hyperon.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("XiXiBar/Xi/hV0Radius"), hyperon.v0radius()); + histos.fill(HIST("XiXiBar/Xi/hCascPointingAngle"), hyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("XiXiBar/Xi/hCascRadius"), hyperon.cascradius()); + histos.fill(HIST("XiXiBar/Xi/hCascDecayLength"), hyperonDecayLength); + histos.fill(HIST("XiXiBar/Xi/hV0InvMassWindow"), hyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("XiXiBar/Xi/hCascInvMassWindow"), hyperon.mXi() - pdgDB->Mass(3312)); + histos.fill(HIST("XiXiBar/Xi/h2dCompetingMassRej"), hyperon.mXi(), hyperon.mOmega()); + histos.fill(HIST("XiXiBar/Xi/hBachTPCNsigma"), bachTrackExtraHyperon.tpcNSigmaPi()); + histos.fill(HIST("XiXiBar/Xi/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPr()); + histos.fill(HIST("XiXiBar/Xi/hNegTPCNsigma"), negTrackExtraHyperon.tpcNSigmaPi()); + histos.fill(HIST("XiXiBar/Xi/h2dBachelorITSvsTPCpts"), bachTrackExtraHyperon.tpcCrossedRows(), bachTrackExtraHyperon.itsNCls()); + histos.fill(HIST("XiXiBar/Xi/h2dPositiveITSvsTPCpts"), posTrackExtraHyperon.tpcCrossedRows(), posTrackExtraHyperon.itsNCls()); + histos.fill(HIST("XiXiBar/Xi/h2dNegativeITSvsTPCpts"), negTrackExtraHyperon.tpcCrossedRows(), negTrackExtraHyperon.itsNCls()); + // Candidates after AntiXi selections + histos.fill(HIST("XiXiBar/AntiXi/hBachDCAToPV"), antiHyperon.dcabachtopv()); + histos.fill(HIST("XiXiBar/AntiXi/hPosDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("XiXiBar/AntiXi/hNegDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("XiXiBar/AntiXi/hDCACascDaughters"), antiHyperon.dcacascdaughters()); + histos.fill(HIST("XiXiBar/AntiXi/hDCAV0Daughters"), antiHyperon.dcaV0daughters()); + histos.fill(HIST("XiXiBar/AntiXi/hDCAV0ToPV"), antiHyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("XiXiBar/AntiXi/hV0PointingAngle"), antiHyperon.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("XiXiBar/AntiXi/hV0Radius"), antiHyperon.v0radius()); + histos.fill(HIST("XiXiBar/AntiXi/hCascPointingAngle"), antiHyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("XiXiBar/AntiXi/hCascRadius"), antiHyperon.cascradius()); + histos.fill(HIST("XiXiBar/AntiXi/hCascDecayLength"), antiHyperonDecayLength); + histos.fill(HIST("XiXiBar/AntiXi/hV0InvMassWindow"), antiHyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("XiXiBar/AntiXi/hCascInvMassWindow"), antiHyperon.mXi() - pdgDB->Mass(3312)); + histos.fill(HIST("XiXiBar/AntiXi/h2dCompetingMassRej"), antiHyperon.mXi(), antiHyperon.mOmega()); + histos.fill(HIST("XiXiBar/AntiXi/hBachTPCNsigma"), bachTrackExtraAntiHyperon.tpcNSigmaPi()); + histos.fill(HIST("XiXiBar/AntiXi/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); + histos.fill(HIST("XiXiBar/AntiXi/hNegTPCNsigma"), negTrackExtraAntiHyperon.tpcNSigmaPr()); + histos.fill(HIST("XiXiBar/AntiXi/h2dBachelorITSvsTPCpts"), bachTrackExtraAntiHyperon.tpcCrossedRows(), bachTrackExtraAntiHyperon.itsNCls()); + histos.fill(HIST("XiXiBar/AntiXi/h2dPositiveITSvsTPCpts"), posTrackExtraAntiHyperon.tpcCrossedRows(), posTrackExtraAntiHyperon.itsNCls()); + histos.fill(HIST("XiXiBar/AntiXi/h2dNegativeITSvsTPCpts"), negTrackExtraAntiHyperon.tpcCrossedRows(), negTrackExtraAntiHyperon.itsNCls()); + } + } + if (type == 2) { + if constexpr (requires { hyperon.dcabachtopv(); antiHyperon.dcabachtopv(); }) { // check if Cascade information is available + auto bachTrackExtraHyperon = hyperon.template bachTrackExtra_as(); + auto posTrackExtraHyperon = hyperon.template posTrackExtra_as(); + auto negTrackExtraHyperon = hyperon.template negTrackExtra_as(); + + auto bachTrackExtraAntiHyperon = antiHyperon.template bachTrackExtra_as(); + auto posTrackExtraAntiHyperon = antiHyperon.template posTrackExtra_as(); + auto negTrackExtraAntiHyperon = antiHyperon.template negTrackExtra_as(); + + float hyperonDecayLength = std::sqrt(std::pow(hyperon.x() - collision.posX(), 2) + std::pow(hyperon.y() - collision.posY(), 2) + std::pow(hyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassOmegaMinus / (hyperon.p() + 1E-10); + float antiHyperonDecayLength = std::sqrt(std::pow(antiHyperon.x() - collision.posX(), 2) + std::pow(antiHyperon.y() - collision.posY(), 2) + std::pow(antiHyperon.z() - collision.posZ(), 2)) * o2::constants::physics::MassOmegaMinus / (antiHyperon.p() + 1E-10); + + // Candidates after Omega selections + histos.fill(HIST("OmOmBar/Omega/hBachDCAToPV"), hyperon.dcabachtopv()); + histos.fill(HIST("OmOmBar/Omega/hPosDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("OmOmBar/Omega/hNegDCAToPV"), hyperon.dcapostopv()); + histos.fill(HIST("OmOmBar/Omega/hDCACascDaughters"), hyperon.dcacascdaughters()); + histos.fill(HIST("OmOmBar/Omega/hDCAV0Daughters"), hyperon.dcaV0daughters()); + histos.fill(HIST("OmOmBar/Omega/hDCAV0ToPV"), hyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("OmOmBar/Omega/hV0PointingAngle"), hyperon.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("OmOmBar/Omega/hV0Radius"), hyperon.v0radius()); + histos.fill(HIST("OmOmBar/Omega/hCascPointingAngle"), hyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("OmOmBar/Omega/hCascRadius"), hyperon.cascradius()); + histos.fill(HIST("OmOmBar/Omega/hCascDecayLength"), hyperonDecayLength); + histos.fill(HIST("OmOmBar/Omega/hV0InvMassWindow"), hyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("OmOmBar/Omega/hCascInvMassWindow"), hyperon.mOmega() - pdgDB->Mass(3334)); + histos.fill(HIST("OmOmBar/Omega/h2dCompetingMassRej"), hyperon.mXi(), hyperon.mOmega()); + histos.fill(HIST("OmOmBar/Omega/hBachTPCNsigma"), bachTrackExtraHyperon.tpcNSigmaKa()); + histos.fill(HIST("OmOmBar/Omega/hPosTPCNsigma"), posTrackExtraHyperon.tpcNSigmaPr()); + histos.fill(HIST("OmOmBar/Omega/hNegTPCNsigma"), negTrackExtraHyperon.tpcNSigmaPi()); + histos.fill(HIST("OmOmBar/Omega/h2dBachelorITSvsTPCpts"), bachTrackExtraHyperon.tpcCrossedRows(), bachTrackExtraHyperon.itsNCls()); + histos.fill(HIST("OmOmBar/Omega/h2dPositiveITSvsTPCpts"), posTrackExtraHyperon.tpcCrossedRows(), posTrackExtraHyperon.itsNCls()); + histos.fill(HIST("OmOmBar/Omega/h2dNegativeITSvsTPCpts"), negTrackExtraHyperon.tpcCrossedRows(), negTrackExtraHyperon.itsNCls()); + // Candidates after AntiOmega selections + histos.fill(HIST("OmOmBar/AntiOmega/hBachDCAToPV"), antiHyperon.dcabachtopv()); + histos.fill(HIST("OmOmBar/AntiOmega/hPosDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("OmOmBar/AntiOmega/hNegDCAToPV"), antiHyperon.dcapostopv()); + histos.fill(HIST("OmOmBar/AntiOmega/hDCACascDaughters"), antiHyperon.dcacascdaughters()); + histos.fill(HIST("OmOmBar/AntiOmega/hDCAV0Daughters"), antiHyperon.dcaV0daughters()); + histos.fill(HIST("OmOmBar/AntiOmega/hDCAV0ToPV"), antiHyperon.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("OmOmBar/AntiOmega/hV0PointingAngle"), antiHyperon.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("OmOmBar/AntiOmega/hV0Radius"), antiHyperon.v0radius()); + histos.fill(HIST("OmOmBar/AntiOmega/hCascPointingAngle"), antiHyperon.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + histos.fill(HIST("OmOmBar/AntiOmega/hCascRadius"), antiHyperon.cascradius()); + histos.fill(HIST("OmOmBar/AntiOmega/hCascDecayLength"), antiHyperonDecayLength); + histos.fill(HIST("OmOmBar/AntiOmega/hV0InvMassWindow"), antiHyperon.mLambda() - pdgDB->Mass(3122)); + histos.fill(HIST("OmOmBar/AntiOmega/hCascInvMassWindow"), antiHyperon.mOmega() - pdgDB->Mass(3334)); + histos.fill(HIST("OmOmBar/AntiOmega/h2dCompetingMassRej"), antiHyperon.mXi(), antiHyperon.mOmega()); + histos.fill(HIST("OmOmBar/AntiOmega/hBachTPCNsigma"), bachTrackExtraAntiHyperon.tpcNSigmaKa()); + histos.fill(HIST("OmOmBar/AntiOmega/hPosTPCNsigma"), posTrackExtraAntiHyperon.tpcNSigmaPi()); + histos.fill(HIST("OmOmBar/AntiOmega/hNegTPCNsigma"), negTrackExtraAntiHyperon.tpcNSigmaPr()); + histos.fill(HIST("OmOmBar/AntiOmega/h2dBachelorITSvsTPCpts"), bachTrackExtraAntiHyperon.tpcCrossedRows(), bachTrackExtraAntiHyperon.itsNCls()); + histos.fill(HIST("OmOmBar/AntiOmega/h2dPositiveITSvsTPCpts"), posTrackExtraAntiHyperon.tpcCrossedRows(), posTrackExtraAntiHyperon.itsNCls()); + histos.fill(HIST("OmOmBar/AntiOmega/h2dNegativeITSvsTPCpts"), negTrackExtraAntiHyperon.tpcCrossedRows(), negTrackExtraAntiHyperon.itsNCls()); + } + } + } + + template + void analyseHyperonPairCandidate(TCollision collision, THyperon hyperon, THyperon antiHyperon, float centrality, uint8_t gapSide, int type) + // fill information related to the quarkonium mother + // type = 0 (Lambda), 1 (Xi), 2 (Omega) + { + float pt = RecoDecay::pt(hyperon.px() + antiHyperon.px(), hyperon.py() + antiHyperon.py()); + + float invmass = -1; + if (type == 0) + invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassLambda0, o2::constants::physics::MassLambda0Bar}); + if (type == 1) + invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassXiMinus, o2::constants::physics::MassXiPlusBar}); + if (type == 2) + invmass = RecoDecay::m(std::array{std::array{hyperon.px(), hyperon.py(), hyperon.pz()}, std::array{antiHyperon.px(), antiHyperon.py(), antiHyperon.pz()}}, std::array{o2::constants::physics::MassOmegaMinus, o2::constants::physics::MassOmegaPlusBar}); + + float rapidity = RecoDecay::y(std::array{hyperon.px() + antiHyperon.px(), hyperon.py() + antiHyperon.py(), hyperon.pz() + antiHyperon.pz()}, invmass); + + // rapidity cut on the quarkonium mother + if (!doMCAssociation && TMath::Abs(rapidity) > rapidityCut) + return; + + // fillV0sInfo(lambda, antiLambda, centrality); + + // __________________________________________ + // main analysis + if (type == 0) { + if (doMCAssociation) { + if constexpr (requires { hyperon.template v0MCCore_as>(); }) { // check if MC information is available + auto hyperonMC = hyperon.template v0MCCore_as>(); + auto antiHyperonMC = antiHyperon.template v0MCCore_as>(); + + if (hyperonMC.pdgCodeMother() != antiHyperonMC.pdgCodeMother()) { + return; + } + + float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); + float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); + + if (TMath::Abs(rapiditymc) > rapidityCut) + return; + + if (hyperonMC.pdgCodeMother() == 441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(1S) + histos.fill(HIST("LaLaBar/h3dInvMassTrueEtaC1S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // J/psi + histos.fill(HIST("LaLaBar/h3dInvMassTrueJPsi"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 10441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC0 + histos.fill(HIST("LaLaBar/h3dInvMassTrueChiC0"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 20443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC1 + histos.fill(HIST("LaLaBar/h3dInvMassTrueChiC1"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 10443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // hC + histos.fill(HIST("LaLaBar/h3dInvMassTrueHC"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 445 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC2 + histos.fill(HIST("LaLaBar/h3dInvMassTrueChiC2"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(2S) + histos.fill(HIST("LaLaBar/h3dInvMassTrueEtaC2S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // Psi(2S) + histos.fill(HIST("LaLaBar/h3dInvMassTruePsi2S"), centrality, ptmc, invmass); + } + } + } + + histos.fill(HIST("LaLaBar/h3dMassLaLabar"), centrality, pt, invmass); + if (!isPP) { // in case of PbPb data + if (gapSide == 0) + histos.fill(HIST("LaLaBar/h3dMassLaLabarSGA"), centrality, pt, invmass); + else if (gapSide == 1) + histos.fill(HIST("LaLaBar/h3dMassLaLabarSGC"), centrality, pt, invmass); + else if (gapSide == 2) + histos.fill(HIST("LaLaBar/h3dMassLaLabarDG"), centrality, pt, invmass); + else + histos.fill(HIST("LaLaBar/h3dMassLaLabarHadronic"), centrality, pt, invmass); + } + fillQAplot(collision, hyperon, antiHyperon, 0); + } + if (type == 1) { + if (doMCAssociation) { + if constexpr (requires { hyperon.template cascMCCore_as>(); }) { // check if MC information is available + auto hyperonMC = hyperon.template cascMCCore_as>(); + auto antiHyperonMC = antiHyperon.template cascMCCore_as>(); + + if (hyperonMC.pdgCodeMother() != antiHyperonMC.pdgCodeMother()) { + return; + } + + float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); + float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); + + if (TMath::Abs(rapiditymc) > rapidityCut) + return; + + if (hyperonMC.pdgCodeMother() == 441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(1S) + histos.fill(HIST("XiXiBar/h3dInvMassTrueEtaC1S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // J/psi + histos.fill(HIST("XiXiBar/h3dInvMassTrueJPsi"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 10441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC0 + histos.fill(HIST("XiXiBar/h3dInvMassTrueChiC0"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 20443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC1 + histos.fill(HIST("XiXiBar/h3dInvMassTrueChiC1"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 10443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // hC + histos.fill(HIST("XiXiBar/h3dInvMassTrueHC"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 445 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // ChiC2 + histos.fill(HIST("XiXiBar/h3dInvMassTrueChiC2"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(2S) + histos.fill(HIST("XiXiBar/h3dInvMassTrueEtaC2S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // Psi(2S) + histos.fill(HIST("XiXiBar/h3dInvMassTruePsi2S"), centrality, ptmc, invmass); + } + } + } + + histos.fill(HIST("XiXiBar/h3dMassXiXibar"), centrality, pt, invmass); + if (!isPP) { // in case of PbPb data + if (gapSide == 0) + histos.fill(HIST("XiXiBar/h3dMassXiXibarSGA"), centrality, pt, invmass); + else if (gapSide == 1) + histos.fill(HIST("XiXiBar/h3dMassXiXibarSGC"), centrality, pt, invmass); + else if (gapSide == 2) + histos.fill(HIST("XiXiBar/h3dMassXiXibarDG"), centrality, pt, invmass); + else + histos.fill(HIST("XiXiBar/h3dMassXiXibarHadronic"), centrality, pt, invmass); + } + fillQAplot(collision, hyperon, antiHyperon, 1); + } + if (type == 2) { + if (doMCAssociation) { + if constexpr (requires { hyperon.template cascMCCore_as>(); }) { // check if MC information is available + auto hyperonMC = hyperon.template cascMCCore_as>(); + auto antiHyperonMC = antiHyperon.template cascMCCore_as>(); + + if (hyperonMC.pdgCodeMother() != antiHyperonMC.pdgCodeMother()) { + return; + } + + float ptmc = RecoDecay::pt(hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC()); + float rapiditymc = RecoDecay::y(std::array{hyperonMC.pxMC() + antiHyperonMC.pxMC(), hyperonMC.pyMC() + antiHyperonMC.pyMC(), hyperonMC.pzMC() + antiHyperonMC.pzMC()}, pdgDB->Mass(hyperonMC.pdgCodeMother())); + + if (TMath::Abs(rapiditymc) > rapidityCut) + return; + + if (hyperonMC.pdgCodeMother() == 100441 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // EtaC(2S) + histos.fill(HIST("OmOmBar/h3dInvMassTrueEtaC2S"), centrality, ptmc, invmass); + } + if (hyperonMC.pdgCodeMother() == 100443 && hyperonMC.pdgCodeMother() == antiHyperonMC.pdgCodeMother()) { // Psi(2S) + histos.fill(HIST("OmOmBar/h3dInvMassTruePsi2S"), centrality, ptmc, invmass); + } + } + } + + histos.fill(HIST("OmOmBar/h3dMassOmOmbar"), centrality, pt, invmass); + if (!isPP) { // in case of PbPb data + if (gapSide == 0) + histos.fill(HIST("OmOmBar/h3dMassOmOmbarSGA"), centrality, pt, invmass); + else if (gapSide == 1) + histos.fill(HIST("OmOmBar/h3dMassOmOmbarSGC"), centrality, pt, invmass); + else if (gapSide == 2) + histos.fill(HIST("OmOmBar/h3dMassOmOmbarDG"), centrality, pt, invmass); + else + histos.fill(HIST("OmOmBar/h3dMassOmOmbarHadronic"), centrality, pt, invmass); + } + fillQAplot(collision, hyperon, antiHyperon, 2); + } + } + + // function to check that the hyperon and antihyperon have different daughter tracks + template + bool checkTrackIndices(THyperon hyperon, THyperon antiHyperon) + { + if constexpr (requires { hyperon.template bachTrackExtra_as(); }) { // cascade case: check if bachelor information is available + // check that bachelor track from hyperon is different from daughter tracks of antiHyperon + if (hyperon.bachTrackExtraId() == antiHyperon.bachTrackExtraId() || + hyperon.bachTrackExtraId() == antiHyperon.posTrackExtraId() || + hyperon.bachTrackExtraId() == antiHyperon.negTrackExtraId()) + return false; + // check that positive track from hyperon is different from daughter tracks of antiHyperon + if (hyperon.posTrackExtraId() == antiHyperon.bachTrackExtraId() || + hyperon.posTrackExtraId() == antiHyperon.posTrackExtraId() || + hyperon.posTrackExtraId() == antiHyperon.negTrackExtraId()) + return false; + // check that negative track from hyperon is different from daughter tracks of antiHyperon + if (hyperon.negTrackExtraId() == antiHyperon.bachTrackExtraId() || + hyperon.negTrackExtraId() == antiHyperon.posTrackExtraId() || + hyperon.negTrackExtraId() == antiHyperon.negTrackExtraId()) + return false; + } else { // v0 case + // check that positive track from hyperon is different from daughter tracks of antiHyperon + if (hyperon.posTrackExtraId() == antiHyperon.posTrackExtraId() || + hyperon.posTrackExtraId() == antiHyperon.negTrackExtraId()) + return false; + // check that negative track from hyperon is different from daughter tracks of antiHyperon + if (hyperon.negTrackExtraId() == antiHyperon.posTrackExtraId() || + hyperon.negTrackExtraId() == antiHyperon.negTrackExtraId()) + return false; + } + return true; + } + + template + void buildHyperonAntiHyperonPairs(TCollision const& collision, THyperons const& fullHyperons, std::vector selHypIndices, std::vector selAntiHypIndices, float centrality, uint8_t gapSide, int type) + { + // 1st loop over all v0s/cascades + for (auto& hyperon : fullHyperons) { + // select only v0s matching Lambda selections + if (!selHypIndices[hyperon.globalIndex() - fullHyperons.offset()]) { // local index needed due to collisions grouping + continue; + } + + // 2nd loop over all v0s/cascade + for (auto& antiHyperon : fullHyperons) { + // select only v0s matching Anti-Lambda selections + if (!selAntiHypIndices[antiHyperon.globalIndex() - fullHyperons.offset()]) { // local index needed due to collisions grouping + continue; + } + + // check we don't look at the same v0s/cascades + if (hyperon.globalIndex() == antiHyperon.globalIndex()) { + continue; + } + + // check that the two hyperons have different daughter tracks + if (!checkTrackIndices(hyperon, antiHyperon)) { + continue; + } + + // form V0 pairs and fill histograms + analyseHyperonPairCandidate(collision, hyperon, antiHyperon, centrality, gapSide, type); + } // end antiHyperon loop + } // end hyperon loop + + return; + } + + // ______________________________________________________ + // Real data processing - no MC subscription + void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, cascadeCandidates const& fullCascades, dauTracks const&) + { + // Fire up CCDB + if ((mlConfigurations.useK0ShortScores && mlConfigurations.calculateK0ShortScores) || + (mlConfigurations.useLambdaScores && mlConfigurations.calculateLambdaScores) || + (mlConfigurations.useAntiLambdaScores && mlConfigurations.calculateAntiLambdaScores)) { + initCCDB(collision); + } + + if (!IsEventAccepted(collision, true)) { + return; + } + + float centrality = -1; + int selGapSide = -1; // only useful in case one wants to use this task in Pb-Pb UPC + fillEventHistograms(collision, centrality, selGapSide); + + // __________________________________________ + // perform main analysis + // + if (buildLaLaBarPairs) { // Look at V0s + std::vector selK0ShortIndices(fullV0s.size()); + std::vector selLambdaIndices(fullV0s.size()); + std::vector selAntiLambdaIndices(fullV0s.size()); + for (auto& v0 : fullV0s) { + if (std::abs(v0.negativeeta()) > v0Selections.daughterEtaCut || std::abs(v0.positiveeta()) > v0Selections.daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + if (v0.v0Type() != v0Selections.v0TypeSelection && v0Selections.v0TypeSelection > -1) + continue; // skip V0s that are not standard + + uint64_t selMap = computeReconstructionBitmap(v0, collision, v0.yLambda(), v0.yK0Short(), v0.pt()); + + // consider for histograms for all species + selMap = selMap | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selConsiderAntiLambda); + selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda); + + analyseV0Candidate(v0, v0.pt(), centrality, selMap, selK0ShortIndices, selLambdaIndices, selAntiLambdaIndices, fullV0s.offset()); + } // end v0 loop + + // count the number of K0s, Lambda and AntiLambdas passsing the selections + int nK0Shorts = std::count(selK0ShortIndices.begin(), selK0ShortIndices.end(), true); + int nLambdas = std::count(selLambdaIndices.begin(), selLambdaIndices.end(), true); + int nAntiLambdas = std::count(selAntiLambdaIndices.begin(), selAntiLambdaIndices.end(), true); + + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + histos.fill(HIST("LaLaBar/h2dNbrOfK0ShortVsCentrality"), centrality, nK0Shorts); + histos.fill(HIST("LaLaBar/h2dNbrOfLambdaVsCentrality"), centrality, nLambdas); + histos.fill(HIST("LaLaBar/h2dNbrOfAntiLambdaVsCentrality"), centrality, nAntiLambdas); + + // Check the number of Lambdas and antiLambdas + // needs at least 1 of each + if (nLambdas >= 1 && nAntiLambdas >= 1) { + buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 0); + } + } + + if (buildXiXiBarPairs || buildOmOmBarPairs) { // Look at Cascades + std::vector selXiIndices(fullCascades.size()); + std::vector selAntiXiIndices(fullCascades.size()); + std::vector selOmIndices(fullCascades.size()); + std::vector selAntiOmIndices(fullCascades.size()); + for (auto& cascade : fullCascades) { + if (std::abs(cascade.negativeeta()) > cascSelections.daughterEtaCut || + std::abs(cascade.positiveeta()) > cascSelections.daughterEtaCut || + std::abs(cascade.bacheloreta()) > cascSelections.daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + if (buildXiXiBarPairs) { + if (cascade.sign() < 0) { + selXiIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, cascade.yXi(), true); + } else { + selAntiXiIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, cascade.yXi(), true); + } + } + if (buildOmOmBarPairs) { + if (cascade.sign() < 0) { + selOmIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, cascade.yOmega(), false); + } else { + selAntiOmIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, cascade.yOmega(), false); + } + } + } // end cascade loop + + // count the number of Xi and antiXi passsing the selections + int nXis = std::count(selXiIndices.begin(), selXiIndices.end(), true); + int nAntiXis = std::count(selAntiXiIndices.begin(), selAntiXiIndices.end(), true); + int nOmegas = std::count(selOmIndices.begin(), selOmIndices.end(), true); + int nAntiOmegas = std::count(selAntiOmIndices.begin(), selAntiOmIndices.end(), true); + + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + if (buildXiXiBarPairs) { + histos.fill(HIST("XiXiBar/h2dNbrOfXiVsCentrality"), centrality, nXis); + histos.fill(HIST("XiXiBar/h2dNbrOfAntiXiVsCentrality"), centrality, nAntiXis); + + // Check the number of Lambdas and antiLambdas + // needs at least 1 of each + if (nXis >= 1 && nAntiXis >= 1) { + buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selAntiXiIndices, centrality, selGapSide, 1); + } + } + if (buildOmOmBarPairs) { + histos.fill(HIST("OmOmBar/h2dNbrOfOmegaVsCentrality"), centrality, nOmegas); + histos.fill(HIST("OmOmBar/h2dNbrOfAntiOmegaVsCentrality"), centrality, nAntiOmegas); + + // Check the number of Lambdas and antiLambdas + // needs at least 1 of each + if (nOmegas >= 1 && nAntiOmegas >= 1) { + buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selAntiOmIndices, centrality, selGapSide, 2); + } + } + } + } + + // ______________________________________________________ + // Simulated processing (subscribes to MC information too) + void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, cascadeMCCandidates const& fullCascades, dauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&, soa::Join const&) + { + // Fire up CCDB + if ((mlConfigurations.useK0ShortScores && mlConfigurations.calculateK0ShortScores) || + (mlConfigurations.useLambdaScores && mlConfigurations.calculateLambdaScores) || + (mlConfigurations.useAntiLambdaScores && mlConfigurations.calculateAntiLambdaScores)) { + initCCDB(collision); + } + + if (!IsEventAccepted(collision, true)) { + return; + } + + float centrality = -1; + int selGapSide = -1; // only useful in case one wants to use this task in Pb-Pb UPC + fillEventHistograms(collision, centrality, selGapSide); + + // __________________________________________ + // perform main analysis + if (buildLaLaBarPairs) { // Look at V0s + std::vector selK0ShortIndices(fullV0s.size()); + std::vector selLambdaIndices(fullV0s.size()); + std::vector selAntiLambdaIndices(fullV0s.size()); + for (auto& v0 : fullV0s) { + if (std::abs(v0.negativeeta()) > v0Selections.daughterEtaCut || std::abs(v0.positiveeta()) > v0Selections.daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + if (!v0.has_v0MCCore()) + continue; + + auto v0MC = v0.v0MCCore_as>(); + + float ptmc = RecoDecay::sqrtSumOfSquares(v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC()); + float ymc = 1e-3; + if (v0MC.pdgCode() == 310) + ymc = RecoDecay::y(std::array{v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC(), v0MC.pzPosMC() + v0MC.pzNegMC()}, o2::constants::physics::MassKaonNeutral); + else if (TMath::Abs(v0MC.pdgCode()) == 3122) + ymc = RecoDecay::y(std::array{v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC(), v0MC.pzPosMC() + v0MC.pzNegMC()}, o2::constants::physics::MassLambda); + + uint64_t selMap = computeReconstructionBitmap(v0, collision, ymc, ymc, ptmc); + selMap = selMap | computeMCAssociation(v0MC); + + // consider only associated candidates if asked to do so, disregard association + if (!doMCAssociation) { + selMap = selMap | (uint64_t(1) << selConsiderK0Short) | (uint64_t(1) << selConsiderLambda) | (uint64_t(1) << selConsiderAntiLambda); + selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda); + } + + analyseV0Candidate(v0, ptmc, centrality, selMap, selK0ShortIndices, selLambdaIndices, selAntiLambdaIndices, fullV0s.offset()); + } // end v0 loop + + /// count the number of K0s, Lambda and AntiLambdas passsing the selections + int nK0Shorts = std::count(selK0ShortIndices.begin(), selK0ShortIndices.end(), true); + int nLambdas = std::count(selLambdaIndices.begin(), selLambdaIndices.end(), true); + int nAntiLambdas = std::count(selAntiLambdaIndices.begin(), selAntiLambdaIndices.end(), true); + + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + histos.fill(HIST("LaLaBar/h2dNbrOfK0ShortVsCentrality"), centrality, nK0Shorts); + histos.fill(HIST("LaLaBar/h2dNbrOfLambdaVsCentrality"), centrality, nLambdas); + histos.fill(HIST("LaLaBar/h2dNbrOfAntiLambdaVsCentrality"), centrality, nAntiLambdas); + + if (nLambdas >= 1 && nAntiLambdas >= 1) { + buildHyperonAntiHyperonPairs(collision, fullV0s, selLambdaIndices, selAntiLambdaIndices, centrality, selGapSide, 0); + } + } + + if (buildXiXiBarPairs || buildOmOmBarPairs) { // Look at Cascades + std::vector selXiIndices(fullCascades.size()); + std::vector selAntiXiIndices(fullCascades.size()); + std::vector selOmIndices(fullCascades.size()); + std::vector selAntiOmIndices(fullCascades.size()); + for (auto& cascade : fullCascades) { + if (std::abs(cascade.negativeeta()) > cascSelections.daughterEtaCut || + std::abs(cascade.positiveeta()) > cascSelections.daughterEtaCut || + std::abs(cascade.bacheloreta()) > cascSelections.daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + if (!cascade.has_cascMCCore()) + continue; + + auto cascadeMC = cascade.cascMCCore_as>(); + + // float ptmc = RecoDecay::sqrtSumOfSquares(cascadeMC.pxMC(), cascadeMC.pyMC()); + float ymc = 1e-3; + if (TMath::Abs(cascadeMC.pdgCode()) == 3312) + ymc = RecoDecay::y(std::array{cascadeMC.pxMC(), cascadeMC.pyMC(), cascadeMC.pzMC()}, o2::constants::physics::MassXiMinus); + else if (TMath::Abs(cascadeMC.pdgCode()) == 3334) + ymc = RecoDecay::y(std::array{cascadeMC.pxMC(), cascadeMC.pyMC(), cascadeMC.pzMC()}, o2::constants::physics::MassOmegaMinus); + + if (buildXiXiBarPairs) { + if (cascade.sign() < 0) { + selXiIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, ymc, true); + } else { + selAntiXiIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, ymc, true); + } + } + if (buildOmOmBarPairs) { + if (cascade.sign() < 0) { + selOmIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, ymc, false); + } else { + selAntiOmIndices[cascade.globalIndex() - fullCascades.offset()] = isCascadeSelected(cascade, collision, ymc, false); + } + } + } // end cascade loop + + // count the number of Xi and antiXi passsing the selections + int nXis = std::count(selXiIndices.begin(), selXiIndices.end(), true); + int nAntiXis = std::count(selAntiXiIndices.begin(), selAntiXiIndices.end(), true); + int nOmegas = std::count(selOmIndices.begin(), selOmIndices.end(), true); + int nAntiOmegas = std::count(selAntiOmIndices.begin(), selAntiOmIndices.end(), true); + + // fill the histograms with the number of reconstructed K0s/Lambda/antiLambda per collision + if (buildXiXiBarPairs) { + histos.fill(HIST("XiXiBar/h2dNbrOfXiVsCentrality"), centrality, nXis); + histos.fill(HIST("XiXiBar/h2dNbrOfAntiXiVsCentrality"), centrality, nAntiXis); + + // Check the number of Lambdas and antiLambdas + // needs at least 1 of each + if (nXis >= 1 && nAntiXis >= 1) { + buildHyperonAntiHyperonPairs(collision, fullCascades, selXiIndices, selAntiXiIndices, centrality, selGapSide, 1); + } + } + if (buildOmOmBarPairs) { + histos.fill(HIST("OmOmBar/h2dNbrOfOmegaVsCentrality"), centrality, nOmegas); + histos.fill(HIST("OmOmBar/h2dNbrOfAntiOmegaVsCentrality"), centrality, nAntiOmegas); + + // Check the number of Lambdas and antiLambdas + // needs at least 1 of each + if (nOmegas >= 1 && nAntiOmegas >= 1) { + buildHyperonAntiHyperonPairs(collision, fullCascades, selOmIndices, selAntiOmIndices, centrality, selGapSide, 2); + } + } + } + } + + PROCESS_SWITCH(quarkoniaToHyperons, processRealData, "process as if real data", true); + PROCESS_SWITCH(quarkoniaToHyperons, processMonteCarlo, "process as if MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 7f871927ece..b7bd4639aba 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -116,6 +116,7 @@ using MyEventsSelected = soa::Join; using MyEventsVtxCov = soa::Join; using MyEventsVtxCovSelected = soa::Join; +using MyEventsVtxCovSelectedMultExtra = soa::Join; using MyEventsVtxCovSelectedQvector = soa::Join; using MyEventsVtxCovSelectedQvectorExtraWithRefFlow = soa::Join; using MyEventsVtxCovSelectedQvectorCentr = soa::Join; @@ -146,6 +147,7 @@ using MyMftTracks = soa::Join; constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended; constexpr static uint32_t gkEventFillMapWithCov = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov; constexpr static uint32_t gkEventFillMapWithQvector = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventQvector; +constexpr static uint32_t gkEventFillMapWithMultExtra = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventMultExtra; constexpr static uint32_t gkEventFillMapWithQvectorMultExtra = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventQvector | VarManager::ObjTypes::ReducedEventMultExtra; constexpr static uint32_t gkEventFillMapWithQvectorCentr = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::CollisionQvect; constexpr static uint32_t gkEventFillMapWithQvectorCentrMultExtra = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::CollisionQvect | VarManager::ObjTypes::ReducedEventMultExtra; @@ -1069,7 +1071,7 @@ struct AnalysisSameEventPairing { } // end if (track cuts) } - if (context.mOptions.get("processDecayToMuMuSkimmed") || context.mOptions.get("processDecayToMuMuVertexingSkimmed") || context.mOptions.get("processDecayToMuMuSkimmedWithColl") || context.mOptions.get("processVnDecayToMuMuSkimmed") || context.mOptions.get("processVnDecayToMuMuSkimmedWithWeights") || context.mOptions.get("processVnDecayToMuMuSkimmedWithWeightsAndColl") || context.mOptions.get("processVnCentrDecayToMuMuSkimmed") || context.mOptions.get("processAllSkimmed")) { + if (context.mOptions.get("processDecayToMuMuSkimmed") || context.mOptions.get("processDecayToMuMuSkimmedWithMult") || context.mOptions.get("processDecayToMuMuVertexingSkimmed") || context.mOptions.get("processDecayToMuMuSkimmedWithColl") || context.mOptions.get("processVnDecayToMuMuSkimmed") || context.mOptions.get("processVnDecayToMuMuSkimmedWithWeights") || context.mOptions.get("processVnDecayToMuMuSkimmedWithWeightsAndColl") || context.mOptions.get("processVnCentrDecayToMuMuSkimmed") || context.mOptions.get("processAllSkimmed")) { TString cutNames = fConfigMuonCuts.value; if (!cutNames.IsNull()) { std::unique_ptr objArray(cutNames.Tokenize(",")); @@ -1477,6 +1479,13 @@ struct AnalysisSameEventPairing { VarManager::FillEvent(event, VarManager::fgValues); runSameEventPairing(event, muons, muons); } + void processDecayToMuMuSkimmedWithMult(soa::Filtered::iterator const& event, soa::Filtered const& muons) + { + // Reset the fValues array + VarManager::ResetValues(0, VarManager::kNVars); + VarManager::FillEvent(event, VarManager::fgValues); + runSameEventPairing(event, muons, muons); + } void processDecayToMuMuVertexingSkimmed(soa::Filtered::iterator const& event, soa::Filtered const& muons) { // Reset the fValues array @@ -1567,6 +1576,7 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithColl, "Run electron-electron pairing, with skimmed tracks and with collision information", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmedWithCollNoTwoProngFitter, "Run electron-electron pairing, with skimmed tracks and with collision information but no two prong fitter", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmed, "Run muon-muon pairing, with skimmed muons", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmedWithMult, "Run muon-muon pairing, with skimmed muons and multiplicity", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuVertexingSkimmed, "Run muon-muon pairing and vertexing, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToMuMuSkimmedWithColl, "Run muon-muon pairing keeping the info of AO2D collision, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processVnDecayToEESkimmed, "Run electron-electron pairing, with skimmed tracks for vn", false); diff --git a/PWGDQ/Tasks/taskFwdTrackPid.cxx b/PWGDQ/Tasks/taskFwdTrackPid.cxx index ce173ecf314..7a135596d56 100644 --- a/PWGDQ/Tasks/taskFwdTrackPid.cxx +++ b/PWGDQ/Tasks/taskFwdTrackPid.cxx @@ -31,6 +31,8 @@ #include "PWGDQ/Core/VarManager.h" #include "PWGDQ/Core/HistogramManager.h" #include "PWGDQ/Core/MixingHandler.h" +#include "PWGDQ/Core/MCSignal.h" +#include "PWGDQ/Core/MCSignalLibrary.h" #include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" #include "PWGDQ/Core/HistogramsLibrary.h" @@ -50,36 +52,100 @@ using namespace o2::framework::expressions; using namespace o2::aod; using MyEvents = soa::Join; +using MyEventsMC = soa::Join; using MyMuonTracks = soa::Join; +using MyMuonTracksMC = soa::Join; using MyMftTracks = soa::Join; +using MyMftTracksMC = soa::Join; // bit maps used for the Fill functions of the VarManager constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended; +constexpr static uint32_t gkMCEventFillMap = VarManager::ObjTypes::ReducedEventMC; constexpr static uint32_t gkMuonFillMap = VarManager::ObjTypes::ReducedMuon | VarManager::ObjTypes::ReducedMuonExtra; +void DefineHistograms(HistogramManager* histMan, TString histClasses); + struct taskFwdTrackPid { Produces fwdPidAllList; + HistogramManager* fHistMan; + OutputObj fOutputList{"output"}; + Configurable fConfigMaxDCA{"cfgMaxDCA", 0.5f, "Manually set maximum DCA of the track"}; Configurable downSampleFactor{"downSampleFactor", 1., "Fraction of candidates to keep for ML"}; + Configurable fConfigMCGenSignals{"cfgMCGenSignals", "", "Comma separated list of MC signals (generated)"}; + Configurable fConfigMCRecSignals{"cfgMCRecSignals", "", "Comma separated list of MC signals (reconstructed)"}; + + std::vector fGenMCSignalsNames; + std::vector fRecMCSignalsNames; + std::vector fGenMCSignals; + std::vector fRecMCSignals; void init(o2::framework::InitContext& context) { if (context.mOptions.get("processDummy")) { return; } + + fHistMan = new HistogramManager("analysisHistos", "aa", VarManager::kNVars); + fHistMan->SetUseDefaultVariableNames(kTRUE); + fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); + + TString histNames = ""; + + TString sigGenNamesStr = fConfigMCGenSignals.value; + std::unique_ptr objGenSigArray(sigGenNamesStr.Tokenize(",")); + for (int isig = 0; isig < objGenSigArray->GetEntries(); isig++) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objGenSigArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() == 1) { // NOTE: 1-prong signals required + fGenMCSignals.push_back(*sig); + histNames += Form("MCTruthGen_%s;", sig->GetName()); // TODO: Add these names to a std::vector to avoid using Form in the process function + } + } + } + + DefineHistograms(fHistMan, histNames.Data()); // define all histograms + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + fOutputList.setObject(fHistMan->GetMainHistogramList()); + + TString sigNamesStr = fConfigMCRecSignals.value; + std::unique_ptr objRecSigArray(sigNamesStr.Tokenize(",")); + if (!sigNamesStr.IsNull()) { + for (int isig = 0; isig < objRecSigArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objRecSigArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() == 1) { + fRecMCSignals.push_back(*sig); + fRecMCSignalsNames.push_back(sig->GetName()); + } + } + } + } + // Setting the MC rec signal names + for (int isig = 0; isig < objRecSigArray->GetEntries(); ++isig) { + MCSignal* sig = o2::aod::dqmcsignals::GetMCSignal(objRecSigArray->At(isig)->GetName()); + if (sig) { + if (sig->GetNProngs() != 1) { // NOTE: 2-prong signals required + continue; + } + fRecMCSignals.push_back(*sig); + } + } } // Template function to pair mft tracks and muon tracks template void runFwdTrackPid(TEvent const& event, Muons const& muons, MftTracks const& mftTracks) { + uint32_t mcDecision = 0; + 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()); + 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(), mcDecision); } } if constexpr (TMatchedOnly == false) { @@ -91,12 +157,75 @@ struct taskFwdTrackPid { continue; } } - 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); + 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, mcDecision); + } + } + } + } + + // Template function to run over reconstructed tracks + template + void runFwdTrackPidMC(TEvent const& event, Muons const& muons, MftTracks const& mftTracks, TEventsMC const& /*eventsMC*/, TTracksMC const& /*tracksMC*/) + { + fwdPidAllList.reserve(1); + for (const auto& muon : muons) { + uint32_t mcDecision = 0; + int isig = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if ((*sig).CheckSignal(false, muon.reducedMCTrack())) { + mcDecision |= (uint32_t(1) << isig); + } + } + + 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(), mcDecision); + } + } + + if constexpr (TMatchedOnly == false) { + for (const auto& mftTrack : mftTracks) { + uint32_t mcDecision = 0; + int isig = 0; + for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) { + if ((*sig).CheckSignal(false, mftTrack.reducedMCTrack())) { + mcDecision |= (uint32_t(1) << isig); + } + } + 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, mcDecision); + } + } + } + } + + // Template function to run over MC tracks + template + void runMCGen(TTracksMC& groupedMCTracks) + { + for (auto& mctrack : groupedMCTracks) { + VarManager::FillTrackMC(groupedMCTracks, mctrack); + + for (auto& sig : fGenMCSignals) { + if (sig.GetNProngs() != 1) { // NOTE: 1-prong signals required + continue; + } + bool checked = false; + if constexpr (soa::is_soa_filtered_v) { + auto mctrack_raw = groupedMCTracks.rawIteratorAt(mctrack.globalIndex()); + checked = sig.CheckSignal(false, mctrack_raw); + } else { + checked = sig.CheckSignal(false, mctrack); + } + if (checked) { + fHistMan->FillHistClass(Form("MCTruthGen_%s", sig.GetName()), VarManager::fgValues); } } } } + PresliceUnsorted perReducedMcEvent = aod::reducedtrackMC::reducedMCeventId; + void processFwdPidMatched(MyEvents::iterator const& event, MyMuonTracks const& muons, MyMftTracks const& mftTracks) { if (muons.size() > 0 && mftTracks.size() > 0) { @@ -111,6 +240,25 @@ struct taskFwdTrackPid { } } + void processFwdPidMatchedMC(MyEventsMC::iterator const& event, MyMuonTracksMC const& muons, MyMftTracksMC const& mftTracks, ReducedMCEvents const& eventsMC, ReducedMCTracks const& tracksMC) + { + if (muons.size() > 0 && mftTracks.size() > 0) { + runFwdTrackPidMC(event, muons, mftTracks, eventsMC, tracksMC); + } + auto groupedMCTracks = tracksMC.sliceBy(perReducedMcEvent, event.reducedMCevent().globalIndex()); + groupedMCTracks.bindInternalIndicesTo(&tracksMC); + runMCGen(groupedMCTracks); + } + void processFwdPidMatchedOnlyMC(MyEventsMC::iterator const& event, MyMuonTracksMC const& muons, MyMftTracksMC const& mftTracks, ReducedMCEvents const& eventsMC, ReducedMCTracks const& tracksMC) + { + if (muons.size() > 0) { + runFwdTrackPidMC(event, muons, mftTracks, eventsMC, tracksMC); + } + auto groupedMCTracks = tracksMC.sliceBy(perReducedMcEvent, event.reducedMCevent().globalIndex()); + groupedMCTracks.bindInternalIndicesTo(&tracksMC); + runMCGen(groupedMCTracks); + } + void processDummy(MyEvents&) { // do nothing @@ -118,6 +266,8 @@ struct taskFwdTrackPid { PROCESS_SWITCH(taskFwdTrackPid, processFwdPidMatched, "Run MFT - muon track pairing filling tree with MFT and global tracks", false); PROCESS_SWITCH(taskFwdTrackPid, processFwdPidMatchedOnly, "Run MFT - muon track pairing filling tree with global tracks only", false); + PROCESS_SWITCH(taskFwdTrackPid, processFwdPidMatchedMC, "Run MFT - muon track pairing filling tree with MFT and global tracks and MC info", false); + PROCESS_SWITCH(taskFwdTrackPid, processFwdPidMatchedOnlyMC, "Run MFT - muon track pairing filling tree with global tracks only and MC info", false); PROCESS_SWITCH(taskFwdTrackPid, processDummy, "Dummy function", false); }; // End of struct taskFwdTrackPid @@ -126,3 +276,21 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) return WorkflowSpec{ adaptAnalysisTask(cfgc)}; } + +void DefineHistograms(HistogramManager* histMan, TString histClasses) +{ + std::unique_ptr objArray(histClasses.Tokenize(";")); + for (Int_t iclass = 0; iclass < objArray->GetEntries(); ++iclass) { + TString classStr = objArray->At(iclass)->GetName(); + histMan->AddHistClass(classStr.Data()); + + if (classStr.Contains("MCTruthGen")) { + dqhistograms::DefineHistograms(histMan, objArray->At(iclass)->GetName(), "mctruth"); + histMan->AddHistogram(objArray->At(iclass)->GetName(), "Pt_Rapidity", "MC generator p_{T}, y distribution", false, 120, 0.0, 30.0, VarManager::kMCPt, 150, 2.5, 4.0, VarManager::kMCY); + histMan->AddHistogram(objArray->At(iclass)->GetName(), "Eta", "MC generator #eta distribution", false, 200, 2.5, 4.0, VarManager::kMCEta); + // histMan->AddHistogram(objArray->At(iclass)->GetName(), "Rapidity", "MC generator y distribution", false, 150, 2.5, 4.0, VarManager::kMCY); + histMan->AddHistogram(objArray->At(iclass)->GetName(), "Phi", "MC generator #varphi distribution", false, 50, 0.0, 2. * TMath::Pi(), VarManager::kMCPhi); + } + + } // end loop over histogram classes +} diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index b44ccc37b61..ac3b6d2bb5b 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -86,7 +86,8 @@ class DielectronCut : public TNamed kTPChadrejORTOFreq = 2, kTPConly = 3, kTOFif = 4, - kPIDML = 5 + kPIDML = 5, + kTPChadrejORTOFreq_woTOFif = 6 }; template @@ -285,6 +286,9 @@ class DielectronCut : public TNamed case static_cast(PIDSchemes::kPIDML): return true; // don't use kPIDML here. + case static_cast(PIDSchemes::kTPChadrejORTOFreq_woTOFif): + return PassTPConlyhadrej(track) || PassTOFreq(track); + case static_cast(PIDSchemes::kUnDef): return true; @@ -321,6 +325,17 @@ class DielectronCut : public TNamed return is_el_included_TPC; } + template + bool PassTPConlyhadrej(T const& track) const + { + bool is_el_included_TPC = mMinTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; + bool is_mu_excluded_TPC = mMuonExclusionTPC ? track.tpcNSigmaMu() < mMinTPCNsigmaMu || mMaxTPCNsigmaMu < track.tpcNSigmaMu() : true; + bool is_pi_excluded_TPC = track.tpcInnerParam() < mMaxPinForPionRejectionTPC ? (track.tpcNSigmaPi() < mMinTPCNsigmaPi || mMaxTPCNsigmaPi < track.tpcNSigmaPi()) : true; + bool is_ka_excluded_TPC = track.tpcNSigmaKa() < mMinTPCNsigmaKa || mMaxTPCNsigmaKa < track.tpcNSigmaKa(); + bool is_pr_excluded_TPC = track.tpcNSigmaPr() < mMinTPCNsigmaPr || mMaxTPCNsigmaPr < track.tpcNSigmaPr(); + return is_el_included_TPC && is_mu_excluded_TPC && is_pi_excluded_TPC && is_ka_excluded_TPC && is_pr_excluded_TPC; + } + template bool PassTOFif(T const& track) const { diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index 1df6951ceb6..1efa2cfe50f 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -39,7 +39,9 @@ #include "CommonConstants/LHCConstants.h" #include "DataFormatsParameters/GRPLHCIFData.h" #include "DataFormatsParameters/GRPECSObject.h" +#include "MathUtils/Utils.h" +#include "DetectorsBase/Propagator.h" #include "DetectorsBase/GeometryManager.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" @@ -117,7 +119,7 @@ struct Dilepton { Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", static_cast(1e+9), "max. multNTracksPV"}; Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; - Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; + Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; Configurable cfgUseSignedDCA{"cfgUseSignedDCA", false, "flag to use signs in the DCA calculation"}; ConfigurableAxis ConfMllBins{"ConfMllBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; @@ -173,9 +175,13 @@ struct Dilepton { Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; + Configurable cfg_apply_detadphi_geom{"cfg_apply_detadphi_geom", false, "flag to apply generator deta-dphi elliptic cut"}; + Configurable cfg_min_deta_geom{"cfg_min_deta_geom", 0.02, "geometrical min deta between 2 electrons (elliptic cut)"}; + Configurable cfg_min_dphi_geom{"cfg_min_dphi_geom", 0.2, "geometrical min dphi between 2 electrons (elliptic cut)"}; Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; Configurable cfg_max_opang{"cfg_max_opang", 6.4, "max opening angle"}; Configurable cfg_require_diff_sides{"cfg_require_diff_sides", false, "flag to require 2 tracks are from different sides."}; + Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for single track"}; @@ -200,7 +206,7 @@ struct Dilepton { Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; - Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif = 4, kPIDML = 5]"}; + Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5, kTPChadrejORTOFreq_woTOFif : 6]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron inclusion"}; Configurable cfg_min_TPCNsigmaMu{"cfg_min_TPCNsigmaMu", -0.0, "min. TPC n sigma for muon exclusion"}; @@ -242,7 +248,7 @@ struct Dilepton { Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 muons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.02, "min dphi between 2 muons (elliptic cut)"}; - Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.1, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; @@ -265,7 +271,7 @@ struct Dilepton { float d_bz; // o2::vertexing::DCAFitterN<2> fitter; // o2::vertexing::FwdDCAFitterN<2> fwdfitter; - // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; static constexpr std::string_view event_cut_types[2] = {"before/", "after/"}; @@ -420,6 +426,7 @@ struct Dilepton { if (fabs(d_bz) > 1e-5) { grpmag.setL3Current(30000.f / (d_bz / 5.0f)); } + o2::base::Propagator::initFieldFromGRP(&grpmag); mRunNumber = collision.runNumber(); // fitter.setBz(d_bz); // fwdfitter.setBz(d_bz); @@ -432,6 +439,7 @@ struct Dilepton { if (!skipGRPOquery) grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); // Fetch magnetic field from ccdb for current collision d_bz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -440,6 +448,7 @@ struct Dilepton { if (!grpmag) { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; } + o2::base::Propagator::initFieldFromGRP(grpmag); // Fetch magnetic field from ccdb for current collision d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -519,8 +528,8 @@ struct Dilepton { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kQC)) { fRegistry.add("Pair/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca}, true); - fRegistry.add("Pair/same/uls/hsDeltaP", "difference of p between 2 tracks;|p_{T,1} - p_{T,2}|/|p_{T,1} + p_{T,2}|;#Delta#eta;#Delta#varphi (rad.);", kTHnSparseD, {{20, 0, 1}, {100, -0.5, +0.5}, {100, -0.5, 0.5}}, true); - + fRegistry.add("Pair/same/uls/hsDeltaP", "difference of p between 2 tracks;|p_{T,1} - p_{T,2}|/|p_{T,1} + p_{T,2}|;#Delta#eta;#Delta#varphi (rad.);", kTHnSparseD, {{20, 0, 1}, {100, -0.5, +0.5}, {180, -M_PI, M_PI}}, true); + fRegistry.add("Pair/same/uls/hGeomDeltaEtaDeltaPhi", Form("difference in #eta-#varphi plane between 2 tracks at X = %2.1f cm;#Delta#varphi (rad.);#Delta#eta;", dielectroncuts.cfg_x_to_go.value), kTH2D, {{180, -M_PI, M_PI}, {100, -0.5, +0.5}}, true); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.add("Pair/same/uls/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2D, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); // phiv is only for dielectron fRegistry.add("Pair/same/uls/hMvsOpAng", "m_{ee} vs. angle between 2 tracks;#omega (rad.);m_{ee} (GeV/c^{2})", kTH2D, {{100, 0, 2.0}, {20, 0.0f, 3.2}}, true); @@ -767,6 +776,26 @@ struct Dilepton { } } + std::map, float> map_eta_geom; // map -> geometrical eta position at propagated point + std::map, float> map_phi_geom; // map -> geometrical phi position at propagated point + + template + void propagateElectron(TTracks const& tracks) + { + // this has to be called after initCCDB for bz. + for (auto& track : tracks) { + auto track_par_cov = getTrackParCov(track); + track_par_cov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToX(track_par_cov, dielectroncuts.cfg_x_to_go, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); + auto xyz = track_par_cov.getXYZGlo(); + float eta = RecoDecay::eta(std::array{xyz.X(), xyz.Y(), xyz.Z()}); + float phi = RecoDecay::phi(std::array{xyz.X(), xyz.Y()}); + o2::math_utils::bringTo02Pi(phi); + map_eta_geom[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = eta; + map_phi_geom[std::make_tuple(ndf, track.emeventId(), track.globalIndex())] = phi; + } + } + template bool fillPairInfo(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut) { @@ -812,10 +841,23 @@ struct Dilepton { } } + float deta_geom = 999.f, dphi_geom = 999.f; if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + + if constexpr (ev_id == 0) { + deta_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_eta_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_eta_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_eta_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_eta_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; + dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_phi_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_phi_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_phi_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_phi_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; + } else { // mixed event + deta_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_eta_geom[std::make_tuple(t1.dfId(), t1.collisionId(), t1.globalIndex())] - map_eta_geom[std::make_tuple(t2.dfId(), t2.collisionId(), t2.globalIndex())] : map_eta_geom[std::make_tuple(t2.dfId(), t2.collisionId(), t2.globalIndex())] - map_eta_geom[std::make_tuple(t1.dfId(), t1.collisionId(), t1.globalIndex())]; + dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_phi_geom[std::make_tuple(t1.dfId(), t1.collisionId(), t1.globalIndex())] - map_phi_geom[std::make_tuple(t2.dfId(), t2.collisionId(), t2.globalIndex())] : map_phi_geom[std::make_tuple(t2.dfId(), t2.collisionId(), t2.globalIndex())] - map_phi_geom[std::make_tuple(t1.dfId(), t1.collisionId(), t1.globalIndex())]; + } + o2::math_utils::bringToPMPi(dphi_geom); + if (dielectroncuts.cfg_x_to_go > 0.f && dielectroncuts.cfg_apply_detadphi_geom && std::pow(deta_geom / dielectroncuts.cfg_min_deta_geom, 2) + std::pow(dphi_geom / dielectroncuts.cfg_min_dphi_geom, 2) < 1.f) { + return false; + } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.template IsSelectedPair(t1, t2)) { return false; @@ -869,12 +911,14 @@ struct Dilepton { float deta = t1.sign() * v1.Pt() > t2.sign() * v2.Pt() ? v1.Eta() - v2.Eta() : v2.Eta() - v1.Eta(); float dphi = t1.sign() * v1.Pt() > t2.sign() * v2.Pt() ? v1.Phi() - v2.Phi() : v2.Phi() - v1.Phi(); o2::math_utils::bringToPMPi(dphi); + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), d_bz); float opAng = o2::aod::pwgem::dilepton::utils::pairutil::getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); if (t1.sign() * t2.sign() < 0) { // ULS fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hsDeltaP"), dpt, deta, dphi, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hGeomDeltaEtaDeltaPhi"), dphi_geom, deta_geom, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hMvsOpAng"), opAng, v12.M(), weight); @@ -882,6 +926,7 @@ struct Dilepton { } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hsDeltaP"), dpt, deta, dphi, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hGeomDeltaEtaDeltaPhi"), dphi_geom, deta_geom, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hMvsOpAng"), opAng, v12.M(), weight); @@ -889,6 +934,7 @@ struct Dilepton { } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hsDeltaP"), dpt, deta, dphi, weight); + fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hGeomDeltaEtaDeltaPhi"), dphi_geom, deta_geom, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsPhiV"), phiv, v12.M(), weight); fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hMvsOpAng"), opAng, v12.M(), weight); @@ -912,7 +958,6 @@ struct Dilepton { } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, aco, asym, abs(dphi_e_ee), abs(cos_thetaCS), weight); } - } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kFlowV2) || cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonAnalysisType::kFlowV3)) { std::array q2ft0m = {collision.q2xft0m(), collision.q2yft0m()}; std::array q2ft0a = {collision.q2xft0a(), collision.q2yft0a()}; @@ -940,13 +985,10 @@ struct Dilepton { float sp = RecoDecay::dotProd(std::array{static_cast(std::cos(nmod * v12.Phi())), static_cast(std::sin(nmod * v12.Phi()))}, qvectors[nmod][cfgQvecEstimator]) / getSPresolution(collision.centFT0C(), collision.trackOccupancyInTimeRange()); if (t1.sign() * t2.sign() < 0) { // ULS fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, sp, weight); - // fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("uls/hPrfUQ"), v12.M(), v12.Pt(), pair_dca, sp, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, sp, weight); - // fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hPrfUQ"), v12.M(), v12.Pt(), pair_dca, sp, weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, sp, weight); - // fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hPrfUQ"), v12.M(), v12.Pt(), pair_dca, sp, weight); } } else if constexpr (ev_id == 1) { if (t1.sign() * t2.sign() < 0) { // ULS @@ -1182,6 +1224,13 @@ struct Dilepton { auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); // LOGF(info, "collision.globalIndex() = %d , collision.posZ() = %f , collision.numContrib() = %d, centrality = %f , posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", collision.globalIndex(), collision.posZ(), collision.numContrib(), centralities[cfgCentEstimator], posTracks_per_coll.size(), negTracks_per_coll.size()); + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (dielectroncuts.cfg_x_to_go > 0.f) { + propagateElectron(posTracks_per_coll); + propagateElectron(negTracks_per_coll); + } + } + int nuls = 0, nlspp = 0, nlsmm = 0; for (auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS bool is_pair_ok = fillPairInfo<0>(collision, pos, neg, cut); @@ -1307,7 +1356,6 @@ struct Dilepton { } // end of collision loop - ndf++; } // end of DF template @@ -1333,6 +1381,12 @@ struct Dilepton { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + float deta_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_eta_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_eta_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_eta_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_eta_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; + float dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? map_phi_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())] - map_phi_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] : map_phi_geom[std::make_tuple(ndf, t2.emeventId(), t2.globalIndex())] - map_phi_geom[std::make_tuple(ndf, t1.emeventId(), t1.globalIndex())]; + o2::math_utils::bringToPMPi(dphi_geom); + if (dielectroncuts.cfg_x_to_go > 0.f && dielectroncuts.cfg_apply_detadphi_geom && std::pow(deta_geom / dielectroncuts.cfg_min_deta_geom, 2) + std::pow(dphi_geom / dielectroncuts.cfg_min_dphi_geom, 2) < 1.f) { + return false; + } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.template IsSelectedPair(t1, t2)) { return false; @@ -1391,6 +1445,12 @@ struct Dilepton { auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); + if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { + if (dielectroncuts.cfg_x_to_go > 0.f) { + propagateElectron(posTracks_per_coll); + propagateElectron(negTracks_per_coll); + } + } for (auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS if (isPairOK(collision, pos, neg, cut)) { @@ -1461,6 +1521,7 @@ struct Dilepton { runPairing(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut); } map_weight.clear(); + ndf++; } PROCESS_SWITCH(Dilepton, processAnalysis, "run dilepton analysis", true); @@ -1481,6 +1542,7 @@ struct Dilepton { runPairing(collisions, positive_muons, negative_muons, o2::aod::emprimarymuon::emeventId, fDimuonCut); } map_weight.clear(); + ndf++; } PROCESS_SWITCH(Dilepton, processTriggerAnalysis, "run dilepton analysis on triggered data", false); diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index 56367531a73..90db1237cc1 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -31,6 +31,7 @@ #include "DataFormatsParameters/GRPLHCIFData.h" #include "DataFormatsParameters/GRPECSObject.h" +#include "DetectorsBase/Propagator.h" #include "DetectorsBase/GeometryManager.h" #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" @@ -98,7 +99,7 @@ struct DileptonMC { Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", static_cast(1e+9), "max. multNTracksPV"}; Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; - Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; + Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; Configurable cfgFillUnfolding{"cfgFillUnfolding", false, "flag to fill histograms for unfolding"}; ConfigurableAxis ConfMllBins{"ConfMllBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; @@ -152,9 +153,13 @@ struct DileptonMC { Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; + Configurable cfg_apply_detadphi_geom{"cfg_apply_detadphi_geom", false, "flag to apply generator deta-dphi elliptic cut"}; + Configurable cfg_min_deta_geom{"cfg_min_deta_geom", 0.02, "geometrical min deta between 2 electrons (elliptic cut)"}; + Configurable cfg_min_dphi_geom{"cfg_min_dphi_geom", 0.2, "geometrical min dphi between 2 electrons (elliptic cut)"}; Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; Configurable cfg_max_opang{"cfg_max_opang", 6.4, "max opening angle"}; Configurable cfg_require_diff_sides{"cfg_require_diff_sides", false, "flag to require 2 tracks are from different sides."}; + Configurable cfg_x_to_go{"cfg_x_to_go", -1, "x (cm) to be propagated in local coordinate"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "max eta for single track"}; @@ -221,7 +226,7 @@ struct DileptonMC { Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 muons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.02, "min dphi between 2 muons (elliptic cut)"}; - Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.1, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; @@ -242,7 +247,7 @@ struct DileptonMC { Service ccdb; // o2::vertexing::DCAFitterN<2> fitter; // o2::vertexing::FwdDCAFitterN<2> fwdfitter; - // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; int mRunNumber; float d_bz; @@ -351,8 +356,9 @@ struct DileptonMC { fRegistry.addClone("Pair/sm/Photon/", "Pair/sm/NonPromptPsi2S/"); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - fRegistry.add("Pair/sm/Photon/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0.0f, 0.5f}}, true); - fRegistry.add("Pair/sm/Pi0/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0.0f, 0.5f}}, true); + fRegistry.add("Pair/sm/Photon/hGeomDeltaEtaDeltaPhi", Form("difference in #eta-#varphi plane between 2 tracks at X = %2.1f cm;#Delta#varphi (rad.);#Delta#eta;", dielectroncuts.cfg_x_to_go.value), kTH2D, {{90, -M_PI, M_PI}, {100, -0.5, +0.5}}, true); + fRegistry.add("Pair/sm/Photon/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); + fRegistry.add("Pair/sm/Pi0/hMvsPhiV", "m_{ee} vs. #varphi_{V};#varphi (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0.0f, 1.0f}}, true); } fRegistry.add("Pair/ccbar/c2l_c2l/hadron_hadron/hs", "hs pair", kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_cs, axis_phi_cs, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_dca}, true); @@ -461,6 +467,7 @@ struct DileptonMC { if (fabs(d_bz) > 1e-5) { grpmag.setL3Current(30000.f / (d_bz / 5.0f)); } + o2::base::Propagator::initFieldFromGRP(&grpmag); mRunNumber = collision.runNumber(); // fitter.setBz(d_bz); // fwdfitter.setBz(d_bz); @@ -473,6 +480,7 @@ struct DileptonMC { if (!skipGRPOquery) grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); // Fetch magnetic field from ccdb for current collision d_bz = grpo->getNominalL3Field(); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -481,6 +489,7 @@ struct DileptonMC { if (!grpmag) { LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; } + o2::base::Propagator::initFieldFromGRP(grpmag); // Fetch magnetic field from ccdb for current collision d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; @@ -684,9 +693,27 @@ struct DileptonMC { } } - template - bool fillTruePairInfo(TCollision const& collision, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TMCParticles const& mcparticles) + template + bool fillTruePairInfo(TCollision const& collision, TMCCollisions const&, TTrack1 const& t1, TTrack2 const& t2, TCut const& cut, TMCParticles const& mcparticles) { + auto t1mc = mcparticles.iteratorAt(t1.emmcparticleId()); + auto t2mc = mcparticles.iteratorAt(t2.emmcparticleId()); + bool is_from_same_mcevent = t1mc.emmceventId() == t2mc.emmceventId(); + + auto mccollision1 = t1mc.template emmcevent_as(); + auto mccollision2 = t2mc.template emmcevent_as(); + if (cfgEventGeneratorType >= 0 && mccollision1.getSubGeneratorId() != cfgEventGeneratorType) { + return false; + } + if (cfgEventGeneratorType >= 0 && mccollision2.getSubGeneratorId() != cfgEventGeneratorType) { + return false; + } + if (!isInAcceptance(t1mc) || !isInAcceptance(t2mc)) { + return false; + } + + float deta_geom = 999.f; + float dphi_geom = 999.f; if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { if (!cut.template IsSelectedTrack(t1, collision) || !cut.template IsSelectedTrack(t2, collision)) { @@ -700,6 +727,31 @@ struct DileptonMC { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + + if (dielectroncuts.cfg_x_to_go > 0.f) { + auto track_par_cov1 = getTrackParCov(t1); + track_par_cov1.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToX(track_par_cov1, dielectroncuts.cfg_x_to_go, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); + auto xyz1 = track_par_cov1.getXYZGlo(); + float eta1 = RecoDecay::eta(std::array{xyz1.X(), xyz1.Y(), xyz1.Z()}); + float phi1 = RecoDecay::phi(std::array{xyz1.X(), xyz1.Y()}); + o2::math_utils::bringTo02Pi(phi1); + + auto track_par_cov2 = getTrackParCov(t2); + track_par_cov2.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToX(track_par_cov2, dielectroncuts.cfg_x_to_go, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); + auto xyz2 = track_par_cov2.getXYZGlo(); + float eta2 = RecoDecay::eta(std::array{xyz2.X(), xyz2.Y(), xyz2.Z()}); + float phi2 = RecoDecay::phi(std::array{xyz2.X(), xyz2.Y()}); + o2::math_utils::bringTo02Pi(phi2); + + float deta_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? eta1 - eta2 : eta2 - eta1; + float dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? phi1 - phi2 : phi2 - phi1; + o2::math_utils::bringToPMPi(dphi_geom); + if (dielectroncuts.cfg_apply_detadphi_geom && std::pow(deta_geom / dielectroncuts.cfg_min_deta_geom, 2) + std::pow(dphi_geom / dielectroncuts.cfg_min_dphi_geom, 2) < 1.f) { + return false; + } + } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.template IsSelectedTrack(t1) || !cut.template IsSelectedTrack(t2)) { return false; @@ -711,14 +763,6 @@ struct DileptonMC { // float pca = 999.f, lxy = 999.f; // in unit of cm // o2::aod::pwgem::dilepton::utils::pairutil::isSVFound(fitter, collision, t1, t2, pca, lxy); - - auto t1mc = mcparticles.iteratorAt(t1.emmcparticleId()); - auto t2mc = mcparticles.iteratorAt(t2.emmcparticleId()); - bool is_from_same_mcevent = t1mc.emmceventId() == t2mc.emmceventId(); - - if (!isInAcceptance(t1mc) || !isInAcceptance(t2mc)) { - return false; - } float pt1 = 0.f, eta1 = 0.f, phi1 = 0.f, pt2 = 0.f, eta2 = 0.f, phi2 = 0.f; if constexpr (isSmeared) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { @@ -765,24 +809,14 @@ struct DileptonMC { ROOT::Math::PtEtaPhiMVector v2mc(pt2, eta2, phi2, leptonM2); ROOT::Math::PtEtaPhiMVector v12mc = v1mc + v2mc; - float deta_mc = v1mc.Eta() - v2mc.Eta(); - float dphi_mc = v1mc.Phi() - v2mc.Phi(); - o2::math_utils::bringToPMPi(dphi_mc); - if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { if (v12mc.Rapidity() < dielectroncuts.cfg_min_pair_y || dielectroncuts.cfg_max_pair_y < v12mc.Rapidity()) { return false; } - if (dielectroncuts.cfg_apply_detadphi && std::pow(deta_mc / dielectroncuts.cfg_min_deta, 2) + std::pow(dphi_mc / dielectroncuts.cfg_min_dphi, 2) < 1.f) { - return false; - } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (v12mc.Rapidity() < dimuoncuts.cfg_min_pair_y || dimuoncuts.cfg_max_pair_y < v12mc.Rapidity()) { return false; } - if (dimuoncuts.cfg_apply_detadphi && std::pow(deta_mc / dimuoncuts.cfg_min_deta, 2) + std::pow(dphi_mc / dimuoncuts.cfg_min_dphi, 2) < 1.f) { - return false; - } } float weight = 1.f; @@ -921,6 +955,7 @@ struct DileptonMC { fRegistry.fill(HIST("Pair/sm/Photon/hs"), v12.M(), v12.Pt(), v12.Rapidity(), abs(dphi), deta, abs(cos_thetaCS), abs(phiCS), aco, asym, abs(dphi_e_ee), pair_dca, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/sm/Photon/hMvsPhiV"), phiv, v12.M()); + fRegistry.fill(HIST("Pair/sm/Photon/hGeomDeltaEtaDeltaPhi"), dphi_geom, deta_geom, weight); } break; default: @@ -1035,7 +1070,7 @@ struct DileptonMC { using FilteredMyCollisions = soa::Filtered; template - void runTruePairing(TCollisions const& collisions, TMCLeptons const& posTracks, TMCLeptons const& negTracks, TPreslice const& perCollision, TCut const& cut, TMCCollisions const&, TMCParticles const& mcparticles) + void runTruePairing(TCollisions const& collisions, TMCLeptons const& posTracks, TMCLeptons const& negTracks, TPreslice const& perCollision, TCut const& cut, TMCCollisions const& mccollisions, TMCParticles const& mcparticles) { for (auto& collision : collisions) { initCCDB(collision); @@ -1044,98 +1079,63 @@ struct DileptonMC { continue; } - // auto mccollision = collision.template emmcevent_as(); - // if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - // continue; - // } - + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<0, -1>(&fRegistry, collision); if (!fEMEventCut.IsSelected(collision)) { continue; } + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<1, -1>(&fRegistry, collision); + fRegistry.fill(HIST("Event/before/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); // LOGF(info, "centrality = %f , posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", centralities[cfgCentEstimator], posTracks_per_coll.size(), negTracks_per_coll.size()); for (auto& [pos, neg] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - auto mcpos = mcparticles.iteratorAt(pos.emmcparticleId()); - auto mccollision_from_pos = mcpos.template emmcevent_as(); - if (cfgEventGeneratorType >= 0 && mccollision_from_pos.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - auto mcneg = mcparticles.iteratorAt(neg.emmcparticleId()); - auto mccollision_from_neg = mcneg.template emmcevent_as(); - if (cfgEventGeneratorType >= 0 && mccollision_from_neg.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - - fillTruePairInfo(collision, pos, neg, cut, mcparticles); + fillTruePairInfo(collision, mccollisions, pos, neg, cut, mcparticles); } // end of ULS pair loop for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ - auto mcpos1 = mcparticles.iteratorAt(pos1.emmcparticleId()); - auto mccollision_from_pos1 = mcpos1.template emmcevent_as(); - if (cfgEventGeneratorType >= 0 && mccollision_from_pos1.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - auto mcpos2 = mcparticles.iteratorAt(pos2.emmcparticleId()); - auto mccollision_from_pos2 = mcpos2.template emmcevent_as(); - if (cfgEventGeneratorType >= 0 && mccollision_from_pos2.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - fillTruePairInfo(collision, pos1, pos2, cut, mcparticles); + fillTruePairInfo(collision, mccollisions, pos1, pos2, cut, mcparticles); } // end of LS++ pair loop for (auto& [neg1, neg2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- - auto mcneg1 = mcparticles.iteratorAt(neg1.emmcparticleId()); - auto mccollision_from_neg1 = mcneg1.template emmcevent_as(); - if (cfgEventGeneratorType >= 0 && mccollision_from_neg1.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - auto mcneg2 = mcparticles.iteratorAt(neg2.emmcparticleId()); - auto mccollision_from_neg2 = mcneg2.template emmcevent_as(); - if (cfgEventGeneratorType >= 0 && mccollision_from_neg2.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - fillTruePairInfo(collision, neg1, neg2, cut, mcparticles); + fillTruePairInfo(collision, mccollisions, neg1, neg2, cut, mcparticles); } // end of LS-- pair loop } // end of collision loop } template - void runGenInfo(TCollisions const& collisions, TMCCollisions const&, TMCLeptons const& posTracksMC, TMCLeptons const& negTracksMC, TMCParticles const& mcparticles) + void runGenInfo(TCollisions const& collisions, TMCCollisions const& mccollisions, TMCLeptons const& posTracksMC, TMCLeptons const& negTracksMC, TMCParticles 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 + for (auto& mccollision : mccollisions) { + if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } - std::vector used_mccollisionIds; // used mc collisionIds - used_mccollisionIds.reserve(collisions.size()); + auto rec_colls_per_mccoll = collisions.sliceBy(recColperMcCollision, mccollision.globalIndex()); + uint32_t maxNumContrib = 0; + int rec_col_globalIndex = -999; + for (auto& rec_col : rec_colls_per_mccoll) { + if (rec_col.numContrib() > maxNumContrib) { + rec_col_globalIndex = rec_col.globalIndex(); + maxNumContrib = rec_col.numContrib(); // assign mc collision to collision where the number of contibutor is lager. LF/MM recommendation + } + } - for (auto& collision : collisions) { - auto mccollision = collision.template emmcevent_as(); - if (std::find(used_mccollisionIds.begin(), used_mccollisionIds.end(), mccollision.globalIndex()) != used_mccollisionIds.end()) { - // LOGF(info, "same mc collision is repeated. continue;"); + if (rec_colls_per_mccoll.size() < 1) { continue; } - used_mccollisionIds.emplace_back(mccollision.globalIndex()); + auto collision = collisions.rawIteratorAt(rec_col_globalIndex); float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { continue; } - - if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - - o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<0, -1>(&fRegistry, collision); if (!fEMEventCut.IsSelected(collision)) { continue; } - o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<1, -1>(&fRegistry, collision); - fRegistry.fill(HIST("Event/before/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted - fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted auto posTracks_per_coll = posTracksMC.sliceByCachedUnsorted(aod::emmcparticle::emmceventId, mccollision.globalIndex(), cache); auto negTracks_per_coll = negTracksMC.sliceByCachedUnsorted(aod::emmcparticle::emmceventId, mccollision.globalIndex(), cache); @@ -1615,8 +1615,6 @@ struct DileptonMC { } } // end of true LS++ pair loop } // end of collision loop - used_mccollisionIds.clear(); - used_mccollisionIds.shrink_to_fit(); } template @@ -1642,6 +1640,30 @@ struct DileptonMC { if (!cut.template IsSelectedPair(t1, t2, d_bz)) { return false; } + if (dielectroncuts.cfg_x_to_go > 0.f) { + auto track_par_cov1 = getTrackParCov(t1); + track_par_cov1.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToX(track_par_cov1, dielectroncuts.cfg_x_to_go, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); + auto xyz1 = track_par_cov1.getXYZGlo(); + float eta1 = RecoDecay::eta(std::array{xyz1.X(), xyz1.Y(), xyz1.Z()}); + float phi1 = RecoDecay::phi(std::array{xyz1.X(), xyz1.Y()}); + o2::math_utils::bringTo02Pi(phi1); + + auto track_par_cov2 = getTrackParCov(t2); + track_par_cov2.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToX(track_par_cov2, dielectroncuts.cfg_x_to_go, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); + auto xyz2 = track_par_cov2.getXYZGlo(); + float eta2 = RecoDecay::eta(std::array{xyz2.X(), xyz2.Y(), xyz2.Z()}); + float phi2 = RecoDecay::phi(std::array{xyz2.X(), xyz2.Y()}); + o2::math_utils::bringTo02Pi(phi2); + + float deta_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? eta1 - eta2 : eta2 - eta1; + float dphi_geom = t1.sign() * t1.pt() > t2.sign() * t2.pt() ? phi1 - phi2 : phi2 - phi1; + o2::math_utils::bringToPMPi(dphi_geom); + if (dielectroncuts.cfg_apply_detadphi_geom && std::pow(deta_geom / dielectroncuts.cfg_min_deta_geom, 2) + std::pow(dphi_geom / dielectroncuts.cfg_min_dphi_geom, 2) < 1.f) { + return false; + } + } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { if (!cut.template IsSelectedPair(t1, t2)) { return false; @@ -2111,6 +2133,7 @@ struct DileptonMC { Partition negative_muonsMC = o2::aod::mcparticle::pdgCode == 13; // mu- PresliceUnsorted perMcCollision = aod::emmcparticle::emmceventId; PresliceUnsorted perMcCollision_vm = aod::emmcgenvectormeson::emmceventId; + PresliceUnsorted recColperMcCollision = aod::emmceventlabel::emmceventId; void processAnalysis(FilteredMyCollisions const& collisions, aod::EMMCEvents const& mccollisions, aod::EMMCParticles const& mcparticles, TLeptons const& leptons) { diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 477c11fa1b2..6bc3f83a2fe 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -79,7 +79,7 @@ struct SingleTrackQC { Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", static_cast(1e+9), "max. multNTracksPV"}; Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; - Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; + Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; ConfigurableAxis ConfPtlBins{"ConfPtlBins", {VARIABLE_WIDTH, 0.00, 0.05, 0.10, 0.15, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTl bins for output histograms"}; ConfigurableAxis ConfDCABins{"ConfDCABins", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCA bins for output histograms"}; @@ -164,7 +164,7 @@ struct SingleTrackQC { struct : ConfigurableGroup { std::string prefix = "dimuoncut_group"; - Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.1, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index 694d6c5aa74..0ca97194716 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -83,7 +83,7 @@ struct SingleTrackQCMC { Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", static_cast(1e+9), "max. multNTracksPV"}; Configurable cfgFillQA{"cfgFillQA", false, "flag to fill QA histograms"}; Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; - Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; + Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; ConfigurableAxis ConfPtlBins{"ConfPtlBins", {VARIABLE_WIDTH, 0.00, 0.05, 0.10, 0.15, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTl bins for output histograms"}; ConfigurableAxis ConfDCABins{"ConfDCABins", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCA bins for output histograms"}; @@ -166,7 +166,7 @@ struct SingleTrackQCMC { DimuonCut fDimuonCut; struct : ConfigurableGroup { std::string prefix = "dimuoncut_group"; - Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -4.0, "min eta for single track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", -2.5, "max eta for single track"}; @@ -659,9 +659,13 @@ struct SingleTrackQCMC { // continue; // } + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<0, -1>(&fRegistry, collision); if (!fEMEventCut.IsSelected(collision)) { continue; } + o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<1, -1>(&fRegistry, collision); + fRegistry.fill(HIST("Event/before/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted + fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted auto tracks_per_coll = tracks.sliceBy(perCollision, collision.globalIndex()); @@ -740,44 +744,39 @@ struct SingleTrackQCMC { } // end of process template - void runGenInfo(TCollisions const& collisions, TMCLeptons const& leptonsMC, TMCCollisions const&, TMCParticles const& mcparticles) + void runGenInfo(TCollisions const& collisions, TMCLeptons const& leptonsMC, TMCCollisions const& mccollisions, TMCParticles 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 + for (auto& mccollision : mccollisions) { + if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { + continue; + } - std::vector used_mccollisionIds; // used mc collisionIds - used_mccollisionIds.reserve(collisions.size()); + auto rec_colls_per_mccoll = collisions.sliceBy(recColperMcCollision, mccollision.globalIndex()); + uint32_t maxNumContrib = 0; + int rec_col_globalIndex = -999; + for (auto& rec_col : rec_colls_per_mccoll) { + if (rec_col.numContrib() > maxNumContrib) { + rec_col_globalIndex = rec_col.globalIndex(); + maxNumContrib = rec_col.numContrib(); // assign mc collision to collision where the number of contibutor is lager. LF/MM recommendation + } + } - for (auto& collision : collisions) { - auto mccollision = collision.template emmcevent_as(); - if (std::find(used_mccollisionIds.begin(), used_mccollisionIds.end(), mccollision.globalIndex()) != used_mccollisionIds.end()) { - // LOGF(info, "same mc collision is repeated. continue;"); + if (rec_colls_per_mccoll.size() < 1) { continue; } - used_mccollisionIds.emplace_back(mccollision.globalIndex()); + + auto collision = collisions.rawIteratorAt(rec_col_globalIndex); float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { continue; } - // LOGF(info, "mccollision.getGeneratorId() = %d", mccollision.getGeneratorId()); - // LOGF(info, "mccollision.getSubGeneratorId() = %d", mccollision.getSubGeneratorId()); - // LOGF(info, "mccollision.getSourceId() = %d", mccollision.getSourceId()); - if (cfgEventGeneratorType >= 0 && mccollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - - o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<0, -1>(&fRegistry, collision); if (!fEMEventCut.IsSelected(collision)) { continue; } - o2::aod::pwgem::dilepton::utils::eventhistogram::fillEventInfo<1, -1>(&fRegistry, collision); - fRegistry.fill(HIST("Event/before/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted - fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted auto leptonsMC_per_coll = leptonsMC.sliceByCachedUnsorted(o2::aod::emmcparticle::emmceventId, mccollision.globalIndex(), cache); - for (auto& lepton : leptonsMC_per_coll) { if (!(lepton.isPhysicalPrimary() || lepton.producedByGenerator())) { continue; @@ -841,11 +840,9 @@ struct SingleTrackQCMC { } else if (IsFromCharm(lepton, mcparticles) > 0) { // c is found in full decay chain. Not from b. fRegistry.fill(HIST("Generated/c2l/hs"), pt, eta, phi, -lepton.pdgCode() / pdg_lepton); } - } + } // end of mc lepton loop per collision - } // end of collision loop - used_mccollisionIds.clear(); - used_mccollisionIds.shrink_to_fit(); + } // end of mc collision loop } std::unordered_map map_weight; // map of track global index -> weight @@ -956,6 +953,8 @@ struct SingleTrackQCMC { Partition muonsMC = nabs(o2::aod::mcparticle::pdgCode) == 13; // mu+, mu- PresliceUnsorted perMcCollision = aod::emmcparticle::emmceventId; + PresliceUnsorted recColperMcCollision = aod::emmceventlabel::emmceventId; + void processQCMC(FilteredMyCollisions const& collisions, aod::EMMCEvents const& mccollisions, aod::EMMCParticles const& mcparticles, TLeptons const& tracks) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx index 4e064d7285c..de581cc2be5 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx @@ -195,8 +195,8 @@ struct TreeCreatorElectronML { Configurable minpt{"minpt", 0.2, "min. pT"}; Configurable maxDcaZ{"maxDcaZ", 1.0, "max DCA Z"}; Configurable maxDcaXY{"maxDcaXY", 1.0, "max DCA XY"}; - Configurable minITSClusters{"minITSLayers", 5, "min. of ITS clusters"}; - Configurable minITSClustersIB{"minITSClustersIB", 3, "min. number of ITS clusters in inner barrel"}; + Configurable minITSClusters{"minITSLayers", 5, "min. of ITS clusters"}; + Configurable minITSClustersIB{"minITSClustersIB", 3, "min. number of ITS clusters in inner barrel"}; Configurable downSampleEl{"downSampleEl", 1.0, "down scaling factor for electrons"}; Configurable downSamplePi{"downSamplePi", 1.0, "down scaling factor for pions"}; Configurable downSampleKa{"downSampleKa", 1.0, "down scaling factor for kaons"}; diff --git a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx index 24efd7f232d..bfcf7e4f8f4 100644 --- a/PWGEM/Dilepton/Tasks/createResolutionMap.cxx +++ b/PWGEM/Dilepton/Tasks/createResolutionMap.cxx @@ -84,7 +84,7 @@ struct CreateResolutionMap { struct : ConfigurableGroup { std::string prefix = "muoncut_group"; - Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; + Configurable cfg_track_type{"cfg_track_type", 3, "muon track type [0: MFT-MCH-MID, 3: MCH-MID]"}; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.01, "min pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -5.0, "min eta for single track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", -1.5, "max eta for single track"}; diff --git a/PWGEM/Dilepton/Tasks/lmeeLFCocktail.cxx b/PWGEM/Dilepton/Tasks/lmeeLFCocktail.cxx index d54e1d2f382..86b69e3a78d 100644 --- a/PWGEM/Dilepton/Tasks/lmeeLFCocktail.cxx +++ b/PWGEM/Dilepton/Tasks/lmeeLFCocktail.cxx @@ -283,6 +283,8 @@ struct lmeelfcocktail { void init(InitContext& context) { + registry.add("NEvents", "NEvents", HistType::kTH1F, {{1, 0., 1.}}, false); + AxisSpec mass_axis = {fConfigMeeBins, "m_{ee} (GeV/#it{c}^{2})"}; AxisSpec ptee_axis = {fConfigPteeBins, "#it{p}_{T,ee} (GeV/#it{c})"}; AxisSpec cos2dphi_axis = {fConfigCos2DPhi, "cos(2(#varphi_{ee} - #Psi_{RP}))"}; // PsiRP = 0 rad. in generator. @@ -328,8 +330,10 @@ struct lmeelfcocktail { } } - void processCocktail(McParticlesSmeared const& mcParticles) + void processCocktail(aod::McCollision const&, McParticlesSmeared const& mcParticles) { + registry.fill(HIST("NEvents"), 0.5); + for (auto const& particle : mcParticles) { if (particle.has_mothers()) { continue; diff --git a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h index 32f9ed1149d..e5437da59cf 100644 --- a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h +++ b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h @@ -80,7 +80,7 @@ using MyEMCClusters = soa::Join; using MyEMCCluster = MyEMCClusters::iterator; using MyPHOSClusters = soa::Join; -using MyPHOSCluster = MyEMCClusters::iterator; +using MyPHOSCluster = MyPHOSClusters::iterator; template struct Pi0EtaToGammaGamma { @@ -210,6 +210,7 @@ struct Pi0EtaToGammaGamma { Service ccdb; int mRunNumber; float d_bz; + o2::emcal::Geometry* emcalGeom; void init(InitContext&) { @@ -244,7 +245,7 @@ struct Pi0EtaToGammaGamma { if constexpr (pairtype == kEMCEMC) { fRegistry.addClone("Pair/same/", "Pair/rotation/"); - o2::emcal::Geometry::GetInstanceFromRunNumber(300000); + emcalGeom = o2::emcal::Geometry::GetInstanceFromRunNumber(300000); } mRunNumber = 0; @@ -449,11 +450,31 @@ struct Pi0EtaToGammaGamma { photon1 = rotationMatrix * photon1; photon2 = rotationMatrix * photon2; + int iCellID_photon1 = 0; + int iCellID_photon2 = 0; + + try { + iCellID_photon1 = emcalGeom->GetAbsCellIdFromEtaPhi(photon1.Eta(), photon1.Phi()); + } catch (o2::emcal::InvalidPositionException& e) { + iCellID_photon1 = -1; + } + try { + iCellID_photon2 = emcalGeom->GetAbsCellIdFromEtaPhi(photon2.Eta(), photon2.Phi()); + } catch (o2::emcal::InvalidPositionException& e) { + iCellID_photon2 = -1; + } + if (iCellID_photon1 == -1 && iCellID_photon2 == -1) { + return; + } + for (auto& photon : photons_coll) { if (photon.globalIndex() == ig1 || photon.globalIndex() == ig2) { // only combine rotated photons with other photons continue; } + if (!(fEMCCut.IsSelected(photon))) { + continue; + } ROOT::Math::PtEtaPhiMVector photon3(photon.pt(), photon.eta(), photon.phi(), 0.); ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3; @@ -462,20 +483,6 @@ struct Pi0EtaToGammaGamma { float openingAngle1 = std::acos(photon1.Vect().Dot(photon3.Vect()) / (photon1.P() * photon3.P())); float openingAngle2 = std::acos(photon2.Vect().Dot(photon3.Vect()) / (photon2.P() * photon3.P())); - int iCellID_photon1 = 0; - int iCellID_photon2 = 0; - - try { - iCellID_photon1 = o2::emcal::Geometry::GetInstance()->GetAbsCellIdFromEtaPhi(photon1.Eta(), photon1.Phi()); - } catch (o2::emcal::InvalidPositionException& e) { - iCellID_photon1 = -1; - } - try { - iCellID_photon2 = o2::emcal::Geometry::GetInstance()->GetAbsCellIdFromEtaPhi(photon2.Eta(), photon2.Phi()); - } catch (o2::emcal::InvalidPositionException& e) { - iCellID_photon2 = -1; - } - if (openingAngle1 > emccuts.minOpenAngle && abs(mother1.Rapidity()) < maxY && iCellID_photon1 > 0) { fRegistry.fill(HIST("Pair/rotation/hs"), mother1.M(), mother1.Pt(), eventWeight); } @@ -483,6 +490,7 @@ struct Pi0EtaToGammaGamma { fRegistry.fill(HIST("Pair/rotation/hs"), mother2.M(), mother2.Pt(), eventWeight); } } + return; } SliceCache cache; diff --git a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx index 489e0bd7008..83d5af15a8e 100644 --- a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx @@ -87,6 +87,9 @@ struct EMfTaskPi0Flow { Configurable saveEpResoHisto{"saveEpResoHisto", false, "Flag to save event plane resolution histogram"}; Configurable saveSPResoHist{"saveSPResoHist", false, "Flag to save scalar product resolution histogram"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable cfgDoRotation{"cfgDoRotation", true, "Flag to enable rotation background method"}; + Configurable cfgDownsampling{"cfgDownsampling", 1, "Calculate rotation background only for every collision"}; + Configurable cfgRotAngle{"cfgRotAngle", M_PI / 2., "Angle used for the rotation method"}; // configurable axis ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {200, 0.0, 0.4}, ""}; @@ -139,6 +142,7 @@ struct EMfTaskPi0Flow { struct : ConfigurableGroup { std::string prefix = "meson"; Configurable minOpenAngle{"minOpenAngle", 0.0202, "apply min opening angle. Default value one EMCal cell"}; + Configurable enableTanThetadPhi{"enableTanThetadPhi", false, "flag to turn cut opening angle in delta theta delta phi on/off"}; Configurable minTanThetadPhi{"minTanThetadPhi", 4., "apply min opening angle in delta theta delta phi to cut on late conversion"}; Configurable maxEnergyAsymmetry{"maxEnergyAsymmetry", 1., "apply max energy asymmetry for meson candidate"}; Configurable enableQA{"enableQA", false, "flag to turn QA plots on/off"}; @@ -170,6 +174,8 @@ struct EMfTaskPi0Flow { HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + o2::emcal::Geometry* emcalGeom; + void DefineEMEventCut() { fEMEventCut = EMPhotonEventCut("fEMEventCut", "fEMEventCut"); @@ -219,7 +225,7 @@ struct EMfTaskPi0Flow { o2::aod::pwgem::photonmeson::utils::eventhistogram::addEventHistograms(®istry); // Load EMCal geometry - o2::emcal::Geometry::GetInstanceFromRunNumber(300000); + emcalGeom = o2::emcal::Geometry::GetInstanceFromRunNumber(300000); const AxisSpec thnAxisInvMass{thnConfigAxisInvMass, "#it{M}_{#gamma#gamma} (GeV/#it{c}^{2})"}; const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; @@ -236,8 +242,7 @@ struct EMfTaskPi0Flow { const AxisSpec thAxisEta{160, -0.8, 0.8, "#eta"}; const AxisSpec thAxisPhi{72, 0, 2 * 3.14159, "phi"}; const AxisSpec thAxisNCell{17664, 0.5, +17664.5, "#it{N}_{cell}"}; - - const AxisSpec thAxisPsi{360 / harmonic, 0.f, 2. / harmonic * M_PI, Form("#Psi_{%d}", harmonic.value)}; + const AxisSpec thAxisPsi{360 / harmonic.value, -(1. / static_cast(harmonic.value)) * M_PI, (1. / static_cast(harmonic.value)) * M_PI, Form("#Psi_{%d}", harmonic.value)}; registry.add("hSparsePi0Flow", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisScalarProd}); registry.add("hSparseBkgFlow", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisScalarProd}); @@ -250,34 +255,34 @@ struct EMfTaskPi0Flow { hClusterCuts->GetXaxis()->SetBinLabel(6, "out"); if (saveSPResoHist) { - registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0cTPCpos", "hSpResoFT0cTPCpos; centrality; Q_{FT0c} #bullet Q_{TPCpos}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0cTPCneg", "hSpResoFT0cTPCneg; centrality; Q_{FT0c} #bullet Q_{TPCneg}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0cTPCtot", "hSpResoFT0cTPCtot; centrality; Q_{FT0c} #bullet Q_{TPCtot}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0aTPCpos", "hSpResoFT0aTPCpos; centrality; Q_{FT0a} #bullet Q_{TPCpos}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0aTPCneg", "hSpResoFT0aTPCneg; centrality; Q_{FT0a} #bullet Q_{TPCneg}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0aTPCtot", "hSpResoFT0aTPCtot; centrality; Q_{FT0m} #bullet Q_{TPCtot}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0mTPCpos", "hSpResoFT0mTPCpos; centrality; Q_{FT0m} #bullet Q_{TPCpos}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0mTPCneg", "hSpResoFT0mTPCneg; centrality; Q_{FT0m} #bullet Q_{TPCneg}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoFT0mTPCtot", "hSpResoFT0mTPCtot; centrality; Q_{FT0m} #bullet Q_{TPCtot}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("spReso/hSpResoTPCposTPCneg", "hSpResoTPCposTPCneg; centrality; Q_{TPCpos} #bullet Q_{TPCneg}", {HistType::kTProfile, {thnAxisCent}}); + registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0cTPCpos", "hSpResoFT0cTPCpos; centrality; Q_{FT0c} #bullet Q_{TPCpos}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0cTPCneg", "hSpResoFT0cTPCneg; centrality; Q_{FT0c} #bullet Q_{TPCneg}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0cTPCtot", "hSpResoFT0cTPCtot; centrality; Q_{FT0c} #bullet Q_{TPCtot}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0aTPCpos", "hSpResoFT0aTPCpos; centrality; Q_{FT0a} #bullet Q_{TPCpos}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0aTPCneg", "hSpResoFT0aTPCneg; centrality; Q_{FT0a} #bullet Q_{TPCneg}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0aTPCtot", "hSpResoFT0aTPCtot; centrality; Q_{FT0m} #bullet Q_{TPCtot}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0mTPCpos", "hSpResoFT0mTPCpos; centrality; Q_{FT0m} #bullet Q_{TPCpos}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0mTPCneg", "hSpResoFT0mTPCneg; centrality; Q_{FT0m} #bullet Q_{TPCneg}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoFT0mTPCtot", "hSpResoFT0mTPCtot; centrality; Q_{FT0m} #bullet Q_{TPCtot}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); + registry.add("spReso/hSpResoTPCposTPCneg", "hSpResoTPCposTPCneg; centrality; Q_{TPCpos} #bullet Q_{TPCneg}", HistType::kTH2D, {thnAxisCent, thnConfigAxisScalarProd}); } if (saveEpResoHisto) { registry.add("hEventPlaneAngleFT0M", "hEventPlaneAngleFT0M", HistType::kTH2D, {thnAxisCent, thAxisPsi}); registry.add("hEventPlaneAngleTPCpos", "hEventPlaneAngleTPCpos", HistType::kTH2D, {thnAxisCent, thAxisPsi}); registry.add("hEventPlaneAngleTPCneg", "hEventPlaneAngleTPCneg", HistType::kTH2D, {thnAxisCent, thAxisPsi}); - registry.add("epReso/hEpResoFT0cFT0a", "hEpResoFT0cFT0a; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0cTPCpos", "hEpResoFT0cTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0cTPCneg", "hEpResoFT0cTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0cTPCtot", "hEpResoFT0cTPCtot; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0aTPCpos", "hEpResoFT0aTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0aTPCneg", "hEpResoFT0aTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0aTPCtot", "hEpResoFT0aTPCtot; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0mTPCpos", "hEpResoFT0mTPCpos; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0mTPCneg", "hEpResoFT0mTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoFT0mTPCtot", "hEpResoFT0mTPCtot; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); - registry.add("epReso/hEpResoTPCposTPCneg", "hEpResoTPCposTPCneg; centrality; #Delta#Psi_{sub}", {HistType::kTProfile, {thnAxisCent}}); + registry.add("epReso/hEpResoFT0cFT0a", "hEpResoFT0cFT0a; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0cTPCpos", "hEpResoFT0cTPCpos; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0cTPCneg", "hEpResoFT0cTPCneg; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0cTPCtot", "hEpResoFT0cTPCtot; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0aTPCpos", "hEpResoFT0aTPCpos; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0aTPCneg", "hEpResoFT0aTPCneg; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0aTPCtot", "hEpResoFT0aTPCtot; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0mTPCpos", "hEpResoFT0mTPCpos; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0mTPCneg", "hEpResoFT0mTPCneg; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoFT0mTPCtot", "hEpResoFT0mTPCtot; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); + registry.add("epReso/hEpResoTPCposTPCneg", "hEpResoTPCposTPCneg; centrality; #Delta#Psi_{sub}", HistType::kTH2D, {thnAxisCent, thnAxisCosNPhi}); } if (eventcuts.enableQA) { auto hCollisionEMCCheck = registry.add("hCollisionEMCCheck", "collision counter;;Counts", kTH1D, {{7, 0.5, 7.5}}, false); @@ -485,13 +490,28 @@ struct EMfTaskPi0Flow { auto [xQVec, yQVec] = getQvec(collision, qvecDetector); float cent = getCentrality(collision); + int iCellID_photon1 = 0; + int iCellID_photon2 = 0; - const float rotationAngle = M_PI / 2.0; // rotaion angle 90 degree - ROOT::Math::AxisAngle rotationAxis(meson.Vect(), rotationAngle); + ROOT::Math::AxisAngle rotationAxis(meson.Vect(), cfgRotAngle.value); ROOT::Math::Rotation3D rotationMatrix(rotationAxis); photon1 = rotationMatrix * photon1; photon2 = rotationMatrix * photon2; + try { + iCellID_photon1 = emcalGeom->GetAbsCellIdFromEtaPhi(photon1.Eta(), photon1.Phi()); + } catch (o2::emcal::InvalidPositionException& e) { + iCellID_photon1 = -1; + } + try { + iCellID_photon2 = emcalGeom->GetAbsCellIdFromEtaPhi(photon2.Eta(), photon2.Phi()); + } catch (o2::emcal::InvalidPositionException& e) { + iCellID_photon2 = -1; + } + + if (iCellID_photon1 == -1 && iCellID_photon2 == -1) { + return; + } for (auto& photon : photons_coll) { if (photon.globalIndex() == ig1 || photon.globalIndex() == ig2) { // only combine rotated photons with other photons @@ -500,43 +520,46 @@ struct EMfTaskPi0Flow { if (!(fEMCCut.IsSelected(photon))) { continue; } - ROOT::Math::PtEtaPhiMVector photon3(photon.pt(), photon.eta(), photon.phi(), 0.); - ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3; - ROOT::Math::PtEtaPhiMVector mother2 = photon2 + photon3; - - float openingAngle1 = std::acos(photon1.Vect().Dot(photon3.Vect()) / (photon1.P() * photon3.P())); - float openingAngle2 = std::acos(photon2.Vect().Dot(photon3.Vect()) / (photon2.P() * photon3.P())); - - int iCellID_photon1 = 0; - int iCellID_photon2 = 0; - - float cosNPhi1 = std::cos(harmonic * mother1.Phi()); - float sinNPhi1 = std::sin(harmonic * mother1.Phi()); - float scalprodCand1 = cosNPhi1 * xQVec + sinNPhi1 * yQVec; - - float cosNPhi2 = std::cos(harmonic * mother2.Phi()); - float sinNPhi2 = std::sin(harmonic * mother2.Phi()); - float scalprodCand2 = cosNPhi2 * xQVec + sinNPhi2 * yQVec; - - try { - iCellID_photon1 = o2::emcal::Geometry::GetInstance()->GetAbsCellIdFromEtaPhi(photon1.Eta(), photon1.Phi()); - } catch (o2::emcal::InvalidPositionException& e) { - iCellID_photon1 = -1; - } - try { - iCellID_photon2 = o2::emcal::Geometry::GetInstance()->GetAbsCellIdFromEtaPhi(photon2.Eta(), photon2.Phi()); - } catch (o2::emcal::InvalidPositionException& e) { - iCellID_photon2 = -1; - } - - if (openingAngle1 > mesonConfig.minOpenAngle && iCellID_photon1 > 0 && thnConfigAxisInvMass.value[1] <= mother1.M() && thnConfigAxisInvMass.value.back() >= mother1.M() && thnConfigAxisPt.value[1] > mother1.Pt() && thnConfigAxisPt.value.back() < mother1.Pt()) { - registry.fill(HIST("hSparseBkgFlow"), mother1.M(), mother1.Pt(), cent, scalprodCand1); + if (iCellID_photon1 > 0) { + ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3; + float openingAngle1 = std::acos(photon1.Vect().Dot(photon3.Vect()) / (photon1.P() * photon3.P())); + float cosNPhi1 = std::cos(harmonic * mother1.Phi()); + float sinNPhi1 = std::sin(harmonic * mother1.Phi()); + float scalprodCand1 = cosNPhi1 * xQVec + sinNPhi1 * yQVec; + if (openingAngle1 > mesonConfig.minOpenAngle && thnConfigAxisInvMass.value[1] <= mother1.M() && thnConfigAxisInvMass.value.back() >= mother1.M() && thnConfigAxisPt.value[1] <= mother1.Pt() && thnConfigAxisPt.value.back() >= mother1.Pt()) { + if (mesonConfig.enableTanThetadPhi) { + float dTheta = photon1.Theta() - photon3.Theta(); + float dPhi = photon1.Phi() - photon3.Phi(); + if (mesonConfig.minTanThetadPhi > std::fabs(getAngleDegree(atan(dTheta / dPhi)))) { + registry.fill(HIST("hSparseBkgFlow"), mother1.M(), mother1.Pt(), cent, scalprodCand1); + } + } else { + registry.fill(HIST("hSparseBkgFlow"), mother1.M(), mother1.Pt(), cent, scalprodCand1); + } + } } - if (openingAngle2 > mesonConfig.minOpenAngle && iCellID_photon2 > 0 && thnConfigAxisInvMass.value[1] <= mother2.M() && thnConfigAxisInvMass.value.back() >= mother2.M() && thnConfigAxisPt.value[1] > mother2.Pt() && thnConfigAxisPt.value.back() < mother2.Pt()) { - registry.fill(HIST("hSparseBkgFlow"), mother2.M(), mother2.Pt(), cent, scalprodCand2); + if (iCellID_photon2 > 0) { + ROOT::Math::PtEtaPhiMVector mother2 = photon2 + photon3; + float openingAngle2 = std::acos(photon2.Vect().Dot(photon3.Vect()) / (photon2.P() * photon3.P())); + float cosNPhi2 = std::cos(harmonic * mother2.Phi()); + float sinNPhi2 = std::sin(harmonic * mother2.Phi()); + float scalprodCand2 = cosNPhi2 * xQVec + sinNPhi2 * yQVec; + + if (openingAngle2 > mesonConfig.minOpenAngle && thnConfigAxisInvMass.value[1] <= mother2.M() && thnConfigAxisInvMass.value.back() >= mother2.M() && thnConfigAxisPt.value[1] <= mother2.Pt() && thnConfigAxisPt.value.back() >= mother2.Pt()) { + if (mesonConfig.enableTanThetadPhi) { + float dTheta = photon2.Theta() - photon3.Theta(); + float dPhi = photon2.Phi() - photon3.Phi(); + if (mesonConfig.minTanThetadPhi > std::fabs(getAngleDegree(atan(dTheta / dPhi)))) { + registry.fill(HIST("hSparseBkgFlow"), mother2.M(), mother2.Pt(), cent, scalprodCand2); + } + } else { + registry.fill(HIST("hSparseBkgFlow"), mother2.M(), mother2.Pt(), cent, scalprodCand2); + } + } } - } + } // end of loop over third photon + return; } /// Compute the scalar product @@ -562,6 +585,7 @@ struct EMfTaskPi0Flow { // Pi0 from EMCal void processEMCal(CollsWithQvecs const& collisions, EMCalPhotons const& clusters) { + int NColl = 1; for (auto& collision : collisions) { auto photons_per_collision = clusters.sliceBy(perCollision_emc, collision.globalIndex()); @@ -630,9 +654,6 @@ struct EMfTaskPi0Flow { 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 vMeson = v1 + v2; - - RotationBackground(vMeson, v1, v2, photons_per_collision, g1.globalIndex(), g2.globalIndex(), collision); - float dTheta = v1.Theta() - v2.Theta(); float dPhi = v1.Phi() - v2.Phi(); float openingAngle = std::acos(v1.Vect().Dot(v2.Vect()) / (v1.P() * v2.P())); @@ -641,6 +662,11 @@ struct EMfTaskPi0Flow { registry.fill(HIST("hClusterCuts"), 2); continue; } + if (cfgDoRotation) { + if (NColl % cfgDownsampling.value == 0) { + RotationBackground(vMeson, v1, v2, photons_per_collision, g1.globalIndex(), g2.globalIndex(), collision); + } + } if (thnConfigAxisInvMass.value[1] > vMeson.M() || thnConfigAxisInvMass.value.back() < vMeson.M()) { registry.fill(HIST("hClusterCuts"), 3); continue; @@ -654,13 +680,20 @@ struct EMfTaskPi0Flow { registry.fill(HIST("hTanThetaPhi"), vMeson.M(), getAngleDegree(atan(dTheta / dPhi))); registry.fill(HIST("hAlphaPt"), (v1.E() - v2.E()) / (v1.E() + v2.E()), vMeson.Pt()); } - if (mesonConfig.minTanThetadPhi > std::fabs(getAngleDegree(atan(dTheta / dPhi)))) { + if (mesonConfig.enableTanThetadPhi && mesonConfig.minTanThetadPhi > std::fabs(getAngleDegree(atan(dTheta / dPhi)))) { registry.fill(HIST("hClusterCuts"), 5); continue; } registry.fill(HIST("hClusterCuts"), 6); runFlowAnalysis(collision, vMeson); } + if (cfgDoRotation) { + if (NColl % cfgDownsampling.value == 0) { + NColl = 1; // reset counter + } else { + NColl++; + } + } } } PROCESS_SWITCH(EMfTaskPi0Flow, processEMCal, "Process EMCal Pi0 candidates", true); diff --git a/PWGHF/Core/HfMlResponseDstarToD0Pi.h b/PWGHF/Core/HfMlResponseDstarToD0Pi.h index b583d93ed88..66fc3a712d4 100644 --- a/PWGHF/Core/HfMlResponseDstarToD0Pi.h +++ b/PWGHF/Core/HfMlResponseDstarToD0Pi.h @@ -61,6 +61,18 @@ break; \ } +// Very specific case of CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(OBJECT, FEATURE, GETTER) +// Use for push back different value for D*+ or D*- candidate getting the correct feature from two different objects (tracks) +#define CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(OBJECTPOS, OBJECTNEG, FEATURENAME, GETTER) \ + case static_cast(InputFeaturesDstarToD0Pi::FEATURENAME): { \ + if (candidate.signSoftPi() > 0) { \ + inputFeatures.emplace_back(OBJECTPOS.GETTER()); \ + } else { \ + inputFeatures.emplace_back(OBJECTNEG.GETTER()); \ + } \ + break; \ + } + // Very specific case of CHECK_AND_FILL_VEC_DSTAR_FULL(OBJECT, FEATURE, GETTER) // Use for push back deltaMassD0 for D*+ or D*- candidate #define CHECK_AND_FILL_VEC_DSTAR_DELTA_MASS_D0(FEATURENAME) \ @@ -156,36 +168,36 @@ class HfMlResponseDstarToD0Pi : public HfMlResponse CHECK_AND_FILL_VEC_DSTAR(cpaXYD0); CHECK_AND_FILL_VEC_DSTAR(deltaIPNormalisedMaxD0); CHECK_AND_FILL_VEC_DSTAR(impactParameterProductD0); - CHECK_AND_FILL_VEC_DSTAR(ptProng0); - CHECK_AND_FILL_VEC_DSTAR(ptProng1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(ptProng0, ptProng1, ptProng0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(ptProng1, ptProng0, ptProng1); CHECK_AND_FILL_VEC_DSTAR(ptSoftPi); - CHECK_AND_FILL_VEC_DSTAR(impactParameter0); - CHECK_AND_FILL_VEC_DSTAR(impactParameter1); - CHECK_AND_FILL_VEC_DSTAR(impactParameterZ0); - CHECK_AND_FILL_VEC_DSTAR(impactParameterZ1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameter0, impactParameter1, impactParameter0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameter1, impactParameter0, impactParameter1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZ0, impactParameterZ1, impactParameterZ0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZ1, impactParameterZ0, impactParameterZ1); CHECK_AND_FILL_VEC_DSTAR(impParamSoftPi); CHECK_AND_FILL_VEC_DSTAR(impParamZSoftPi); - CHECK_AND_FILL_VEC_DSTAR(impactParameterNormalised0); - CHECK_AND_FILL_VEC_DSTAR(impactParameterNormalised1); - CHECK_AND_FILL_VEC_DSTAR(impactParameterZNormalised0); - CHECK_AND_FILL_VEC_DSTAR(impactParameterZNormalised1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterNormalised0, impactParameterNormalised1, impactParameterNormalised0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterNormalised1, impactParameterNormalised0, impactParameterNormalised1); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZNormalised0, impactParameterZNormalised1, impactParameterZNormalised0); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(impactParameterZNormalised1, impactParameterZNormalised0, impactParameterZNormalised1); CHECK_AND_FILL_VEC_DSTAR(normalisedImpParamSoftPi); CHECK_AND_FILL_VEC_DSTAR(normalisedImpParamZSoftPi); CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(cosThetaStarD0, cosThetaStarD0Bar, cosThetaStarD0); CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE(invMassD0, invMassD0Bar, massD0); CHECK_AND_FILL_VEC_DSTAR_DELTA_MASS_D0(deltaMassD0); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong0, nSigmaTPCPiPr0, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong0, nSigmaTPCKaPr0, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong0, nSigmaTOFPiPr0, tofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong0, nSigmaTOFKaPr0, tofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong0, nSigmaTPCTOFPiPr0, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong0, nSigmaTPCTOFKaPr0, tpcTofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong1, nSigmaTPCPiPr1, tpcNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong1, nSigmaTPCKaPr1, tpcNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong1, nSigmaTOFPiPr1, tofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong1, nSigmaTOFKaPr1, tofNSigmaKa); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong1, nSigmaTPCTOFPiPr1, tpcTofNSigmaPi); - CHECK_AND_FILL_VEC_DSTAR_FULL(prong1, nSigmaTPCTOFKaPr1, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCPiPr0, tpcNSigmaPi); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCKaPr0, tpcNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTOFPiPr0, tofNSigmaPi); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTOFKaPr0, tofNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCTOFPiPr0, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong0, prong1, nSigmaTPCTOFKaPr0, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCPiPr1, tpcNSigmaPi); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCKaPr1, tpcNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTOFPiPr1, tofNSigmaPi); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTOFKaPr1, tofNSigmaKa); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCTOFPiPr1, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_DSTAR_CHARGEBASE_FROMOBJECT(prong1, prong0, nSigmaTPCTOFKaPr1, tpcTofNSigmaKa); CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTPCPiPrSoftPi, tpcNSigmaPi); CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTPCKaPrSoftPi, tpcNSigmaKa); CHECK_AND_FILL_VEC_DSTAR_FULL(prongSoftPi, nSigmaTOFPiPrSoftPi, tofNSigmaPi); diff --git a/PWGHF/Core/HfMlResponseXicToXiPiPi.h b/PWGHF/Core/HfMlResponseXicToXiPiPi.h new file mode 100644 index 00000000000..0a290e14d1d --- /dev/null +++ b/PWGHF/Core/HfMlResponseXicToXiPiPi.h @@ -0,0 +1,147 @@ +// 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 HfMlResponseXicToXiPiPi.h +/// \brief Class to compute the ML response for Ξc± → Ξ∓ π± π± analysis selections +/// \author Jaeyoon Cho , Inha University + +#ifndef PWGHF_CORE_HFMLRESPONSEXICTOXIPIPI_H_ +#define PWGHF_CORE_HFMLRESPONSEXICTOXIPIPI_H_ + +#include +#include +#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_XICTOXIPIPI(FEATURE) \ + { \ + #FEATURE, static_cast(InputFeaturesXicToXiPiPi::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_XICTOXIPIPI_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesXicToXiPiPi::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ + } + +// Specific case of CHECK_AND_FILL_VEC_XICTOXIPIPI_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_XICTOXIPIPI(GETTER) \ + case static_cast(InputFeaturesXicToXiPiPi::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + +namespace o2::analysis +{ + +enum class InputFeaturesXicToXiPiPi : uint8_t { + ptProng0 = 0, + ptProng1, + ptProng2, + chi2PCA, + decayLength, + decayLengthNormalised, + decayLengthXY, + decayLengthXYNormalised, + cpa, + cpaXY, + cosPaXi, + cosPaXYXi, + cosPaLambda, + cosPaXYLambda, + impactParameterXY0, + impactParameterXY1, + impactParameterXY2 +}; + +template +class HfMlResponseXicToXiPiPi : public HfMlResponse +{ + public: + /// Default constructor + HfMlResponseXicToXiPiPi() = default; + /// Default destructor + virtual ~HfMlResponseXicToXiPiPi() = default; + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the Xic candidate + /// \return inputFeatures vector + template + std::vector getInputFeatures(T1 const& candidate) + { + std::vector inputFeatures; + + for (const auto& idx : MlResponse::mCachedIndices) { + switch (idx) { + CHECK_AND_FILL_VEC_XICTOXIPIPI(ptProng0); + CHECK_AND_FILL_VEC_XICTOXIPIPI(ptProng1); + CHECK_AND_FILL_VEC_XICTOXIPIPI(ptProng2); + CHECK_AND_FILL_VEC_XICTOXIPIPI(chi2PCA); + CHECK_AND_FILL_VEC_XICTOXIPIPI(decayLength); + CHECK_AND_FILL_VEC_XICTOXIPIPI(decayLengthNormalised); + CHECK_AND_FILL_VEC_XICTOXIPIPI(decayLengthXY); + CHECK_AND_FILL_VEC_XICTOXIPIPI(decayLengthXYNormalised); + CHECK_AND_FILL_VEC_XICTOXIPIPI(cpa); + CHECK_AND_FILL_VEC_XICTOXIPIPI(cpaXY); + CHECK_AND_FILL_VEC_XICTOXIPIPI(cosPaXi); + CHECK_AND_FILL_VEC_XICTOXIPIPI(cosPaXYXi); + CHECK_AND_FILL_VEC_XICTOXIPIPI(cosPaLambda); + CHECK_AND_FILL_VEC_XICTOXIPIPI(cosPaXYLambda); + CHECK_AND_FILL_VEC_XICTOXIPIPI_FULL(candidate, impactParameterXY0, impactParameter0); + CHECK_AND_FILL_VEC_XICTOXIPIPI_FULL(candidate, impactParameterXY1, impactParameter1); + CHECK_AND_FILL_VEC_XICTOXIPIPI_FULL(candidate, impactParameterXY2, impactParameter2); + } + } + + return inputFeatures; + } + + protected: + /// Method to fill the map of available input features + void setAvailableInputFeatures() + { + MlResponse::mAvailableInputFeatures = { + FILL_MAP_XICTOXIPIPI(ptProng0), + FILL_MAP_XICTOXIPIPI(ptProng1), + FILL_MAP_XICTOXIPIPI(ptProng2), + FILL_MAP_XICTOXIPIPI(chi2PCA), + FILL_MAP_XICTOXIPIPI(decayLength), + FILL_MAP_XICTOXIPIPI(decayLengthNormalised), + FILL_MAP_XICTOXIPIPI(decayLengthXY), + FILL_MAP_XICTOXIPIPI(decayLengthXYNormalised), + FILL_MAP_XICTOXIPIPI(cpa), + FILL_MAP_XICTOXIPIPI(cpaXY), + FILL_MAP_XICTOXIPIPI(cosPaXi), + FILL_MAP_XICTOXIPIPI(cosPaXYXi), + FILL_MAP_XICTOXIPIPI(cosPaLambda), + FILL_MAP_XICTOXIPIPI(cosPaXYLambda), + FILL_MAP_XICTOXIPIPI(impactParameterXY0), + FILL_MAP_XICTOXIPIPI(impactParameterXY1), + FILL_MAP_XICTOXIPIPI(impactParameterXY2)}; + } +}; + +} // namespace o2::analysis + +#undef FILL_MAP_XICTOXIPIPI +#undef CHECK_AND_FILL_VEC_XICTOXIPIPI_FULL +#undef CHECK_AND_FILL_VEC_XICTOXIPIPI + +#endif // PWGHF_CORE_HFMLRESPONSEXICTOXIPIPI_H_ diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 590b536f61a..d8c06e0d26f 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -343,8 +343,8 @@ DECLARE_SOA_TABLE(HfRedPidDau1s, "AOD", "HFREDPIDDAU1", //! hf_track_pid_reduced::TOFNSigmaKaProng1, hf_track_vars_reduced::HasTOFProng1, hf_track_vars_reduced::HasTPCProng1, - hf_track_pid_reduced::TPCTOFNSigmaPiProng0, - hf_track_pid_reduced::TPCTOFNSigmaKaProng0); + hf_track_pid_reduced::TPCTOFNSigmaPiProng1, + hf_track_pid_reduced::TPCTOFNSigmaKaProng1); DECLARE_SOA_TABLE(HfRedPidDau2s, "AOD", "HFREDPIDDAU2", //! hf_track_pid_reduced::TPCNSigmaPiProng2, diff --git a/PWGHF/D2H/Macros/HFInvMassFitter.h b/PWGHF/D2H/Macros/HFInvMassFitter.h index 6ac9357c5c2..410450de273 100644 --- a/PWGHF/D2H/Macros/HFInvMassFitter.h +++ b/PWGHF/D2H/Macros/HFInvMassFitter.h @@ -20,7 +20,8 @@ #ifndef PWGHF_D2H_MACROS_HFINVMASSFITTER_H_ #define PWGHF_D2H_MACROS_HFINVMASSFITTER_H_ -#include // std::string +#include // std::cout +#include // std::string #include #include @@ -121,7 +122,7 @@ class HFInvMassFitter : public TNamed { if (mean < meanLowLimit || mean > meanUpLimit) { - cout << "Invalid Gaussian mean limmit!" << endl; + std::cout << "Invalid Gaussian mean limmit!" << std::endl; } setInitialGaussianMean(mean); mMassLowLimit = meanLowLimit; @@ -132,7 +133,7 @@ class HFInvMassFitter : public TNamed { if (mean < meanLowLimit || mean > meanUpLimit) { - cout << "Invalid Gaussian mean limmit for reflection!" << endl; + std::cout << "Invalid Gaussian mean limmit for reflection!" << std::endl; } setInitialGaussianMean(mean); mMassReflLowLimit = meanLowLimit; @@ -153,7 +154,7 @@ class HFInvMassFitter : public TNamed void setFixSecondGaussianSigma(Double_t sigma) { if (mTypeOfSgnPdf != DoubleGaus) { - cout << "Fit type should be 2Gaus!" << endl; + std::cout << "Fit type should be 2Gaus!" << std::endl; } setInitialSecondGaussianSigma(sigma); mFixedSigmaDoubleGaus = kTRUE; @@ -162,7 +163,7 @@ class HFInvMassFitter : public TNamed { if (mTypeOfSgnPdf != DoubleGaus && mTypeOfSgnPdf != DoubleGausSigmaRatioPar) { - cout << "Fit type should be 2Gaus or 2GausSigmaRatio!" << endl; + std::cout << "Fit type should be 2Gaus or 2GausSigmaRatio!" << std::endl; } setInitialFracDoubleGaus(frac); mFixedFracDoubleGaus = kTRUE; @@ -170,7 +171,7 @@ class HFInvMassFitter : public TNamed void setFixRatioToGausSigma(Double_t sigmaFrac) { if (mTypeOfSgnPdf != DoubleGausSigmaRatioPar) { - cout << "Fit type should be set to k2GausSigmaRatioPar!" << endl; + std::cout << "Fit type should be set to k2GausSigmaRatioPar!" << std::endl; } setInitialRatioDoubleGausSigma(sigmaFrac); mFixedRatioDoubleGausSigma = kTRUE; diff --git a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx index 58ed7639b99..0005fd09b96 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx @@ -122,6 +122,8 @@ struct HfCandidateCreatorCharmResoReduced { double massK0{0.}; double massLambda{0.}; double massProton{0.}; + double massPion{0.}; + double massKaon{0.}; double massDplus{0.}; double massDstar{0.}; double massD0{0.}; @@ -165,6 +167,8 @@ struct HfCandidateCreatorCharmResoReduced { massK0 = o2::constants::physics::MassK0Short; massLambda = o2::constants::physics::MassLambda; massProton = o2::constants::physics::MassProton; + massPion = o2::constants::physics::MassPiPlus; + massKaon = o2::constants::physics::MassKPlus; massDplus = o2::constants::physics::MassDPlus; massDstar = o2::constants::physics::MassDStar; massD0 = o2::constants::physics::MassD0; @@ -314,8 +318,12 @@ struct HfCandidateCreatorCharmResoReduced { float ptReso = RecoDecay::pt(RecoDecay::sumOfVec(pVecV0Tr, pVecD)); if constexpr (channel == DecayChannel::DstarTrack) { - invMassReso = RecoDecay::m(std::array{pVecD, pVecV0Tr}, std::array{massDstar, massProton}); - registry.fill(HIST("hMassDstarTrack"), invMassReso, ptReso); + if (candD.dType() > 0) { + invMassReso = RecoDecay::m(std::array{candD.pVectorProng0(), candD.pVectorProng1(), candD.pVectorProng2(), pVecV0Tr}, std::array{massPion, massKaon, massPion, massProton}); + } else { + invMassReso = RecoDecay::m(std::array{candD.pVectorProng1(), candD.pVectorProng0(), candD.pVectorProng2(), pVecV0Tr}, std::array{massPion, massKaon, massPion, massProton}); + } + registry.fill(HIST("hMassDstarTrack"), invMassReso - invMassD, ptReso); } else { switch (channel) { case DecayChannel::Ds1ToDstarK0s: diff --git a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx index 02db4418680..a47f9137f7c 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx @@ -15,6 +15,9 @@ /// \author Alexandre Bigot , IPHC Strasbourg /// \author Fabrizio Grosa , CERN +#include +#include + #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -64,7 +67,7 @@ struct HfCandidateSelectorB0ToDPiReduced { Configurable> binsPtB0Ml{"binsPtB0Ml", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; Configurable> cutDirB0Ml{"cutDirB0Ml", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsB0Ml{"cutsB0Ml", {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 nClassesB0Ml{"nClassesB0Ml", (int8_t)hf_cuts_ml::nCutScores, "Number of classes in ML model"}; + Configurable nClassesB0Ml{"nClassesB0Ml", static_cast(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"}; diff --git a/PWGHF/D2H/TableProducer/candidateSelectorBplusToD0PiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorBplusToD0PiReduced.cxx index 5a45f7c3fab..9960ce06946 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorBplusToD0PiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorBplusToD0PiReduced.cxx @@ -14,6 +14,9 @@ /// /// \author Antonio Palasciano , Università degli Studi di Bari +#include +#include + #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -63,7 +66,7 @@ struct HfCandidateSelectorBplusToD0PiReduced { Configurable> binsPtBpMl{"binsPtBpMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; Configurable> cutDirBpMl{"cutDirBpMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsBpMl{"cutsBpMl", {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 nClassesBpMl{"nClassesBpMl", (int8_t)hf_cuts_ml::nCutScores, "Number of classes in ML model"}; + Configurable nClassesBpMl{"nClassesBpMl", static_cast(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"}; diff --git a/PWGHF/D2H/TableProducer/candidateSelectorBsToDsPiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorBsToDsPiReduced.cxx index 6161e31774d..b89272f3059 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorBsToDsPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorBsToDsPiReduced.cxx @@ -14,6 +14,9 @@ /// /// \author Fabio Catalano , CERN +#include +#include + #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -63,7 +66,7 @@ struct HfCandidateSelectorBsToDsPiReduced { Configurable> binsPtBsMl{"binsPtBsMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; Configurable> cutDirBsMl{"cutDirBsMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsBsMl{"cutsBsMl", {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 nClassesBsMl{"nClassesBsMl", (int8_t)hf_cuts_ml::nCutScores, "Number of classes in ML model"}; + Configurable nClassesBsMl{"nClassesBsMl", static_cast(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"}; diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index a0f5b14e5cc..d3f81aac980 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -36,58 +36,106 @@ namespace o2::aod { namespace hf_cand_b0_lite { -DECLARE_SOA_COLUMN(PtProng0, ptProng0, float); //! Transverse momentum of prong0 (GeV/c) -DECLARE_SOA_COLUMN(PtProng1, ptProng1, float); //! Transverse momentum of prong1 (GeV/c) -DECLARE_SOA_COLUMN(MProng0, mProng0, float); //! Invariant mass of prong0 (GeV/c) -DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) -DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! Transverse momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) -DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate -DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate -DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate -DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) -DECLARE_SOA_COLUMN(NSigTpcPi1, nSigTpcPi1, float); //! TPC Nsigma separation for prong1 with pion mass hypothesis -DECLARE_SOA_COLUMN(NSigTofPi1, nSigTofPi1, float); //! TOF Nsigma separation for prong1 with pion mass hypothesis -DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length of candidate (cm) -DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) -DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate -DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! Normalised transverse decay length of candidate -DECLARE_SOA_COLUMN(ImpactParameterProduct, impactParameterProduct, float); //! Impact parameter product of candidate -DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate -DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane -DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! Maximum normalized difference between measured and expected impact parameter of candidate prongs -DECLARE_SOA_COLUMN(MlScoreSig, mlScoreSig, float); //! ML score for signal class -DECLARE_SOA_COLUMN(FlagWrongCollision, flagWrongCollision, int8_t); //! Flag for association with wrong collision +DECLARE_SOA_COLUMN(PtD, ptD, float); //! Transverse momentum of D-meson daughter candidate (GeV/c) +DECLARE_SOA_COLUMN(PtBach, ptBach, float); //! Transverse momentum of bachelor pion (GeV/c) +DECLARE_SOA_COLUMN(AbsEtaBach, absEtaBach, float); //! Absolute pseudorapidity of bachelor pion +DECLARE_SOA_COLUMN(ItsNClsBach, itsNClsBach, int); //! Number of ITS clusters of bachelor pion +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsBach, tpcNClsCrossedRowsBach, int); //! Number of TPC crossed rows of prongs of bachelor pion +DECLARE_SOA_COLUMN(TpcChi2NClBach, tpcChi2NClBach, float); //! Maximum TPC chi2 of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(PtDmesProngMin, ptProngDmesMin, float); //! Minimum pT of prongs of D-meson daughter candidate (GeV/c) +DECLARE_SOA_COLUMN(AbsEtaDmesProngMin, absEtaProngDmesMin, float); //! Minimum absolute pseudorapidity of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(ItsNClsDmesProngMin, itsNClsDmesProngMin, int); //! Minimum number of ITS clusters of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(TpcNClsCrossedRowsDmesProngMin, tpcNClsCrossedRowsDmesProngMin, int); //! Minimum number of TPC crossed rows of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(TpcChi2NClDmesProngMax, tpcChi2NClDmesProngMax, float); //! Maximum TPC chi2 of prongs of D-meson daughter candidate +DECLARE_SOA_COLUMN(MD, mD, float); //! Invariant mass of D-meson daughter candidates (GeV/c) +DECLARE_SOA_COLUMN(M, m, float); //! Invariant mass of candidate (GeV/c2) +DECLARE_SOA_COLUMN(Pt, pt, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! Transverse momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(P, p, float); //! Momentum of candidate (GeV/c) +DECLARE_SOA_COLUMN(Y, y, float); //! Rapidity of candidate +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity of candidate +DECLARE_SOA_COLUMN(Phi, phi, float); //! Azimuth angle of candidate +DECLARE_SOA_COLUMN(E, e, float); //! Energy of candidate (GeV) +DECLARE_SOA_COLUMN(NSigTpcPiBachelor, nSigTpcPiBachelor, float); //! TPC Nsigma separation for bachelor with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiBachelor, nSigTofPiBachelor, float); //! TOF Nsigma separation for bachelor with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiBachelor, nSigTpcTofPiBachelor, float); //! Combined TPC and TOF Nsigma separation for bachelor with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcPiDmesProng0, nSigTpcPiDmesProng0, float); //! TPC Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiDmesProng0, nSigTofPiDmesProng0, float); //! TOF Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiDmesProng0, nSigTpcTofPiDmesProng0, float); //! Combined TPC and TOF Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcKaDmesProng1, nSigTpcKaDmesProng1, float); //! TPC Nsigma separation for D-meson prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTofKaDmesProng1, nSigTofKaDmesProng1, float); //! TOF Nsigma separation for D-meson prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofKaDmesProng1, nSigTpcTofKaDmesProng1, float); //! Combined TPC and TOF Nsigma separation for D-meson prong1 with kaon mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcPiDmesProng2, nSigTpcPiDmesProng2, float); //! TPC Nsigma separation for D-meson prong2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTofPiDmesProng2, nSigTofPiDmesProng2, float); //! TOF Nsigma separation for D-meson prong2 with pion mass hypothesis +DECLARE_SOA_COLUMN(NSigTpcTofPiDmesProng2, nSigTpcTofPiDmesProng2, float); //! Combined TPC and TOF Nsigma separation for D-meson prong0 with pion mass hypothesis +DECLARE_SOA_COLUMN(DecayLength, decayLength, float); //! Decay length of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); //! Transverse decay length of candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); //! Normalised decay length of candidate +DECLARE_SOA_COLUMN(DecayLengthXYNormalised, decayLengthXYNormalised, float); //! Normalised transverse decay length of candidate +DECLARE_SOA_COLUMN(DecayLengthD, decayLengthD, float); //! Decay length of D-meson daughter candidate (cm) +DECLARE_SOA_COLUMN(DecayLengthXYD, decayLengthXYD, float); //! Transverse decay length of D-meson daughter candidate (cm) +DECLARE_SOA_COLUMN(ImpactParameterD, impactParameterD, float); //! Impact parameter product of D-meson daughter candidate +DECLARE_SOA_COLUMN(ImpactParameterBach, impactParameterBach, float); //! Impact parameter product of bachelor pion +DECLARE_SOA_COLUMN(ImpactParameterProduct, impactParameterProduct, float); //! Impact parameter product of daughters +DECLARE_SOA_COLUMN(Cpa, cpa, float); //! Cosine pointing angle of candidate +DECLARE_SOA_COLUMN(CpaXY, cpaXY, float); //! Cosine pointing angle of candidate in transverse plane +DECLARE_SOA_COLUMN(MaxNormalisedDeltaIP, maxNormalisedDeltaIP, float); //! Maximum normalized difference between measured and expected impact parameter of candidate prongs +DECLARE_SOA_COLUMN(MlScoreSig, mlScoreSig, float); //! ML score for signal class +DECLARE_SOA_COLUMN(FlagWrongCollision, flagWrongCollision, int8_t); //! Flag for association with wrong collision } // namespace hf_cand_b0_lite DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with some B0 properties + // B meson features hf_cand_b0_lite::M, + hf_cand_b0_lite::M, + hf_cand_b0_lite::Pt, + hf_cand_b0_lite::Eta, + hf_cand_b0_lite::Phi, + hf_cand_b0_lite::Y, + hf_cand_b0_lite::Cpa, + hf_cand_b0_lite::CpaXY, hf_cand::Chi2PCA, hf_cand_b0_lite::DecayLength, hf_cand_b0_lite::DecayLengthXY, hf_cand_b0_lite::DecayLengthNormalised, hf_cand_b0_lite::DecayLengthXYNormalised, - hf_cand_b0_lite::MProng0, - hf_cand_b0_lite::PtProng0, - hf_cand_b0_lite::PtProng1, - hf_cand::ImpactParameter0, - hf_cand::ImpactParameter1, hf_cand_b0_lite::ImpactParameterProduct, - hf_cand_b0_lite::NSigTpcPi1, - hf_cand_b0_lite::NSigTofPi1, + hf_cand_b0_lite::MaxNormalisedDeltaIP, + hf_cand_b0_lite::MlScoreSig, + hf_sel_candidate_b0::IsSelB0ToDPi, + // D meson features + hf_cand_b0_lite::MD, + hf_cand_b0_lite::PtD, + hf_cand_b0_lite::DecayLengthD, + hf_cand_b0_lite::DecayLengthXYD, + hf_cand_b0_lite::ImpactParameterD, + hf_cand_b0_lite::PtDmesProngMin, + hf_cand_b0_lite::AbsEtaDmesProngMin, + hf_cand_b0_lite::ItsNClsDmesProngMin, + hf_cand_b0_lite::TpcNClsCrossedRowsDmesProngMin, + hf_cand_b0_lite::TpcChi2NClDmesProngMax, + hf_cand_b0_lite::NSigTpcPiDmesProng0, + hf_cand_b0_lite::NSigTofPiDmesProng0, + hf_cand_b0_lite::NSigTpcTofPiDmesProng0, + hf_cand_b0_lite::NSigTpcKaDmesProng1, + hf_cand_b0_lite::NSigTofKaDmesProng1, + hf_cand_b0_lite::NSigTpcTofKaDmesProng1, + hf_cand_b0_lite::NSigTpcPiDmesProng2, + hf_cand_b0_lite::NSigTofPiDmesProng2, + hf_cand_b0_lite::NSigTpcTofPiDmesProng2, hf_cand_b0_reduced::Prong0MlScoreBkg, hf_cand_b0_reduced::Prong0MlScorePrompt, hf_cand_b0_reduced::Prong0MlScoreNonprompt, - hf_cand_b0_lite::MlScoreSig, - hf_sel_candidate_b0::IsSelB0ToDPi, - hf_cand_b0_lite::M, - hf_cand_b0_lite::Pt, - hf_cand_b0_lite::Cpa, - hf_cand_b0_lite::CpaXY, - hf_cand_b0_lite::MaxNormalisedDeltaIP, - hf_cand_b0_lite::Eta, - hf_cand_b0_lite::Phi, - hf_cand_b0_lite::Y, + // pion features + hf_cand_b0_lite::PtBach, + hf_cand_b0_lite::AbsEtaBach, + hf_cand_b0_lite::ItsNClsBach, + hf_cand_b0_lite::TpcNClsCrossedRowsBach, + hf_cand_b0_lite::TpcChi2NClBach, + hf_cand_b0_lite::ImpactParameterBach, + hf_cand_b0_lite::NSigTpcPiBachelor, + hf_cand_b0_lite::NSigTofPiBachelor, + hf_cand_b0_lite::NSigTpcTofPiBachelor, + // MC truth hf_cand_3prong::FlagMcMatchRec, hf_cand_3prong::OriginMcRec, hf_cand_b0_lite::FlagWrongCollision, @@ -96,8 +144,8 @@ DECLARE_SOA_TABLE(HfRedCandB0Lites, "AOD", "HFREDCANDB0LITE", //! Table with som DECLARE_SOA_TABLE(HfRedB0McCheck, "AOD", "HFREDB0MCCHECK", //! Table with MC decay type check hf_cand_3prong::FlagMcMatchRec, hf_cand_b0_lite::FlagWrongCollision, - hf_cand_b0_lite::MProng0, - hf_cand_b0_lite::PtProng0, + hf_cand_b0_lite::MD, + hf_cand_b0_lite::PtD, hf_cand_b0_lite::M, hf_cand_b0_lite::Pt, hf_cand_b0_lite::MlScoreSig, @@ -133,6 +181,7 @@ struct HfTaskB0Reduced { HistogramRegistry registry{"registry"}; using TracksPion = soa::Join; + using CandsDplus = soa::Join; void init(InitContext&) { @@ -326,13 +375,13 @@ struct HfTaskB0Reduced { /// \param withB0Ml is the flag to enable the filling with ML scores for the B0 candidate /// \param candidate is the B0 candidate /// \param candidatesD is the table with D- candidates - template + template void fillCand(Cand const& candidate, - aod::HfRed3Prongs const&) + CandsDmes const&) { auto ptCandB0 = candidate.pt(); auto invMassB0 = hfHelper.invMassB0ToDPi(candidate); - auto candD = candidate.template prong0_as(); + auto candD = candidate.template prong0_as(); auto ptD = candidate.ptProng0(); auto invMassD = candD.invMassHypo0(); std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; @@ -474,7 +523,7 @@ struct HfTaskB0Reduced { } } if (fillTree) { - float pseudoRndm = ptD * 1000. - (int64_t)(ptD * 1000); + float pseudoRndm = ptD * 1000. - static_cast(ptD * 1000); if (flagMcMatchRec != 0 || (((doMc && fillBackground) || !doMc) && (ptCandB0 >= ptMaxForDownSample || pseudoRndm < downSampleBkgFactor))) { float prong0MlScoreBkg = -1.; float prong0MlScorePrompt = -1.; @@ -496,42 +545,63 @@ struct HfTaskB0Reduced { } hfRedCandB0Lite( + // B-meson features + invMassB0, + ptCandB0, + candidate.eta(), + candidate.phi(), + hfHelper.yB0(candidate), + candidate.cpa(), + candidate.cpaXY(), candidate.chi2PCA(), candidate.decayLength(), candidate.decayLengthXY(), candidate.decayLengthNormalised(), candidate.decayLengthXYNormalised(), + candidate.impactParameterProduct(), + candidate.maxNormalisedDeltaIP(), + candidateMlScoreSig, + candidate.isSelB0ToDPi(), + // D-meson features invMassD, ptD, - candidate.ptProng1(), + decLenD, + decLenXyD, candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameterProduct(), - prong1.tpcNSigmaPi(), - prong1.tofNSigmaPi(), + candD.ptProngMin(), + candD.absEtaProngMin(), + candD.itsNClsProngMin(), + candD.tpcNClsCrossedRowsProngMin(), + candD.tpcChi2NClProngMax(), + candD.tpcNSigmaPiProng0(), + candD.tofNSigmaPiProng0(), + candD.tpcTofNSigmaPiProng0(), + candD.tpcNSigmaKaProng1(), + candD.tofNSigmaKaProng1(), + candD.tpcTofNSigmaKaProng1(), + candD.tpcNSigmaPiProng2(), + candD.tofNSigmaPiProng2(), + candD.tpcTofNSigmaPiProng2(), prong0MlScoreBkg, prong0MlScorePrompt, prong0MlScoreNonprompt, - candidateMlScoreSig, - candidate.isSelB0ToDPi(), - invMassB0, - ptCandB0, - candidate.cpa(), - candidate.cpaXY(), - candidate.maxNormalisedDeltaIP(), - candidate.eta(), - candidate.phi(), - hfHelper.yB0(candidate), + // pion features + candidate.ptProng1(), + std::abs(RecoDecay::eta(prong1.pVector())), + prong1.itsNCls(), + prong1.tpcNClsCrossedRows(), + prong1.tpcChi2NCl(), + candidate.impactParameter1(), + prong1.tpcNSigmaPi(), + prong1.tofNSigmaPi(), + prong1.tpcTofNSigmaPi(), + // MC truth flagMcMatchRec, isSignal, flagWrongCollision, ptMother); if constexpr (withDecayTypeCheck) { - float candidateMlScoreSig = -1; - if constexpr (withB0Ml) { - candidateMlScoreSig = candidate.mlProbB0ToDPi(); - } hfRedB0McCheck( flagMcMatchRec, flagWrongCollision, @@ -591,7 +661,7 @@ struct HfTaskB0Reduced { // Process functions void processData(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { for (const auto& candidate : candidates) { @@ -604,7 +674,7 @@ struct HfTaskB0Reduced { PROCESS_SWITCH(HfTaskB0Reduced, processData, "Process data without ML scores for B0 and D daughter", true); void processDataWithDmesMl(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { for (const auto& candidate : candidates) { @@ -617,7 +687,7 @@ struct HfTaskB0Reduced { PROCESS_SWITCH(HfTaskB0Reduced, processDataWithDmesMl, "Process data with(out) ML scores for D daughter (B0)", false); void processDataWithB0Ml(soa::Filtered> const& candidates, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { for (const auto& candidate : candidates) { @@ -631,7 +701,7 @@ struct HfTaskB0Reduced { void processMc(soa::Filtered> const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { // MC rec @@ -651,7 +721,7 @@ struct HfTaskB0Reduced { void processMcWithDecayTypeCheck(soa::Filtered> const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { // MC rec @@ -671,7 +741,7 @@ struct HfTaskB0Reduced { void processMcWithDmesMl(soa::Filtered> const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { // MC rec @@ -691,7 +761,7 @@ struct HfTaskB0Reduced { void processMcWithDmesMlAndDecayTypeCheck(soa::Filtered> const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { // MC rec @@ -711,7 +781,7 @@ struct HfTaskB0Reduced { void processMcWithB0Ml(soa::Filtered> const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { // MC rec @@ -731,7 +801,7 @@ struct HfTaskB0Reduced { void processMcWithB0MlAndDecayTypeCheck(soa::Filtered> const& candidates, aod::HfMcGenRedB0s const& mcParticles, - aod::HfRed3Prongs const& candidatesD, + CandsDplus const& candidatesD, TracksPion const&) { // MC rec diff --git a/PWGHF/D2H/Tasks/taskBplus.cxx b/PWGHF/D2H/Tasks/taskBplus.cxx index 9586ebaa424..b98a2930258 100644 --- a/PWGHF/D2H/Tasks/taskBplus.cxx +++ b/PWGHF/D2H/Tasks/taskBplus.cxx @@ -18,6 +18,8 @@ /// \author Antonio Palasciano , Università degli Studi di Bari & INFN, Sezione di Bari /// \author Deepa Thomas , UT Austin +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" @@ -263,7 +265,7 @@ struct HfTaskBplus { float ptProngs[2], yProngs[2], etaProngs[2]; int counter = 0; - for (const auto& daught : particle.daughters_as()) { + for (const auto& daught : particle.daughters_as>()) { ptProngs[counter] = daught.pt(); etaProngs[counter] = daught.eta(); yProngs[counter] = RecoDecay::y(daught.pVector(), pdg->Mass(daught.pdgCode())); diff --git a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx index cbcfb44a85b..1594cc5e9cc 100644 --- a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx +++ b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx @@ -16,6 +16,8 @@ /// \author S. Kundu (CERN) sourav.kundu@cern.ch /// \author M. Faggin (CERN) mattia.faggin@cern.ch +#include + #include "TRandom3.h" #include "Math/Vector3D.h" #include "Math/Vector4D.h" @@ -189,6 +191,9 @@ struct TaskPolarisationCharmHadrons { Configurable activateTHnEulerPhiMonitor{"activateTHnEulerPhiMonitor", false, "Flag to switch on the monitoring THnSparse vs. Euler angle phi (Lc -> pKpi)"}; ConfigurableAxis configTHnAxisEulerPhi{"configTHnAxisEulerPhi", {24, -o2::constants::math::PI, o2::constants::math::PI}, "Euler polar angle #phi"}; + /// Application of rapidity cut for reconstructed candidates + Configurable rapidityCut{"rapidityCut", 999.f, "Max. value of reconstructed candidate rapidity (abs. value)"}; + 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); @@ -537,18 +542,18 @@ struct TaskPolarisationCharmHadrons { if constexpr (!doMc) { // data if constexpr (withMl) { // with ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); if (activateTHnEulerPhiMonitor) { registry.fill(HIST("hEulerPhiHelicity"), invMassCharmHad, ptCharmHad, invMassKPiLc, phiEuler, outputMl[0], /*outputMl[1],*/ outputMl[2], charge); } } } else { // without ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hHelicity"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); if (activateTHnEulerPhiMonitor) { registry.fill(HIST("hEulerPhiHelicity"), invMassCharmHad, ptCharmHad, invMassKPiLc, phiEuler, charge); } @@ -601,18 +606,18 @@ struct TaskPolarisationCharmHadrons { if constexpr (!doMc) { // data if constexpr (withMl) { // with ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); if (activateTHnEulerPhiMonitor) { registry.fill(HIST("hEulerPhiProduction"), invMassCharmHad, ptCharmHad, invMassKPiLc, phiEuler, outputMl[0], /*outputMl[1],*/ outputMl[2], charge); } } } else { // without ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hProduction"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); if (activateTHnEulerPhiMonitor) { registry.fill(HIST("hEulerPhiProduction"), invMassCharmHad, ptCharmHad, invMassKPiLc, phiEuler, charge); } @@ -665,18 +670,18 @@ struct TaskPolarisationCharmHadrons { if constexpr (!doMc) { // data if constexpr (withMl) { // with ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); if (activateTHnEulerPhiMonitor) { registry.fill(HIST("hEulerPhiBeam"), invMassCharmHad, ptCharmHad, invMassKPiLc, phiEuler, outputMl[0], /*outputMl[1],*/ outputMl[2], charge); } } } else { // without ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hBeam"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); if (activateTHnEulerPhiMonitor) { registry.fill(HIST("hEulerPhiBeam"), invMassCharmHad, ptCharmHad, invMassKPiLc, phiEuler, charge); } @@ -729,15 +734,15 @@ struct TaskPolarisationCharmHadrons { if constexpr (!doMc) { // data if constexpr (withMl) { // with ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, outputMl[0], /*outputMl[1],*/ outputMl[2], absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); } } else { // without ML if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { // D*+ - registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); + registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassD0, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate); } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { // Lc+ - registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, rapCharmHad, invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); + registry.fill(HIST("hRandom"), invMassCharmHad, ptCharmHad, numPvContributors, std::abs(rapCharmHad), invMassKPiLc, cosThetaStar, absEtaMin, numItsClsMin, numTpcClsMin, isRotatedCandidate, charge); } } } else { // MC --> no distinction among channels, since rotational bkg not supported @@ -1168,6 +1173,11 @@ struct TaskPolarisationCharmHadrons { continue; } + /// apply rapidity selection on the reconstructed candidate + if (std::abs(rapidity) > rapidityCut) { + continue; + } + float phiRandom = gRandom->Uniform(0.f, constants::math::TwoPI); float thetaRandom = gRandom->Uniform(0.f, constants::math::PI); ROOT::Math::PxPyPzMVector fourVecDau = ROOT::Math::PxPyPzMVector(pxDau, pyDau, pzDau, massDau); diff --git a/PWGHF/D2H/Tasks/taskDirectedFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskDirectedFlowCharmHadrons.cxx index 1905048725f..5d52470a6b0 100644 --- a/PWGHF/D2H/Tasks/taskDirectedFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskDirectedFlowCharmHadrons.cxx @@ -48,6 +48,7 @@ struct HfTaskDirectedFlowCharmHadrons { Configurable centralityMin{"centralityMin", 0., "Minimum centrality accepted in SP computation"}; Configurable centralityMax{"centralityMax", 100., "Maximum centrality accepted in SP computation"}; Configurable storeMl{"storeMl", false, "Flag to store ML scores"}; + Configurable direct{"direct", false, "Flag to calculate direct v1 odd and even"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> classMl{"classMl", {0, 2}, "Indices of BDT scores to be stored. Two indexes max."}; @@ -100,15 +101,23 @@ struct HfTaskDirectedFlowCharmHadrons { if (storeMl) { axes.insert(axes.end(), {thnAxisMlOne, thnAxisMlTwo}); } - registry.add("hpuxQxpvscentpteta", "hpuxQxpvscentpteta", HistType::kTHnSparseF, axes, true); - registry.add("hpuyQypvscentpteta", "hpuyQypvscentpteta", HistType::kTHnSparseF, axes, true); - registry.add("hpuxQxtvscentpteta", "hpuxQxtvscentpteta", HistType::kTHnSparseF, axes, true); - registry.add("hpuyQytvscentpteta", "hpuyQytvscentpteta", HistType::kTHnSparseF, axes, true); - registry.add("hpQxtQxpvscent", "hpQxtQxpvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); - registry.add("hpQytQypvscent", "hpQytQypvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); - registry.add("hpQxtQypvscent", "hpQxtQypvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); - registry.add("hpQxpQytvscent", "hpQxpQytvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); + if (direct) { + registry.add("hpQxytpvscent", "hpQxytpvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); + registry.add("hpuxyQxypvscentpteta", "hpuxyQxypvscentpteta", HistType::kTHnSparseF, axes, true); + registry.add("hpuxyQxytvscentpteta", "hpuxyQxytvscentpteta", HistType::kTHnSparseF, axes, true); + registry.add("hpoddvscentpteta", "hpoddvscentpteta", HistType::kTHnSparseF, axes, true); + registry.add("hpevenvscentpteta", "hpevenvscentpteta", HistType::kTHnSparseF, axes, true); + } else { + registry.add("hpQxtQxpvscent", "hpQxtQxpvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); + registry.add("hpQytQypvscent", "hpQytQypvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); + registry.add("hpQxtQypvscent", "hpQxtQypvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); + registry.add("hpQxpQytvscent", "hpQxpQytvscent", HistType::kTHnSparseF, {thnAxisCent, thnAxisScalarProd}, true); + registry.add("hpuxQxpvscentpteta", "hpuxQxpvscentpteta", HistType::kTHnSparseF, axes, true); + registry.add("hpuyQypvscentpteta", "hpuyQypvscentpteta", HistType::kTHnSparseF, axes, true); + registry.add("hpuxQxtvscentpteta", "hpuxQxtvscentpteta", HistType::kTHnSparseF, axes, true); + registry.add("hpuyQytvscentpteta", "hpuyQytvscentpteta", HistType::kTHnSparseF, axes, true); + } ccdb->setURL(ccdbUrl); ccdb->setCaching(true); @@ -154,7 +163,7 @@ struct HfTaskDirectedFlowCharmHadrons { return; } - if (!collision.triggerevent()) { // for selecting only callibrated events + if (!collision.triggereventsp()) { // for selecting only callibrated events return; } @@ -165,14 +174,19 @@ struct HfTaskDirectedFlowCharmHadrons { auto QxtQxp = qxZDCC * qxZDCA; auto QytQyp = qyZDCC * qyZDCA; + auto Qxytp = QxtQxp + QytQyp; auto QxpQyt = qxZDCA * qyZDCC; auto QxtQyp = qxZDCC * qyZDCA; // correlations in the denominators for SP calculation - registry.fill(HIST("hpQxtQxpvscent"), cent, QxtQxp); - registry.fill(HIST("hpQytQypvscent"), cent, QytQyp); - registry.fill(HIST("hpQxpQytvscent"), cent, QxpQyt); - registry.fill(HIST("hpQxtQypvscent"), cent, QxtQyp); + if (direct) { + registry.fill(HIST("hpQxytpvscent"), cent, Qxytp); + } else { + registry.fill(HIST("hpQxtQxpvscent"), cent, QxtQxp); + registry.fill(HIST("hpQytQypvscent"), cent, QytQyp); + registry.fill(HIST("hpQxpQytvscent"), cent, QxpQyt); + registry.fill(HIST("hpQxtQypvscent"), cent, QxtQyp); + } for (const auto& candidate : candidates) { double massCand = 0.; @@ -198,19 +212,37 @@ struct HfTaskDirectedFlowCharmHadrons { auto uy = sinNPhi; // imaginary part of candidate q vector auto uxQxp = ux * qxZDCA; auto uyQyp = uy * qyZDCA; // correlations of particle and ZDC q vectors + auto uxyQxyp = uxQxp + uyQyp; auto uxQxt = ux * qxZDCC; auto uyQyt = uy * qyZDCC; + auto uxyQxyt = uxQxt + uyQyt; + auto oddv1 = ux * (qxZDCA - qxZDCC) + uy * (qyZDCA - qyZDCC); + auto evenv1 = ux * (qxZDCA + qxZDCC) + uy * (qyZDCA + qyZDCC); if (storeMl) { - registry.fill(HIST("hpuxQxpvscentpteta"), massCand, cent, ptCand, etaCand, uxQxp, sign, outputMl[0], outputMl[1]); - registry.fill(HIST("hpuyQypvscentpteta"), massCand, cent, ptCand, etaCand, uyQyp, sign, outputMl[0], outputMl[1]); - registry.fill(HIST("hpuxQxtvscentpteta"), massCand, cent, ptCand, etaCand, uxQxt, sign, outputMl[0], outputMl[1]); - registry.fill(HIST("hpuyQytvscentpteta"), massCand, cent, ptCand, etaCand, uyQyt, sign, outputMl[0], outputMl[1]); + if (direct) { + registry.fill(HIST("hpuxyQxypvscentpteta"), massCand, cent, ptCand, etaCand, uxyQxyp, sign, outputMl[0], outputMl[1]); + registry.fill(HIST("hpuxyQxytvscentpteta"), massCand, cent, ptCand, etaCand, uxyQxyt, sign, outputMl[0], outputMl[1]); + registry.fill(HIST("hpoddvscentpteta"), massCand, cent, ptCand, etaCand, oddv1, sign, outputMl[0], outputMl[1]); + registry.fill(HIST("hpevenvscentpteta"), massCand, cent, ptCand, etaCand, evenv1, sign, outputMl[0], outputMl[1]); + } else { + registry.fill(HIST("hpuxQxpvscentpteta"), massCand, cent, ptCand, etaCand, uxQxp, sign, outputMl[0], outputMl[1]); + registry.fill(HIST("hpuyQypvscentpteta"), massCand, cent, ptCand, etaCand, uyQyp, sign, outputMl[0], outputMl[1]); + registry.fill(HIST("hpuxQxtvscentpteta"), massCand, cent, ptCand, etaCand, uxQxt, sign, outputMl[0], outputMl[1]); + registry.fill(HIST("hpuyQytvscentpteta"), massCand, cent, ptCand, etaCand, uyQyt, sign, outputMl[0], outputMl[1]); + } } else { - registry.fill(HIST("hpuxQxpvscentpteta"), massCand, cent, ptCand, etaCand, uxQxp, sign); - registry.fill(HIST("hpuyQypvscentpteta"), massCand, cent, ptCand, etaCand, uyQyp, sign); - registry.fill(HIST("hpuxQxtvscentpteta"), massCand, cent, ptCand, etaCand, uxQxt, sign); - registry.fill(HIST("hpuyQytvscentpteta"), massCand, cent, ptCand, etaCand, uyQyt, sign); + if (direct) { + registry.fill(HIST("hpuxyQxypvscentpteta"), massCand, cent, ptCand, etaCand, uxyQxyp, sign); + registry.fill(HIST("hpuxyQxytvscentpteta"), massCand, cent, ptCand, etaCand, uxyQxyt, sign); + registry.fill(HIST("hpoddvscentpteta"), massCand, cent, ptCand, etaCand, oddv1, sign); + registry.fill(HIST("hpevenvscentpteta"), massCand, cent, ptCand, etaCand, evenv1, sign); + } else { + registry.fill(HIST("hpuxQxpvscentpteta"), massCand, cent, ptCand, etaCand, uxQxp, sign); + registry.fill(HIST("hpuyQypvscentpteta"), massCand, cent, ptCand, etaCand, uyQyp, sign); + registry.fill(HIST("hpuxQxtvscentpteta"), massCand, cent, ptCand, etaCand, uxQxt, sign); + registry.fill(HIST("hpuyQytvscentpteta"), massCand, cent, ptCand, etaCand, uyQyt, sign); + } } } } diff --git a/PWGHF/D2H/Tasks/taskDs.cxx b/PWGHF/D2H/Tasks/taskDs.cxx index 5cd09dfa9f5..e9c49d9fc86 100644 --- a/PWGHF/D2H/Tasks/taskDs.cxx +++ b/PWGHF/D2H/Tasks/taskDs.cxx @@ -17,10 +17,18 @@ /// \author Stefano Politanò , Politecnico & INFN Torino /// \author Fabrizio Chinu , Universita and INFN Torino +#include +#include +#include +#include +#include + +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" +#include "MetadataHelper.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/CentralityEstimation.h" @@ -32,6 +40,8 @@ using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; +MetadataHelper metadataInfo; // Metadata helper + enum FinalState { KKPi = 0, PiKK }; @@ -65,14 +75,23 @@ struct HfTaskDs { Configurable massDsSignalMax{"massDsSignalMax", 1.994, "max mass for Ds signal"}; Configurable massDplusSignalMin{"massDplusSignalMin", 1.866, "min mass for Dplus signal"}; Configurable massDplusSignalMax{"massDplusSignalMax", 1.906, "max mass for Dplus signal"}; + Configurable fillPercentiles{"fillPercentiles", true, "Wheter to fill multiplicity axis with percentiles or raw information"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 8.f, 12.f, 24.f}, "axis for pT"}; ConfigurableAxis axisNPvContributors{"axisNPvContributors", {200, -0.5f, 199.5f}, "axis for NPvContributors"}; ConfigurableAxis axisMlScore0{"axisMlScore0", {100, 0., 1.}, "axis for ML output score 0"}; ConfigurableAxis axisMlScore1{"axisMlScore1", {100, 0., 1.}, "axis for ML output score 1"}; ConfigurableAxis axisMlScore2{"axisMlScore2", {100, 0., 1.}, "axis for ML output score 2"}; + ConfigurableAxis axisCentrality{"axisCentrality", {100, 0., 1.}, "axis for centrality/multiplicity"}; + + struct : ConfigurableGroup { + Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "The CCDB endpoint url address"}; + Configurable ccdbPath{"ccdbpath", "Centrality/Calibration", "The CCDB path for centrality/multiplicity information"}; + Configurable reconstructionPass{"reconstructionPass", "", {"Apass to use when fetching the calibration tables. Empty (default) does not check for any pass. Use `metadata` to fetch it from the AO2D metadata. Otherwise it will override the metadata."}}; + } ccdbConfig; HfHelper hfHelper; + Service ccdb; using TH1_ptr = std::shared_ptr; using TH2_ptr = std::shared_ptr; @@ -81,14 +100,14 @@ struct HfTaskDs { template using MemberFunctionPointer = bool (HfTaskDs::*)(const CandDs&); - using CollisionsWithFT0C = soa::Join; - using CollisionsWithFT0M = soa::Join; - using CollisionsWithNTracksPV = soa::Join; + using CollisionsWithFT0C = soa::Join; + using CollisionsWithFT0M = soa::Join; + using CollisionsWithNTracksPV = soa::Join; using CollisionsMc = soa::Join; - using CollisionsMcWithFT0C = soa::Join; - using CollisionsMcWithFT0M = soa::Join; - using CollisionsMcWithNTracksPV = soa::Join; + using CollisionsMcWithFT0C = soa::Join; + using CollisionsMcWithFT0M = soa::Join; + using CollisionsMcWithNTracksPV = soa::Join; using CandDsData = soa::Filtered>; using CandDsDataWithMl = soa::Filtered>; @@ -101,6 +120,12 @@ struct HfTaskDs { SliceCache cache; int offsetDplusDecayChannel = aod::hf_cand_3prong::DecayChannelDToKKPi::DplusToPhiPi - aod::hf_cand_3prong::DecayChannelDToKKPi::DsToPhiPi; // Offset between Dplus and Ds to use the same decay channel. See aod::hf_cand_3prong::DecayChannelDToKKPi + int mRunNumber{0}; + bool lCalibLoaded; + TList* lCalibObjects; + TProfile* hVtxZFT0A; + TProfile* hVtxZFT0C; + TProfile* hVtxZNTracks; Filter filterDsFlag = (o2::aod::hf_track_index::hfflag & static_cast(BIT(aod::hf_cand_3prong::DecayType::DsToKKPi))) != static_cast(0); @@ -252,13 +277,63 @@ struct HfTaskDs { return true; } + /// Evaluate centrality/multiplicity percentile using FT0M estimator + /// \param candidate is candidate + /// \return centrality/multiplicity percentile of the collision + template + float getZEqMultColl(const Coll& collision, uint8_t nProngsContributorsPV) + { + auto multFT0A = collision.multFT0A() - nProngsContributorsPV; + auto multFT0C = collision.multFT0C() - nProngsContributorsPV; + float multZeqFT0A = hVtxZFT0A->Interpolate(0.0) * multFT0A / hVtxZFT0A->Interpolate(collision.posZ()); + float multZeqFT0C = hVtxZFT0C->Interpolate(0.0) * multFT0C / hVtxZFT0C->Interpolate(collision.posZ()); + return multZeqFT0A + multZeqFT0C; + } + + /// Evaluate centrality/multiplicity percentile using NTracksPV estimator + /// \param candidate is candidate + /// \return centrality/multiplicity percentile of the collision + template + float getZEqMultColl(const Coll& collision, uint8_t nProngsContributorsPV) + { + auto multNTracksPV = collision.multNTracksPV() - nProngsContributorsPV; + float multZeqNTracksPV = hVtxZNTracks->Interpolate(0.0) * multNTracksPV / hVtxZNTracks->Interpolate(collision.posZ()); + return multZeqNTracksPV; + } + + /// Default case if no centrality/multiplicity estimator is provided + /// \param candidate is candidate + /// \return dummy value for centrality/multiplicity percentile of the collision + template + float getZEqMultColl(const Coll&, uint8_t) + { + return -1.f; + } + + /// Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table) + /// \param candidate is candidate + /// \return centrality/multiplicity percentile of the collision + template + float evaluateCentralityColl(const Coll& collision, const CandDs& candidate) + { + if (fillPercentiles) { + return o2::hf_centrality::getCentralityColl(collision); + } else { + return getZEqMultColl(collision, candidate.nProngsContributorsPV()); + } + } + /// Evaluate centrality/multiplicity percentile (centrality estimator is automatically selected based on the used table) /// \param candidate is candidate /// \return centrality/multiplicity percentile of the collision template float evaluateCentralityColl(const Coll& collision) { - return o2::hf_centrality::getCentralityColl(collision); + if (fillPercentiles) { + return o2::hf_centrality::getCentralityColl(collision); + } else { + return getZEqMultColl(collision, 0); + } } /// Evaluate centrality/multiplicity percentile @@ -267,7 +342,7 @@ struct HfTaskDs { template float evaluateCentralityCand(const T1& candidate) { - return evaluateCentralityColl(candidate.template collision_as()); + return evaluateCentralityColl(candidate.template collision_as(), candidate); } /// Fill histograms of quantities independent from the daugther-mass hypothesis @@ -583,6 +658,41 @@ struct HfTaskDs { void runDataAnalysisPerCollision(const Coll& collisions, const CandsDs& candsDs) { for (const auto& collision : collisions) { + /* check the previous run number */ + const auto& bc = collision.bc(); + if (bc.runNumber() != mRunNumber) { + mRunNumber = bc.runNumber(); // mark this run as at least tried + if (ccdbConfig.reconstructionPass.value == "") { + lCalibObjects = ccdb->getForRun(ccdbConfig.ccdbPath, mRunNumber); + } else if (ccdbConfig.reconstructionPass.value == "metadata") { + std::map metadata; + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); + lCalibObjects = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, mRunNumber, metadata); + } else { + std::map metadata; + metadata["RecoPassName"] = ccdbConfig.reconstructionPass.value; + LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", ccdbConfig.reconstructionPass.value); + lCalibObjects = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, mRunNumber, metadata); + } + + if (lCalibObjects) { + LOG(info) << "CCDB objects loaded successfully"; + hVtxZFT0A = static_cast(lCalibObjects->FindObject("hVtxZFT0A")); + hVtxZFT0C = static_cast(lCalibObjects->FindObject("hVtxZFT0C")); + hVtxZNTracks = static_cast(lCalibObjects->FindObject("hVtxZNTracksPV")); + lCalibLoaded = true; + // Capture error + if (!hVtxZFT0A || !hVtxZFT0C || !hVtxZNTracks) { + LOGF(error, "Problem loading CCDB objects! Please check"); + lCalibLoaded = false; + } + } else { + LOGF(error, "Problem loading CCDB object! Please check"); + lCalibLoaded = false; + } + } + auto thisCollId = collision.globalIndex(); std::array nCandsPerType{0}; std::array nCandsInSignalRegionDsPerType{0}; @@ -613,6 +723,41 @@ struct HfTaskDs { const CandDsMcGen& mcParticles) { for (const auto& collision : collisions) { + /* check the previous run number */ + const auto& bc = collision.bc(); + if (bc.runNumber() != mRunNumber) { + mRunNumber = bc.runNumber(); // mark this run as at least tried + if (ccdbConfig.reconstructionPass.value == "") { + lCalibObjects = ccdb->getForRun(ccdbConfig.ccdbPath, mRunNumber); + } else if (ccdbConfig.reconstructionPass.value == "metadata") { + std::map metadata; + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGF(info, "Loading CCDB for reconstruction pass (from metadata): %s", metadataInfo.get("RecoPassName")); + lCalibObjects = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, mRunNumber, metadata); + } else { + std::map metadata; + metadata["RecoPassName"] = ccdbConfig.reconstructionPass.value; + LOGF(info, "Loading CCDB for reconstruction pass (from provided argument): %s", ccdbConfig.reconstructionPass.value); + lCalibObjects = ccdb->getSpecificForRun(ccdbConfig.ccdbPath, mRunNumber, metadata); + } + + if (lCalibObjects) { + LOG(info) << "CCDB objects loaded successfully"; + hVtxZFT0A = static_cast(lCalibObjects->FindObject("hVtxZFT0A")); + hVtxZFT0C = static_cast(lCalibObjects->FindObject("hVtxZFT0C")); + hVtxZNTracks = static_cast(lCalibObjects->FindObject("hVtxZNTracksPV")); + lCalibLoaded = true; + // Capture error + if (!hVtxZFT0A || !hVtxZFT0C || !hVtxZNTracks) { + LOGF(error, "Problem loading CCDB objects! Please check"); + lCalibLoaded = false; + } + } else { + LOGF(error, "Problem loading CCDB object! Please check"); + lCalibLoaded = false; + } + } + auto thisCollId = collision.globalIndex(); std::array nCandsPerType{0}; std::array nCandsInSignalRegionDsPerType{0}; @@ -669,6 +814,7 @@ struct HfTaskDs { void processDataWithCentFT0C(CollisionsWithFT0C const& collisions, CandDsData const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -677,6 +823,7 @@ struct HfTaskDs { void processDataWithCentFT0M(CollisionsWithFT0M const& collisions, CandDsData const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -685,6 +832,7 @@ struct HfTaskDs { void processDataWithCentNTracksPV(CollisionsWithNTracksPV const& collisions, CandDsData const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -693,6 +841,7 @@ struct HfTaskDs { void processData(soa::Join const& collisions, CandDsData const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -701,6 +850,7 @@ struct HfTaskDs { void processDataWithMlAndCentFT0C(CollisionsWithFT0C const& collisions, CandDsDataWithMl const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -709,6 +859,7 @@ struct HfTaskDs { void processDataWithMlAndCentFT0M(CollisionsWithFT0M const& collisions, CandDsDataWithMl const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -717,6 +868,7 @@ struct HfTaskDs { void processDataWithMlAndCentNTracksPV(CollisionsWithNTracksPV const& collisions, CandDsDataWithMl const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -725,6 +877,7 @@ struct HfTaskDs { void processDataWithMl(soa::Join const& collisions, CandDsDataWithMl const& candsDs, + aod::BCs const&, aod::Tracks const&) { runDataAnalysisPerCollision(collisions, candsDs); @@ -734,6 +887,7 @@ struct HfTaskDs { void processMcWithCentFT0C(CollisionsMcWithFT0C const& collisions, CandDsMcReco const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -744,6 +898,7 @@ struct HfTaskDs { void processMcWithCentFT0M(CollisionsMcWithFT0M const& collisions, CandDsMcReco const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -754,6 +909,7 @@ struct HfTaskDs { void processMcWithCentNTracksPV(CollisionsMcWithNTracksPV const& collisions, CandDsMcReco const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -764,6 +920,7 @@ struct HfTaskDs { void processMc(CollisionsMc const& collisions, CandDsMcReco const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -774,6 +931,7 @@ struct HfTaskDs { void processMcWithMlAndCentFT0C(CollisionsMcWithFT0C const& collisions, CandDsMcRecoWithMl const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -784,6 +942,7 @@ struct HfTaskDs { void processMcWithMlAndCentFT0M(CollisionsMcWithFT0M const& collisions, CandDsMcRecoWithMl const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -794,6 +953,7 @@ struct HfTaskDs { void processMcWithMlAndCentNTracksPV(CollisionsMcWithNTracksPV const& collisions, CandDsMcRecoWithMl const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -804,6 +964,7 @@ struct HfTaskDs { void processMcWithMl(CollisionsMc const& collisions, CandDsMcRecoWithMl const& candsDs, CandDsMcGen const& mcParticles, + aod::BCs const&, aod::McCollisions const&, aod::TracksWMc const&) { @@ -814,5 +975,7 @@ struct HfTaskDs { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + // Parse the metadata + metadataInfo.initMetadata(cfgc); return WorkflowSpec{adaptAnalysisTask(cfgc)}; } diff --git a/PWGHF/D2H/Tasks/taskLc.cxx b/PWGHF/D2H/Tasks/taskLc.cxx index 2a5b869b789..2981f64c8c7 100644 --- a/PWGHF/D2H/Tasks/taskLc.cxx +++ b/PWGHF/D2H/Tasks/taskLc.cxx @@ -673,10 +673,9 @@ struct HfTaskLc { for (const auto& collision : collisions) { // MC Rec. fillHistosMcRec(collision, candidates, mcParticles); - // MC gen. - auto mcParticlesPerColl = mcParticles.sliceBy(perMcCollision, collision.globalIndex()); - fillHistosMcGen(mcParticlesPerColl); } + // MC gen. + fillHistosMcGen(mcParticles); } void processDataStd(Collisions const& collisions, diff --git a/PWGHF/D2H/Tasks/taskXicToXiPiPi.cxx b/PWGHF/D2H/Tasks/taskXicToXiPiPi.cxx index a5a14c734cc..726bf86d77d 100644 --- a/PWGHF/D2H/Tasks/taskXicToXiPiPi.cxx +++ b/PWGHF/D2H/Tasks/taskXicToXiPiPi.cxx @@ -15,6 +15,9 @@ /// /// \author Phil Lennart Stahlhut , Heidelberg University /// \author Carolina Reetz , Heidelberg University +/// \author Jaeyoon Cho , Inha University + +#include #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -42,7 +45,17 @@ struct HfTaskXicToXiPiPi { Configurable> binsPt{"binsPt", std::vector{hf_cuts_xic_to_xi_pi_pi::vecBinsPt}, "pT bin limits"}; // MC checks Configurable checkDecayTypeMc{"checkDecayTypeMc", false, "Flag to enable DecayType histogram"}; - + // THnSparese for ML selection check + Configurable enableTHn{"enableTHn", false, "Fill THnSparse for Xic"}; + ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {400, 0., 40.}, ""}; + ConfigurableAxis thnConfigAxisMass{"thnConfigAxisMass", {300, 1.8, 3.0}, ""}; + ConfigurableAxis thnConfigAxisPtProng{"thnConfigAxisPtProng", {300, 0., 30.}, ""}; + ConfigurableAxis thnConfigAxisChi2PCA{"thnConfigAxisChi2PCA", {200, 0., 20}, ""}; + ConfigurableAxis thnConfigAxisDecLength{"thnConfigAxisDecLength", {200, 0., 0.5}, ""}; + ConfigurableAxis thnConfigAxisDecLengthXY{"thnConfigAxisDecLengthXY", {200, 0., 0.5}, ""}; + ConfigurableAxis thnConfigAxisCPA{"thnConfigAxisCPA", {110, -1.1, 1.1}, ""}; + ConfigurableAxis thnConfigAxisBdtScoreBkg{"thnConfigAxisBdtScoreBkg", {100, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisBdtScoreSignal{"thnConfigAxisBdtScoreSignal", {100, 0., 1.}, ""}; // Axis ConfigurableAxis binsDecLength{"binsDecLength", {200, 0., 0.5}, ""}; ConfigurableAxis binsErrDecLength{"binsErrDecLength", {100, 0., 1.}, ""}; @@ -64,20 +77,15 @@ struct HfTaskXicToXiPiPi { void init(InitContext const&) { - if (!doprocessWithKFParticle && !doprocessWithDCAFitter && !doprocessMcWithKFParticle && !doprocessMcWithDCAFitter) { - LOGF(fatal, "No process function enabled. Please enable one."); - } - if (doprocessWithKFParticle && doprocessWithDCAFitter) { - LOGF(fatal, "Cannot enable doprocessWithKFParticle and doprocessWithDCAFitter at the same time. Please choose one."); + std::array doprocess{doprocessWithDCAFitter, doprocessWithKFParticle, doprocessWithDCAFitterAndML, doprocessWithKFParticleAndML, doprocessMcWithDCAFitter, doprocessMcWithKFParticle, doprocessMcWithDCAFitterAndML, doprocessMcWithKFParticleAndML}; + if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) == 0) { + LOGP(fatal, "No process function enabled. Please enable one."); } - if (doprocessMcWithKFParticle && doprocessMcWithDCAFitter) { - LOGF(fatal, "Cannot enable doprocessMcWithKFParticle and doprocessMcWithDCAFitter at the same time. Please choose one."); + if ((doprocessWithDCAFitter || doprocessWithDCAFitterAndML || doprocessMcWithDCAFitter || doprocessMcWithDCAFitterAndML) && (doprocessWithKFParticle || doprocessWithKFParticleAndML || doprocessMcWithKFParticle || doprocessMcWithKFParticleAndML)) { + LOGP(fatal, "Cannot enable DCAFitter and KFParticle at the same time. Please choose one."); } - if (doprocessWithKFParticle && doprocessMcWithDCAFitter) { - LOGF(fatal, "Cannot enable doprocessWithKFParticle and doprocessMcWithDCAFitter at the same time. Please choose one."); - } - if (doprocessWithDCAFitter && doprocessMcWithKFParticle) { - LOGF(fatal, "Cannot enable doprocessWithDCAFitter and doprocessMcWithKFParticle at the same time. Please choose one."); + if ((doprocessWithDCAFitter || doprocessWithKFParticle || doprocessMcWithDCAFitter || doprocessMcWithKFParticle) && (doprocessWithDCAFitterAndML || doprocessWithKFParticleAndML || doprocessMcWithDCAFitterAndML || doprocessMcWithKFParticleAndML)) { + LOGP(fatal, "Cannot enable process function with ML and process function without ML at the same time. Please choose one."); } static const AxisSpec axisMassXic = {300, 1.8, 3.0, "inv. mass (GeV/#it{c}^{2})"}; @@ -120,14 +128,14 @@ struct HfTaskXicToXiPiPi { registry.add("hMassXiPi1", "#Xi^{#plus}_{c} candidates;inv. mass #Xi^{#mp} #pi^{#pm} (prong 1) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisMassXiRes, axisPt}}); registry.add("hMassXiPi2", "#Xi^{#plus}_{c} candidates;inv. mass #Xi^{#mp} #pi^{#pm} (prong 2) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisMassXiRes, axisPt}}); - if (doprocessWithKFParticle) { + if (doprocessWithKFParticle || doprocessWithKFParticleAndML) { registry.add("hChi2geoXi", "#Xi^{#plus}_{c} candidates;#Xi^{#mp} #chi^{2}_{geo};entries", {HistType::kTH2F, {axisChi2, axisPt}}); registry.add("hChi2geoLam", "#Xi^{#plus}_{c} candidates;#Lambda #chi^{2}_{geo};entries", {HistType::kTH2F, {axisChi2, axisPt}}); registry.add("hChi2topoToPV", "#Xi^{#plus}_{c} candidates;#Xi^{#plus}_{c} candidate #chi^{2}_{topo} to PV;entries", {HistType::kTH2F, {axisChi2, axisPt}}); registry.add("hChi2topoXiToXicPlus", "#Xi^{#plus}_{c} candidates;#Xi^{#mp} candidate #chi^{2}_{topo} to #Xi^{#plus}_{c};entries", {HistType::kTH2F, {axisChi2, axisPt}}); } - if (doprocessMcWithKFParticle || doprocessMcWithDCAFitter) { + if (doprocessMcWithKFParticle || doprocessMcWithDCAFitter || doprocessMcWithKFParticleAndML || doprocessMcWithDCAFitterAndML) { // MC reconstructed registry.add("hPtGenSig", "#Xi^{#plus}_{c} candidates (gen+rec);candidate #it{p}_{T}^{gen.} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); registry.add("hPtRecSig", "#Xi^{#plus}_{c} candidates (matched);candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{300, 0., 30.}}}); @@ -191,7 +199,7 @@ struct HfTaskXicToXiPiPi { registry.add("hMassXiPi2RecSig", "#Xi^{#plus}_{c} candidates (matched);inv. mass #Xi^{#mp} #pi^{#pm} (prong 2) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{300, 1.0, 2.0}, axisPt}}); registry.add("hMassXiPi2RecBg", "#Xi^{#plus}_{c} candidates (unmatched);inv. mass #Xi^{#mp} #pi^{#pm} (prong 2) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{300, 1.0, 2.0}, axisPt}}); - if (doprocessMcWithKFParticle) { + if (doprocessMcWithKFParticle || doprocessMcWithDCAFitterAndML) { registry.add("hChi2topoToPVRecSig", "#Xi^{#plus}_{c} candidates (matched);#Xi^{#plus}_{c} candidate #chi^{2}_{topo} to PV;entries", {HistType::kTH2F, {axisChi2, axisPt}}); registry.add("hChi2topoToPVRecBg", "#Xi^{#plus}_{c} candidates (unmatched);#Xi^{#plus}_{c} candidate #chi^{2}_{topo} to PV;entries", {HistType::kTH2F, {axisChi2, axisPt}}); registry.add("hChi2geoXiRecSig", "#Xi^{#plus}_{c} candidates (matched);#Xi^{#mp} #chi^{2}_{geo};entries", {HistType::kTH2F, {axisChi2, axisPt}}); @@ -235,6 +243,50 @@ struct HfTaskXicToXiPiPi { registry.get(HIST("hDecayTypeMc"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin]); } } + + if (enableTHn) { + const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec thnAxisMass{thnConfigAxisMass, "inv. mass #Xi^{#mp} #pi^{#pm} #pi^{#pm}"}; + const AxisSpec thnAxisChi2PCA{thnConfigAxisChi2PCA, "Chi2PCA to sec. vertex (cm)"}; + const AxisSpec thnAxisDecLength{thnConfigAxisDecLength, "decay length (cm)"}; + const AxisSpec thnAxisDecLengthXY{thnConfigAxisDecLengthXY, "decay length xy (cm)"}; + const AxisSpec thnAxisCPA{thnConfigAxisCPA, "#Xi^{#plus}_{c} candidate cosine of pointing angle"}; + const AxisSpec thnAxisBdtScoreBkg{thnConfigAxisBdtScoreBkg, "BDT score of background"}; + const AxisSpec thnAxisBdtScoreSignal{thnConfigAxisBdtScoreSignal, "BDT score of prompt Xic"}; + + if (doprocessWithKFParticleAndML || doprocessWithDCAFitterAndML || doprocessMcWithKFParticleAndML || doprocessMcWithDCAFitterAndML) { + // with ML information + registry.add("hXicToXiPiPiVarsWithML", "THnSparse for Xic with ML", HistType::kTHnSparseF, {thnAxisPt, thnAxisMass, thnAxisChi2PCA, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisBdtScoreBkg, thnAxisBdtScoreSignal}); + } else { + // without ML information + registry.add("hXicToXiPiPiVars", "THnSparse for Xic", HistType::kTHnSparseF, {thnAxisPt, thnAxisMass, thnAxisChi2PCA, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA}); + } + } // enable THnSpare + + } // end init + + /// Fill THnSpare depending on whether ML selection is used + // \param candidate is candidate + template + void fillTHnSparse(const T1& candidate) + { + if (!enableTHn) { + return; + } + + if constexpr (useMl) { + // with ML information + double outputBkg = -99.; + double outputPrompt = -99.; + if (candidate.mlProbXicToXiPiPi().size() > 0) { + outputBkg = candidate.mlProbXicToXiPiPi()[0]; + outputPrompt = candidate.mlProbXicToXiPiPi()[1]; + } + registry.get(HIST("hXicToXiPiPiVarsWithML"))->Fill(candidate.pt(), candidate.invMassXic(), candidate.chi2PCA(), candidate.decayLength(), candidate.decayLengthXY(), candidate.cpa(), outputBkg, outputPrompt); + } else { + // without ML information + registry.get(HIST("hXicToXiPiPiVars"))->Fill(candidate.pt(), candidate.invMassXic(), candidate.chi2PCA(), candidate.decayLength(), candidate.decayLengthXY(), candidate.cpa()); + } } /// Selection of Xic daughter in geometrical acceptance @@ -248,7 +300,7 @@ struct HfTaskXicToXiPiPi { } /// Function to fill histograms - template + template void fillHistograms(TCanTable const& candidates) { for (const auto& candidate : candidates) { @@ -299,11 +351,20 @@ struct HfTaskXicToXiPiPi { registry.fill(HIST("hChi2geoXi"), candidate.kfCascadeChi2(), ptCandXic); registry.fill(HIST("hChi2geoLam"), candidate.kfV0Chi2(), ptCandXic); } + + // fill THnSparse + if (enableTHn) { + if constexpr (useMl) { + fillTHnSparse(candidate); + } else { + fillTHnSparse(candidate); + } + } } // candidate loop } /// Function for MC analysis and histogram filling - template + template void fillHistogramsMc(TCandTable const& candidates, soa::Join const& mcParticles, aod::TracksWMc const&) @@ -413,6 +474,15 @@ struct HfTaskXicToXiPiPi { registry.fill(HIST("hDecayTypeMc"), 1 + hf_cand_xic_to_xi_pi_pi::DecayType::NDecayType, candidate.invMassXic(), ptCandXic); } } + // fill THnSparse + if (enableTHn) { + if constexpr (useMl) { + fillTHnSparse(candidate); + } else { + fillTHnSparse(candidate); + } + } + } // rec // MC gen. level @@ -473,24 +543,38 @@ struct HfTaskXicToXiPiPi { } // gen } + /// Data analysis and fill histograms void processWithDCAFitter(soa::Filtered> const& candidates) { - fillHistograms(candidates); + fillHistograms(candidates); } PROCESS_SWITCH(HfTaskXicToXiPiPi, processWithDCAFitter, "Process data with DCAFitter", true); void processWithKFParticle(soa::Filtered> const& candidates) { - fillHistograms(candidates); + fillHistograms(candidates); } PROCESS_SWITCH(HfTaskXicToXiPiPi, processWithKFParticle, "Process data with KFParticle", false); + /// Data analysis and fill histograms with ML + void processWithDCAFitterAndML(soa::Filtered> const& candidates) + { + fillHistograms(candidates); + } + PROCESS_SWITCH(HfTaskXicToXiPiPi, processWithDCAFitterAndML, "Process data with DCAFitter and ML approach", false); + + void processWithKFParticleAndML(soa::Filtered> const& candidates) + { + fillHistograms(candidates); + } + PROCESS_SWITCH(HfTaskXicToXiPiPi, processWithKFParticleAndML, "Process data with KFParticle and ML approach", false); + /// MC analysis and fill histograms void processMcWithDCAFitter(soa::Filtered> const& candidates, soa::Join const& mcParticles, aod::TracksWMc const& tracksWMc) { - fillHistogramsMc(candidates, mcParticles, tracksWMc); + fillHistogramsMc(candidates, mcParticles, tracksWMc); } PROCESS_SWITCH(HfTaskXicToXiPiPi, processMcWithDCAFitter, "Process MC with DCAFitter", false); @@ -499,9 +583,27 @@ struct HfTaskXicToXiPiPi { soa::Join const& mcParticles, aod::TracksWMc const& tracksWMc) { - fillHistogramsMc(candidates, mcParticles, tracksWMc); + fillHistogramsMc(candidates, mcParticles, tracksWMc); } PROCESS_SWITCH(HfTaskXicToXiPiPi, processMcWithKFParticle, "Process MC with KFParticle", false); + + // MC analysis and fill histograms with ML + void processMcWithDCAFitterAndML(soa::Filtered> const& candidates, + soa::Join const& mcParticles, + aod::TracksWMc const& tracksWMc) + { + fillHistogramsMc(candidates, mcParticles, tracksWMc); + } + PROCESS_SWITCH(HfTaskXicToXiPiPi, processMcWithDCAFitterAndML, "Process MC with DCAFitter and ML approach", false); + + void processMcWithKFParticleAndML(soa::Filtered> const& candidates, + soa::Join const& mcParticles, + aod::TracksWMc const& tracksWMc) + { + fillHistogramsMc(candidates, mcParticles, tracksWMc); + } + PROCESS_SWITCH(HfTaskXicToXiPiPi, processMcWithKFParticleAndML, "Process MC with KFParticle and ML approach", false); + }; // struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index 071ad7c0431..583c30a5de2 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -308,6 +308,7 @@ DECLARE_SOA_COLUMN(MlProbXicToPKPi, mlProbXicToPKPi, std::vector); //! DECLARE_SOA_COLUMN(MlProbXicToPiKP, mlProbXicToPiKP, std::vector); //! // XicPlus to Xi Pi Pi DECLARE_SOA_COLUMN(IsSelXicToXiPiPi, isSelXicToXiPiPi, int); //! +DECLARE_SOA_COLUMN(MlProbXicToXiPiPi, mlProbXicToXiPiPi, std::vector); //! } // namespace hf_sel_candidate_xic DECLARE_SOA_TABLE(HfSelXicToPKPi, "AOD", "HFSELXIC", //! @@ -317,6 +318,8 @@ DECLARE_SOA_TABLE(HfMlXicToPKPi, "AOD", "HFMLXIC", //! // XicPlus to Xi Pi Pi DECLARE_SOA_TABLE(HfSelXicToXiPiPi, "AOD", "HFSELXICTOXI2PI", //! hf_sel_candidate_xic::IsSelXicToXiPiPi); +DECLARE_SOA_TABLE(HfMlXicToXiPiPi, "AOD", "HFMLXICTOXI2PI", //! + hf_sel_candidate_xic::MlProbXicToXiPiPi); namespace hf_sel_candidate_xicc { diff --git a/PWGHF/DataModel/DerivedTables.h b/PWGHF/DataModel/DerivedTables.h index 62c7a9cd15c..88f570b47c0 100644 --- a/PWGHF/DataModel/DerivedTables.h +++ b/PWGHF/DataModel/DerivedTables.h @@ -28,8 +28,20 @@ namespace o2::aod { -constexpr uint MarkerD0 = 10; -constexpr uint Marker3P = 20; +// basic species: +// D0 -> K- + pi+ (done) +// Lc -> pi+ K- p (existing 3P table to be renamed Lc) +// D+ -> K- + pi+ + pi+ (3P table with adapted PID columns) +// Ds+ -> K- + K+ + pi+ (3P table with adapted PID columns) +// composite species +// B0 -> D- + pi+ +// B+ -> D0 + pi+ (in progress) +// D*+ -> D0 + pi+ +constexpr uint MarkerBase = 2; +constexpr uint MarkerD0 = 3; +constexpr uint Marker3P = 4; +constexpr uint MarkerBplus = 5; +constexpr uint MarkerB0 = 6; // ================ // Collision tables @@ -38,17 +50,40 @@ constexpr uint Marker3P = 20; // Basic collision properties namespace hf_coll_base { -DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int8_t); //! collision rejection flag -DECLARE_SOA_COLUMN(MultFT0M, multFT0M, float); //! FT0M multiplicity -DECLARE_SOA_COLUMN(CentFT0A, centFT0A, float); //! FT0A centrality percentile -DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); //! FT0C centrality percentile -DECLARE_SOA_COLUMN(CentFT0M, centFT0M, float); //! FT0M centrality percentile -DECLARE_SOA_COLUMN(CentFV0A, centFV0A, float); //! FT0A centrality percentile -DECLARE_SOA_COLUMN(CentFDDM, centFDDM, float); //! FDDM centrality percentile +DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int8_t); //! collision rejection flag +DECLARE_SOA_COLUMN(MultFT0M, multFT0M, float); //! FT0M multiplicity +DECLARE_SOA_COLUMN(CentFT0A, centFT0A, float); //! FT0A centrality percentile +DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); //! FT0C centrality percentile +DECLARE_SOA_COLUMN(CentFT0M, centFT0M, float); //! FT0M centrality percentile +DECLARE_SOA_COLUMN(CentFV0A, centFV0A, float); //! FV0A centrality percentile +DECLARE_SOA_COLUMN(CentFDDM, centFDDM, float); //! FDDM centrality percentile DECLARE_SOA_COLUMN(MultZeqNTracksPV, multZeqNTracksPV, float); //! z-equalised barrel multiplicity } // namespace hf_coll_base -// D0 +// base + +DECLARE_SOA_TABLE_STAGED(HfCollBases, "HFCOLLBASE", //! Table with basic collision info + o2::soa::Index<>, + collision::PosX, + collision::PosY, + collision::PosZ, + collision::NumContrib, + hf_coll_base::CentFT0A, + hf_coll_base::CentFT0C, + hf_coll_base::CentFT0M, + hf_coll_base::CentFV0A, + hf_coll_base::MultZeqNTracksPV, + // hf_coll_base::IsEventReject, + // bc::RunNumber, + o2::soa::Marker); + +using HfCollBase = HfCollBases::iterator; + +DECLARE_SOA_TABLE_STAGED(HfCollIds, "HFCOLLID", //! Table with original global indices of collisions + hf_cand::CollisionId, + o2::soa::Marker); + +// D0 (to be replaced by base version) DECLARE_SOA_TABLE_STAGED(HfD0CollBases, "HFD0COLLBASE", //! Table with basic collision info o2::soa::Index<>, @@ -62,16 +97,17 @@ DECLARE_SOA_TABLE_STAGED(HfD0CollBases, "HFD0COLLBASE", //! Table with basic col hf_coll_base::CentFV0A, hf_coll_base::MultZeqNTracksPV, // hf_coll_base::IsEventReject, - // bc::RunNumber); - soa::Marker); + // bc::RunNumber, + o2::soa::Marker); using HfD0CollBase = HfD0CollBases::iterator; using StoredHfD0CollBase = StoredHfD0CollBases::iterator; DECLARE_SOA_TABLE_STAGED(HfD0CollIds, "HFD0COLLID", //! Table with original global indices of collisions - hf_cand::CollisionId); + hf_cand::CollisionId, + o2::soa::Marker); -// 3-prong decays +// 3-prong decays (to be replaced by base version) DECLARE_SOA_TABLE_STAGED(Hf3PCollBases, "HF3PCOLLBASE", //! Table with basic collision info o2::soa::Index<>, @@ -93,7 +129,7 @@ using StoredHf3PCollBase = StoredHf3PCollBases::iterator; DECLARE_SOA_TABLE_STAGED(Hf3PCollIds, "HF3PCOLLID", //! Table with original global indices of collisions hf_cand::CollisionId, - soa::Marker); + o2::soa::Marker); // =================== // MC collision tables @@ -102,7 +138,8 @@ DECLARE_SOA_TABLE_STAGED(Hf3PCollIds, "HF3PCOLLID", //! Table with original glob // MC collision columns namespace hf_mc_coll { -DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); //! original global index of the MC collision +DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); //! original global index of the MC collision +DECLARE_SOA_ARRAY_INDEX_COLUMN(HfCollBase, hfCollBases); //! collision index array pointing to the derived reconstructed collisions for D0 candidates namespace der_d0 { DECLARE_SOA_ARRAY_INDEX_COLUMN(HfD0CollBase, hfCollBases); //! collision index array pointing to the derived reconstructed collisions for D0 candidates @@ -113,21 +150,39 @@ DECLARE_SOA_ARRAY_INDEX_COLUMN(Hf3PCollBase, hfCollBases); //! collision index a } } // namespace hf_mc_coll -// DO +// base + +DECLARE_SOA_TABLE_STAGED(HfMcCollBases, "HFMCCOLLBASE", //! Table with basic MC collision info + o2::soa::Index<>, + mccollision::PosX, + mccollision::PosY, + mccollision::PosZ, + o2::soa::Marker); + +using HfMcCollBase = HfMcCollBases::iterator; + +DECLARE_SOA_TABLE_STAGED(HfMcCollIds, "HFMCCOLLID", //! Table with original global indices of MC collisions + hf_mc_coll::McCollisionId, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfMcRCollIds, "HFMCRCOLLID", //! Table with indices pointing to the derived reconstructed-collision table + hf_mc_coll::HfCollBaseIds); + +// D0 DECLARE_SOA_TABLE_STAGED(HfD0McCollBases, "HFD0MCCOLLBASE", //! Table with basic MC collision info o2::soa::Index<>, mccollision::PosX, mccollision::PosY, mccollision::PosZ, - soa::Marker); + o2::soa::Marker); using HfD0McCollBase = HfD0McCollBases::iterator; using StoredHfD0McCollBase = StoredHfD0McCollBases::iterator; DECLARE_SOA_TABLE_STAGED(HfD0McCollIds, "HFD0MCCOLLID", //! Table with original global indices of MC collisions hf_mc_coll::McCollisionId, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0McRCollIds, "HFD0MCRCOLLID", //! Table with indices pointing to the derived reconstructed-collision table hf_mc_coll::der_d0::HfD0CollBaseIds); @@ -139,14 +194,14 @@ DECLARE_SOA_TABLE_STAGED(Hf3PMcCollBases, "HF3PMCCOLLBASE", //! Table with basic mccollision::PosX, mccollision::PosY, mccollision::PosZ, - soa::Marker); + o2::soa::Marker); using Hf3PMcCollBase = Hf3PMcCollBases::iterator; using StoredHf3PMcCollBase = StoredHf3PMcCollBases::iterator; DECLARE_SOA_TABLE_STAGED(Hf3PMcCollIds, "HF3PMCCOLLID", //! Table with original global indices of MC collisions hf_mc_coll::McCollisionId, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PMcRCollIds, "HF3PMCRCOLLID", //! Table with indices pointing to the derived reconstructed-collision table hf_mc_coll::der_3p::Hf3PCollBaseIds); @@ -162,6 +217,10 @@ namespace der_d0 { DECLARE_SOA_INDEX_COLUMN(HfD0CollBase, hfCollBase); //! collision index pointing to the derived collision table for D0 candidates } +namespace der_bplus +{ +DECLARE_SOA_INDEX_COLUMN(HfCollBase, hfCollBase); //! collision index pointing to the derived collision table for B+ candidates +} namespace der_3p { DECLARE_SOA_INDEX_COLUMN(Hf3PCollBase, hfCollBase); //! collision index pointing to the derived collision table for 3-prong candidates @@ -248,6 +307,77 @@ DECLARE_SOA_COLUMN(NSigTpcTofPr1, nSigTpcTofPr1, float); DECLARE_SOA_COLUMN(NSigTpcTofPr2, nSigTpcTofPr2, float); } // namespace hf_cand_par +// Candidate properties of the charm daughter candidate used for selection of the beauty candidate +// Copy of hf_cand_par with "Charm" suffix to make it joinable with the beauty candidate table. +// We don't want to link the charm candidate table because we want to avoid producing it. +namespace hf_cand_par_charm +{ +DECLARE_SOA_COLUMN(CosThetaStarCharm, cosThetaStarCharm, float); //! cosine of theta star +DECLARE_SOA_COLUMN(CpaCharm, cpaCharm, float); //! cosine of pointing angle +DECLARE_SOA_COLUMN(CpaXYCharm, cpaXYCharm, float); //! cosine of pointing angle in the transverse plane +DECLARE_SOA_COLUMN(CtCharm, ctCharm, float); //! proper lifetime times c +DECLARE_SOA_COLUMN(DecayLengthCharm, decayLengthCharm, float); //! decay length +DECLARE_SOA_COLUMN(DecayLengthNormalisedCharm, decayLengthNormalisedCharm, float); //! decay length divided by its uncertainty +DECLARE_SOA_COLUMN(DecayLengthXYCharm, decayLengthXYCharm, float); //! decay length in the transverse plane +DECLARE_SOA_COLUMN(DecayLengthXYNormalisedCharm, decayLengthXYNormalisedCharm, float); //! decay length in the transverse plane divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameter0Charm, impactParameter0Charm, float); //! impact parameter of prong 0 +DECLARE_SOA_COLUMN(ImpactParameter1Charm, impactParameter1Charm, float); //! impact parameter of prong 1 +DECLARE_SOA_COLUMN(ImpactParameterNormalised0Charm, impactParameterNormalised0Charm, float); //! impact parameter of prong 0 divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterNormalised1Charm, impactParameterNormalised1Charm, float); //! impact parameter of prong 1 divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterNormalised2Charm, impactParameterNormalised2Charm, float); //! impact parameter of prong 2 divided by its uncertainty +DECLARE_SOA_COLUMN(ImpactParameterProductCharm, impactParameterProductCharm, float); //! product of impact parameters of prong 0 and prong 1 +DECLARE_SOA_COLUMN(MaxNormalisedDeltaIPCharm, maxNormalisedDeltaIPCharm, float); //! see RecoDecay::maxNormalisedDeltaIP +DECLARE_SOA_COLUMN(PProng0Charm, pProng0Charm, float); //! momentum magnitude of prong 0 +DECLARE_SOA_COLUMN(PProng1Charm, pProng1Charm, float); //! momentum magnitude of prong 1 +DECLARE_SOA_COLUMN(PProng2Charm, pProng2Charm, float); //! momentum magnitude of prong 2 +DECLARE_SOA_COLUMN(PtProng0Charm, ptProng0Charm, float); //! transverse momentum of prong 0 +DECLARE_SOA_COLUMN(PtProng1Charm, ptProng1Charm, float); //! transverse momentum of prong 1 +DECLARE_SOA_COLUMN(PtProng2Charm, ptProng2Charm, float); //! transverse momentum of prong 2 +DECLARE_SOA_COLUMN(RSecondaryVertexCharm, rSecondaryVertexCharm, float); //! distance of the secondary vertex from the z axis +// TOF +DECLARE_SOA_COLUMN(NSigTofKa0Charm, nSigTofKa0Charm, float); +DECLARE_SOA_COLUMN(NSigTofKa1Charm, nSigTofKa1Charm, float); +DECLARE_SOA_COLUMN(NSigTofKa2Charm, nSigTofKa2Charm, float); +DECLARE_SOA_COLUMN(NSigTofKaExpPiCharm, nSigTofKaExpPiCharm, float); +DECLARE_SOA_COLUMN(NSigTofKaExpKaCharm, nSigTofKaExpKaCharm, float); +DECLARE_SOA_COLUMN(NSigTofPi0Charm, nSigTofPi0Charm, float); +DECLARE_SOA_COLUMN(NSigTofPi1Charm, nSigTofPi1Charm, float); +DECLARE_SOA_COLUMN(NSigTofPi2Charm, nSigTofPi2Charm, float); +DECLARE_SOA_COLUMN(NSigTofPiExpPiCharm, nSigTofPiExpPiCharm, float); +DECLARE_SOA_COLUMN(NSigTofPiExpKaCharm, nSigTofPiExpKaCharm, float); +DECLARE_SOA_COLUMN(NSigTofPr0Charm, nSigTofPr0Charm, float); +DECLARE_SOA_COLUMN(NSigTofPr1Charm, nSigTofPr1Charm, float); +DECLARE_SOA_COLUMN(NSigTofPr2Charm, nSigTofPr2Charm, float); +// TPC +DECLARE_SOA_COLUMN(NSigTpcKa0Charm, nSigTpcKa0Charm, float); +DECLARE_SOA_COLUMN(NSigTpcKa1Charm, nSigTpcKa1Charm, float); +DECLARE_SOA_COLUMN(NSigTpcKa2Charm, nSigTpcKa2Charm, float); +DECLARE_SOA_COLUMN(NSigTpcKaExpPiCharm, nSigTpcKaExpPiCharm, float); +DECLARE_SOA_COLUMN(NSigTpcKaExpKaCharm, nSigTpcKaExpKaCharm, float); +DECLARE_SOA_COLUMN(NSigTpcPi0Charm, nSigTpcPi0Charm, float); +DECLARE_SOA_COLUMN(NSigTpcPi1Charm, nSigTpcPi1Charm, float); +DECLARE_SOA_COLUMN(NSigTpcPi2Charm, nSigTpcPi2Charm, float); +DECLARE_SOA_COLUMN(NSigTpcPiExpPiCharm, nSigTpcPiExpPiCharm, float); +DECLARE_SOA_COLUMN(NSigTpcPiExpKaCharm, nSigTpcPiExpKaCharm, float); +DECLARE_SOA_COLUMN(NSigTpcPr0Charm, nSigTpcPr0Charm, float); +DECLARE_SOA_COLUMN(NSigTpcPr1Charm, nSigTpcPr1Charm, float); +DECLARE_SOA_COLUMN(NSigTpcPr2Charm, nSigTpcPr2Charm, float); +// TPC+TOF +DECLARE_SOA_COLUMN(NSigTpcTofKa0Charm, nSigTpcTofKa0Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofKa1Charm, nSigTpcTofKa1Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofKa2Charm, nSigTpcTofKa2Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofKaExpPiCharm, nSigTpcTofKaExpPiCharm, float); +DECLARE_SOA_COLUMN(NSigTpcTofKaExpKaCharm, nSigTpcTofKaExpKaCharm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi0Charm, nSigTpcTofPi0Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi1Charm, nSigTpcTofPi1Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi2Charm, nSigTpcTofPi2Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPiExpPiCharm, nSigTpcTofPiExpPiCharm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPiExpKaCharm, nSigTpcTofPiExpKaCharm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr0Charm, nSigTpcTofPr0Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr1Charm, nSigTpcTofPr1Charm, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr2Charm, nSigTpcTofPr2Charm, float); +} // namespace hf_cand_par_charm + // Candidate selection flags namespace hf_cand_sel { @@ -261,12 +391,27 @@ DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! flag for DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); //! particle origin, reconstruction level DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int8_t); //! swapping of the prongs order DECLARE_SOA_COLUMN(FlagMcDecayChanRec, flagMcDecayChanRec, int8_t); //! resonant decay channel flag, reconstruction level +DECLARE_SOA_COLUMN(MlScoreSig, mlScoreSig, float); //! ML score for signal class DECLARE_SOA_COLUMN(MlScoreBkg, mlScoreBkg, float); //! ML score for background class DECLARE_SOA_COLUMN(MlScorePrompt, mlScorePrompt, float); //! ML score for prompt class DECLARE_SOA_COLUMN(MlScoreNonPrompt, mlScoreNonPrompt, float); //! ML score for non-prompt class DECLARE_SOA_COLUMN(MlScores, mlScores, std::vector); //! vector of ML scores } // namespace hf_cand_mc +// Candidate MC columns of the charm daughter +namespace hf_cand_mc_charm +{ +DECLARE_SOA_COLUMN(FlagMcMatchRecCharm, flagMcMatchRecCharm, int8_t); //! flag for reconstruction level matching +DECLARE_SOA_COLUMN(OriginMcRecCharm, originMcRecCharm, int8_t); //! particle origin, reconstruction level +DECLARE_SOA_COLUMN(IsCandidateSwappedCharm, isCandidateSwappedCharm, int8_t); //! swapping of the prongs order +DECLARE_SOA_COLUMN(FlagMcDecayChanRecCharm, flagMcDecayChanRecCharm, int8_t); //! resonant decay channel flag, reconstruction level +DECLARE_SOA_COLUMN(MlScoreSigCharm, mlScoreSigCharm, float); //! ML score for signal class +DECLARE_SOA_COLUMN(MlScoreBkgCharm, mlScoreBkgCharm, float); //! ML score for background class +DECLARE_SOA_COLUMN(MlScorePromptCharm, mlScorePromptCharm, float); //! ML score for prompt class +DECLARE_SOA_COLUMN(MlScoreNonPromptCharm, mlScoreNonPromptCharm, float); //! ML score for non-prompt class +DECLARE_SOA_COLUMN(MlScoresCharm, mlScoresCharm, std::vector); //! vector of ML scores +} // namespace hf_cand_mc_charm + // D0 DECLARE_SOA_TABLE_STAGED(HfD0Bases, "HFD0BASE", //! Table with basic candidate properties used in the analyses @@ -281,7 +426,7 @@ DECLARE_SOA_TABLE_STAGED(HfD0Bases, "HFD0BASE", //! Table with basic candidate p hf_cand_base::Py, hf_cand_base::Pz, hf_cand_base::P, - soa::Marker); + o2::soa::Marker); // candidates for removal: // PxProng0, PyProng0, PzProng0,... (same for 1, 2), we can keep Pt, Eta, Phi instead @@ -315,7 +460,7 @@ DECLARE_SOA_TABLE_STAGED(HfD0Pars, "HFD0PAR", //! Table with candidate propertie hf_cand_par::NSigTpcTofKaExpKa, hf_cand_par::MaxNormalisedDeltaIP, hf_cand_par::ImpactParameterProduct, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0ParEs, "HFD0PARE", //! Table with additional candidate properties used for selection hf_cand::XSecondaryVertex, @@ -337,26 +482,125 @@ DECLARE_SOA_TABLE_STAGED(HfD0ParEs, "HFD0PARE", //! Table with additional candid hf_cand::ErrorImpactParameter1, hf_cand_par::CosThetaStar, hf_cand_par::Ct, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0Sels, "HFD0SEL", //! Table with candidate selection flags hf_cand_sel::CandidateSelFlag, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0Mls, "HFD0ML", //! Table with candidate selection ML scores hf_cand_mc::MlScores, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0Ids, "HFD0ID", //! Table with original global indices for candidates hf_cand::CollisionId, hf_track_index::Prong0Id, hf_track_index::Prong1Id, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0Mcs, "HFD0MC", //! Table with MC candidate info hf_cand_mc::FlagMcMatchRec, hf_cand_mc::OriginMcRec, - soa::Marker); + o2::soa::Marker); + +// B+ + +DECLARE_SOA_TABLE_STAGED(HfBplusBases, "HFBPBASE", //! Table with basic candidate properties used in the analyses + o2::soa::Index<>, + hf_cand_base::der_bplus::HfCollBaseId, + 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, + o2::soa::Marker); + +// 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_STAGED(HfBplusPars, "HFBPPAR", //! Table with candidate properties used for selection + hf_cand::Chi2PCA, + hf_cand_par::Cpa, + hf_cand_par::CpaXY, + hf_cand_par::DecayLength, + hf_cand_par::DecayLengthXY, + hf_cand_par::DecayLengthNormalised, + hf_cand_par::DecayLengthXYNormalised, + hf_cand_par::PtProng0, + hf_cand_par::PtProng1, + hf_cand::ImpactParameter0, + hf_cand::ImpactParameter1, + hf_cand_par::ImpactParameterNormalised0, + hf_cand_par::ImpactParameterNormalised1, + hf_cand_par::NSigTpcPiExpPi, + hf_cand_par::NSigTofPiExpPi, + hf_cand_par::NSigTpcTofPiExpPi, + hf_cand_par::NSigTpcKaExpPi, + hf_cand_par::NSigTofKaExpPi, + hf_cand_par::NSigTpcTofKaExpPi, + hf_cand_par::MaxNormalisedDeltaIP, + hf_cand_par::ImpactParameterProduct, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfBplusParD0s, "HFBPPARD0", //! Table with D0 candidate properties used for selection of B+ + hf_cand_par_charm::CpaCharm, + hf_cand_par_charm::DecayLengthCharm, + hf_cand_par_charm::ImpactParameter0Charm, + hf_cand_par_charm::ImpactParameter1Charm, + hf_cand_par_charm::ImpactParameterProductCharm, + hf_cand_par_charm::NSigTpcPiExpPiCharm, + hf_cand_par_charm::NSigTofPiExpPiCharm, + hf_cand_par_charm::NSigTpcTofPiExpPiCharm, + hf_cand_par_charm::NSigTpcKaExpPiCharm, + hf_cand_par_charm::NSigTofKaExpPiCharm, + hf_cand_par_charm::NSigTpcTofKaExpPiCharm, + hf_cand_par_charm::NSigTpcPiExpKaCharm, + hf_cand_par_charm::NSigTofPiExpKaCharm, + hf_cand_par_charm::NSigTpcTofPiExpKaCharm, + hf_cand_par_charm::NSigTpcKaExpKaCharm, + hf_cand_par_charm::NSigTofKaExpKaCharm, + hf_cand_par_charm::NSigTpcTofKaExpKaCharm); + +DECLARE_SOA_TABLE_STAGED(HfBplusParEs, "HFBPPARE", //! Table with additional candidate properties used for selection + hf_cand::XSecondaryVertex, + hf_cand::YSecondaryVertex, + hf_cand::ZSecondaryVertex, + hf_cand::ErrorDecayLength, + hf_cand::ErrorDecayLengthXY, + hf_cand_par::RSecondaryVertex, + hf_cand_par::PProng1, + hf_cand::PxProng1, + hf_cand::PyProng1, + hf_cand::PzProng1, + hf_cand::ErrorImpactParameter1, + hf_cand_par::CosThetaStar, + hf_cand_par::Ct, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfBplusMls, "HFBPML", //! Table with candidate selection ML scores + hf_cand_mc::MlScoreSig, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfBplusMlD0s, "HFBPMLD0", //! Table with D0 candidate selection ML scores + hf_cand_mc_charm::MlScoresCharm, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfBplusIds, "HFBPID", //! Table with original global indices for candidates + hf_cand::CollisionId, + hf_track_index::Prong0Id, // D0 prong 0 + hf_track_index::Prong1Id, // D0 prong 1 + hf_track_index::Prong2Id, // bachelor pion + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfBplusMcs, "HFBPMC", //! Table with MC candidate info + hf_cand_mc::FlagMcMatchRec, + hf_cand_mc::OriginMcRec, + o2::soa::Marker); // 3-prong decays @@ -372,7 +616,7 @@ DECLARE_SOA_TABLE_STAGED(Hf3PBases, "HF3PBASE", //! Table with basic candidate p hf_cand_base::Py, hf_cand_base::Pz, hf_cand_base::P, - soa::Marker); + o2::soa::Marker); // candidates for removal: // PxProng0, PyProng0, PzProng0,... (same for 1, 2), we can keep Pt, Eta, Phi instead @@ -411,7 +655,7 @@ DECLARE_SOA_TABLE_STAGED(Hf3PPars, "HF3PPAR", //! Table with candidate propertie hf_cand_par::NSigTofPr2, hf_cand_par::NSigTpcTofPi2, hf_cand_par::NSigTpcTofPr2, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PParEs, "HF3PPARE", //! Table with additional candidate properties used for selection hf_cand::XSecondaryVertex, @@ -436,28 +680,28 @@ DECLARE_SOA_TABLE_STAGED(Hf3PParEs, "HF3PPARE", //! Table with additional candid hf_cand::ErrorImpactParameter1, hf_cand::ErrorImpactParameter2, hf_cand_par::Ct, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PSels, "HF3PSEL", //! Table with candidate selection flags hf_cand_sel::CandidateSelFlag, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PMls, "HF3PML", //! Table with candidate selection ML scores hf_cand_mc::MlScores, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PIds, "HF3PID", //! Table with original global indices for candidates hf_cand::CollisionId, hf_track_index::Prong0Id, hf_track_index::Prong1Id, hf_track_index::Prong2Id, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PMcs, "HF3PMC", //! Table with MC candidate info hf_cand_mc::FlagMcMatchRec, hf_cand_mc::OriginMcRec, hf_cand_mc::IsCandidateSwapped, - soa::Marker); + o2::soa::Marker); // ================== // MC particle tables @@ -466,12 +710,16 @@ DECLARE_SOA_TABLE_STAGED(Hf3PMcs, "HF3PMC", //! Table with MC candidate info // MC particle columns namespace hf_mc_particle { -DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); //! MC collision of this particle -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle +DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); //! MC collision of this particle +DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle namespace der_d0 { DECLARE_SOA_INDEX_COLUMN(HfD0McCollBase, hfMcCollBase); //! collision index pointing to the derived MC collision table for D0 candidates } +namespace der_bplus +{ +DECLARE_SOA_INDEX_COLUMN(HfMcCollBase, hfMcCollBase); //! collision index pointing to the derived MC collision table for B+ candidates +} namespace der_3p { DECLARE_SOA_INDEX_COLUMN(Hf3PMcCollBase, hfMcCollBase); //! collision index pointing to the derived MC collision table for 3-prong candidates @@ -496,12 +744,34 @@ DECLARE_SOA_TABLE_STAGED(HfD0PBases, "HFD0PBASE", //! Table with MC particle inf hf_cand_base::Py, hf_cand_base::Pz, hf_cand_base::P, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(HfD0PIds, "HFD0PID", //! Table with original global indices for MC particles hf_mc_particle::McCollisionId, hf_mc_particle::McParticleId, - soa::Marker); + o2::soa::Marker); + +// B+ + +DECLARE_SOA_TABLE_STAGED(HfBplusPBases, "HFBPPBASE", //! Table with MC particle info + o2::soa::Index<>, + hf_mc_particle::der_bplus::HfMcCollBaseId, + hf_cand_base::Pt, + hf_cand_base::Eta, + hf_cand_base::Phi, + hf_cand_base::Y, + hf_mc_particle::FlagMcMatchGen, + hf_mc_particle::OriginMcGen, + hf_cand_base::Px, + hf_cand_base::Py, + hf_cand_base::Pz, + hf_cand_base::P, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(HfBplusPIds, "HFBPPID", //! Table with original global indices for MC particles + hf_mc_particle::McCollisionId, + hf_mc_particle::McParticleId, + o2::soa::Marker); // 3-prong decays @@ -518,12 +788,12 @@ DECLARE_SOA_TABLE_STAGED(Hf3PPBases, "HF3PPBASE", //! Table with MC particle inf hf_cand_base::Py, hf_cand_base::Pz, hf_cand_base::P, - soa::Marker); + o2::soa::Marker); DECLARE_SOA_TABLE_STAGED(Hf3PPIds, "HF3PPID", //! Table with original global indices for MC particles hf_mc_particle::McCollisionId, hf_mc_particle::McParticleId, - soa::Marker); + o2::soa::Marker); } // namespace o2::aod #endif // PWGHF_DATAMODEL_DERIVEDTABLES_H_ diff --git a/PWGHF/HFC/Macros/DhCorrelationFitter.cxx b/PWGHF/HFC/Macros/DhCorrelationFitter.cxx index d203c6ee63f..7e5157bb752 100644 --- a/PWGHF/HFC/Macros/DhCorrelationFitter.cxx +++ b/PWGHF/HFC/Macros/DhCorrelationFitter.cxx @@ -14,6 +14,12 @@ /// \author Samuele Cattaruzzi /// \author Swapnesh Santosh Khade +#include "DhCorrelationFitter.h" + +#include +#include +#include + #include #include #include @@ -34,10 +40,10 @@ #include #include #include -#include #include #include -#include "DhCorrelationFitter.h" + +using namespace std; DhCorrelationFitter::DhCorrelationFitter() : // default constructor fIsReflected(kFALSE), diff --git a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx index 3d8bf16dd31..9ec7e5fc7c2 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx @@ -180,7 +180,7 @@ struct HfCorrelatorD0Hadrons { Configurable applyEfficiency{"efficiencyFlagD", 1, "Flag for applying D-meson efficiency weights"}; Configurable multMin{"multMin", 0., "minimum multiplicity accepted"}; Configurable multMax{"multMax", 10000., "maximum multiplicity accepted"}; - Configurable ptSoftPionMax{"ptSoftPionMax", 3 * 800. * pow(10., -6.), "max. pT cut for soft pion identification"}; + Configurable ptSoftPionMax{"ptSoftPionMax", 3.f * 800.f * std::pow(10.f, -6.f), "max. pT cut for soft pion identification"}; Configurable correlateD0WithLeadingParticle{"correlateD0WithLeadingParticle", false, "Switch for correlation of D0 mesons with leading particle only"}; Configurable storeAutoCorrelationFlag{"storeAutoCorrelationFlag", false, "Store flag that indicates if the track is paired to its D-meson mother instead of skipping it"}; Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; @@ -281,7 +281,7 @@ struct HfCorrelatorD0Hadrons { } // find leading particle if (correlateD0WithLeadingParticle) { - leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value); + leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value, etaTrackMax.value); } int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFT0M())); @@ -425,7 +425,7 @@ struct HfCorrelatorD0Hadrons { } // find leading particle if (correlateD0WithLeadingParticle) { - leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value); + leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value, etaTrackMax.value); } int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFT0M())); int nTracks = 0; diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx index 0ba872d67d5..45ad4877388 100644 --- a/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairs.cxx @@ -14,6 +14,9 @@ /// /// \author Andrea Tavira García , IJCLab Orsay +#include +#include + #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" @@ -79,9 +82,10 @@ struct HfCorrelatorDMesonPairs { HistogramConfigSpec hTH1Pt{HistType::kTH1F, {{180, 0., 36.}}}; HistogramConfigSpec hTH1Y{HistType::kTH1F, {{100, -5., 5.}}}; + HistogramConfigSpec hTH1NContrib{HistType::kTH1F, {{120, -0.5, 119.5}}}; HistogramConfigSpec hTH1Phi{HistType::kTH1F, {{32, 0., o2::constants::math::TwoPI}}}; HistogramConfigSpec hTH2Pid{HistType::kTH2F, {{500, 0., 10.}, {400, -20., 20.}}}; - HistogramConfigSpec hTH2PtVsY{HistType::kTH2F, {{360, 0., 36.}, {20, -1., 1.}}}; + HistogramConfigSpec hTH3PtVsYVsNContrib{HistType::kTH3F, {{360, 0., 36.}, {20, -1., 1.}, {120, -0.5, 119.5}}}; HistogramRegistry registry{ "registry", @@ -97,9 +101,11 @@ struct HfCorrelatorDMesonPairs { {"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}, - {"hPtVsYMcGen", "D meson candidates MC Gen;candidate #it{p}_{T} (GeV/#it{c});#it{y}", hTH2PtVsY}, + {"hPtVsYVsNContribMcGen", "D meson candidates MC Gen;candidate #it{p}_{T} (GeV/#it{c});#it{y};Number of contributors", hTH3PtVsYVsNContrib}, + {"hNContribMcGen", "D meson candidates MC Gen;Number of contributors", hTH1NContrib}, // MC Rec plots - {"hPtVsYMcRec", "D meson candidates MC Rec;candidate #it{p}_{T} (GeV/#it{c});#it{y}", hTH2PtVsY}, + {"hPtVsYVsNContribMcRec", "D meson candidates MC Rec;candidate #it{p}_{T} (GeV/#it{c});#it{y};Number of contributors", hTH3PtVsYVsNContrib}, + {"hNContribMcRec", "D meson candidates MC Rec;Number of contributors", hTH1NContrib}, // 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}, @@ -559,7 +565,8 @@ struct HfCorrelatorDMesonPairs { if (isDCand1) { if (isTrueDCand1) { registry.fill(HIST("hMass"), hfHelper.invMassD0ToPiK(candidate1), candidate1.pt()); - registry.fill(HIST("hPtVsYMcRec"), candidate1.pt(), hfHelper.yD0(candidate1)); + registry.fill(HIST("hPtVsYVsNContribMcRec"), candidate1.pt(), hfHelper.yD0(candidate1), collision.numContrib()); + registry.fill(HIST("hNContribMcRec"), collision.numContrib()); if (originRec1 == 1) { registry.fill(HIST("hMassMcRecPrompt"), hfHelper.invMassD0ToPiK(candidate1), candidate1.pt()); } else if (originRec1 == 2) { @@ -572,7 +579,8 @@ struct HfCorrelatorDMesonPairs { if (isDbarCand1) { if (isTrueDbarCand1) { registry.fill(HIST("hMass"), hfHelper.invMassD0barToKPi(candidate1), candidate1.pt()); - registry.fill(HIST("hPtVsYMcRec"), candidate1.pt(), hfHelper.yD0(candidate1)); + registry.fill(HIST("hPtVsYVsNContribMcRec"), candidate1.pt(), hfHelper.yD0(candidate1), collision.numContrib()); + registry.fill(HIST("hNContribMcRec"), collision.numContrib()); if (originRec1 == 1) { registry.fill(HIST("hMassMcRecPrompt"), hfHelper.invMassD0barToKPi(candidate1), candidate1.pt()); } else if (originRec1 == 2) { @@ -665,8 +673,16 @@ struct HfCorrelatorDMesonPairs { PROCESS_SWITCH(HfCorrelatorDMesonPairs, processMcRec, "Process Mc reco mode", false); - void processMcGen(aod::McCollision const&, McParticlesPlus2Prong const& mcParticles) + void processMcGen(aod::McCollision const&, soa::SmallGroups> const& collisions, McParticlesPlus2Prong const& mcParticles) { + int numPvContributorsGen{0}; + for (const auto& collision : collisions) { // loop over reco collisions associated to this gen collision + int numPvContributors = collision.numContrib(); + + if (numPvContributors > numPvContributorsGen) { // we take the associated reconstructed collision with higher number of PV contributors + numPvContributorsGen = numPvContributors; + } + } // Get counters per event int nDevent = 0, nDbarevent = 0, nDDbarevent = 0, nDorDbarevent = 0; for (const auto& particle : mcParticles) { @@ -750,7 +766,8 @@ struct HfCorrelatorDMesonPairs { registry.fill(HIST("hStatusSinglePartMcGen"), 4); } - registry.fill(HIST("hPtVsYMcGen"), particle1.pt(), particle1.y()); + registry.fill(HIST("hPtVsYVsNContribMcGen"), particle1.pt(), particle1.y(), numPvContributorsGen); + registry.fill(HIST("hNContribMcGen"), numPvContributorsGen); for (auto particle2 = particle1 + 1; particle2 != mcParticles.end(); ++particle2) { // check if the particle is D0 or D0bar diff --git a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx index a2f57e21a9f..ecd5d7c0bc6 100644 --- a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx @@ -271,10 +271,9 @@ struct HfCorrelatorLcHadrons { if (selectedLcCandidates.size() == 0) { return; } - // find leading particle if (correlateLcWithLeadingParticle) { - leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value); + leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value, etaTrackMax.value); } int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFT0M())); @@ -363,7 +362,6 @@ struct HfCorrelatorLcHadrons { continue; } } - if (candidate.isSelLcToPKPi() >= selectionFlagLc) { entryLcHadronPair(getDeltaPhi(track.phi(), candidate.phi()), track.eta() - candidate.eta(), @@ -397,10 +395,9 @@ struct HfCorrelatorLcHadrons { if (selectedLcCandidatesMc.size() == 0) { return; } - // find leading particle if (correlateLcWithLeadingParticle) { - leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value); + leadingIndex = findLeadingParticle(tracks, dcaXYTrackMax.value, dcaZTrackMax.value, etaTrackMax.value); } int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFT0M())); @@ -517,7 +514,6 @@ struct HfCorrelatorLcHadrons { continue; } } - if (candidate.isSelLcToPKPi() >= selectionFlagLc) { entryLcHadronPair(getDeltaPhi(track.phi(), candidate.phi()), track.eta() - candidate.eta(), @@ -536,6 +532,7 @@ struct HfCorrelatorLcHadrons { correlationStatus); entryLcHadronRecoInfo(hfHelper.invMassLcToPiKP(candidate), isLcSignal); } + } // end inner loop (Tracks) } // end outer Lc loop registry.fill(HIST("hZvtx"), collision.posZ()); diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx index 351b900d48a..f7aad26d676 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx @@ -77,8 +77,8 @@ struct HfTaskCharmHadronsFemtoDream { /// Particle 2 (Charm Hadrons) Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; - Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron"}; - Configurable charmHadMcSel{"charmHadMcSel", 2, "charm hadron selection for mc, partDplusToPiKPi (1), partLcToPKPi (2), partDsToKKPi (4), partXicToPKPi (8)"}; + Configurable charmHadCandSel{"charmHadCandSel", 1, "candidate selection for charm hadron"}; + Configurable charmHadMcSel{"charmHadMcSel", 2, "charm hadron selection for mc, partDplusToPiKPi (1), partLcToPKPi (2), partDsToKKPi (4), partXicToPKPi (8)"}; Configurable charmHadFdBDTmin{"charmHadFdBDTmin", 0., "Minimum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadFdBDTmax{"charmHadFdBDTmax", 1., "Maximum feed-down bdt score Charm Hadron (particle 2)"}; Configurable charmHadMaxInvMass{"charmHadMaxInvMass", 2.45, "Maximum invariant mass of Charm Hadron (particle 2)"}; @@ -196,6 +196,10 @@ struct HfTaskCharmHadronsFemtoDream { void init(InitContext& /*context*/) { + // setup columnpolicy for binning + colBinningMult = {{mixingBinVztx, mixingBinMult}, true}; + colBinningMultPercentile = {{mixingBinVztx, mixingBinMultPercentile}, true}; + colBinningMultMultPercentile = {{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; eventHisto.init(®istry); trackHistoPartOne.init(®istry, binmultTempFit, binMulPercentile, binpTTrack, binEta, binPhi, binTempFitVarTrack, binNSigmaTPC, binNSigmaTOF, binNSigmaTPCTOF, binTPCClusters, dummy, isMc, pdgCodeTrack1, true); @@ -242,7 +246,7 @@ struct HfTaskCharmHadronsFemtoDream { /// Histogramming same event for (auto const& part : sliceTrk1) { - trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + trackHistoPartOne.fillQA(part, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); } for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { @@ -349,7 +353,6 @@ struct HfTaskCharmHadronsFemtoDream { } const int multiplicityCol = collision1.multNtr(); - registryMixQa.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), multiplicityCol})); auto sliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); diff --git a/PWGHF/HFC/Utils/utilsCorrelations.h b/PWGHF/HFC/Utils/utilsCorrelations.h index 0c214cb1c6f..65f447a2b90 100644 --- a/PWGHF/HFC/Utils/utilsCorrelations.h +++ b/PWGHF/HFC/Utils/utilsCorrelations.h @@ -43,14 +43,17 @@ Region getRegion(T const deltaPhi) } // ========= Find Leading Particle ============== -template -int findLeadingParticle(TTracks const& tracks, T1 const dcaXYTrackMax, T2 const dcaZTrackMax) +template +int findLeadingParticle(TTracks const& tracks, T1 const dcaXYTrackMax, T2 const dcaZTrackMax, T3 const etaTrackMax) { auto leadingParticle = tracks.begin(); for (auto const& track : tracks) { if (std::abs(track.dcaXY()) >= dcaXYTrackMax || std::abs(track.dcaZ()) >= dcaZTrackMax) { continue; } + if (std::abs(track.eta()) > etaTrackMax) { + continue; + } if (track.pt() > leadingParticle.pt()) { leadingParticle = track; } diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index 918f06da9bd..e86fe36813f 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -206,8 +206,8 @@ struct HfTaskElectronWeakBoson { // LOG(info) << "tr phi1 = " << track.phi(); // LOG(info) << "emc phi = " << phiEmc; if (nMatch == 0) { - double dEta = match.track_as().eta() - etaEmc; - double dPhi = match.track_as().phi() - phiEmc; + double dEta = match.track_as().trackEtaEmcal() - etaEmc; + double dPhi = match.track_as().trackPhiEmcal() - phiEmc; dPhi = RecoDecay::constrainAngle(dPhi, -o2::constants::math::PI); registry.fill(HIST("hMatchPhi"), phiEmc, match.track_as().phi()); diff --git a/PWGHF/HFL/Tasks/taskSingleMuon.cxx b/PWGHF/HFL/Tasks/taskSingleMuon.cxx index fc70cfecc35..73445124ae9 100644 --- a/PWGHF/HFL/Tasks/taskSingleMuon.cxx +++ b/PWGHF/HFL/Tasks/taskSingleMuon.cxx @@ -56,8 +56,8 @@ struct HfTaskSingleMuonSelectionAmbiguousMftIndexBuilder { }; struct HfTaskSingleMuon { - Configurable trkType{"trkType", 0, "Muon track type, valid values are 0, 1, 2, 3 and 4"}; - Configurable mcMaskSelection{"mcMaskSelection", 0, "McMask for correct match, valid values are 0 and 128"}; + Configurable trkType{"trkType", 0u, "Muon track type, valid values are 0, 1, 2, 3 and 4"}; + Configurable mcMaskSelection{"mcMaskSelection", 0u, "McMask for correct match, valid values are 0 and 128"}; Configurable etaMin{"etaMin", -3.6, "eta minimum value"}; Configurable etaMax{"etaMax", -2.5, "eta maximum value"}; Configurable pDcaMin{"pDcaMin", 324., "p*DCA maximum value for small Rabs"}; diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index 133d4bf3d45..58f6d3280e4 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -276,6 +276,11 @@ o2physics_add_dpl_workflow(tree-creator-dstar-to-d0-pi # Derived-data creators +o2physics_add_dpl_workflow(derived-data-creator-bplus-to-d0-pi + SOURCES derivedDataCreatorBplusToD0Pi.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(derived-data-creator-d0-to-k-pi SOURCES derivedDataCreatorD0ToKPi.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/TableProducer/candidateCreator2Prong.cxx b/PWGHF/TableProducer/candidateCreator2Prong.cxx index 59426b210bb..6d27cfd9021 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -20,6 +20,10 @@ #define HomogeneousField #endif +#include +#include +#include + #include #include #include @@ -78,15 +82,12 @@ struct HfCandidateCreator2Prong { // magnetic field setting from CCDB Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; HfEventSelection hfEvSel; // event selection and monitoring o2::vertexing::DCAFitterN<2> df; // 2-prong vertex fitter Service ccdb; - o2::base::MatLayerCylSet* lut; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; using TracksWCovExtraPidPiKa = soa::Join; @@ -168,7 +169,6 @@ struct HfCandidateCreator2Prong { ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; /// candidate monitoring @@ -204,7 +204,7 @@ struct HfCandidateCreator2Prong { auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); + initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, nullptr, isRun2); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; // df.setBz(bz); /// put it outside the 'if'! Otherwise we have a difference wrt bz Configurable (< 1 permille) in Run2 conv. data @@ -349,7 +349,7 @@ struct HfCandidateCreator2Prong { auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); + initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, nullptr, isRun2); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; // df.setBz(bz); /// put it outside the 'if'! Otherwise we have a difference wrt bz Configurable (< 1 permille) in Run2 conv. data diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index 4e1349786e5..a14df266590 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -15,6 +15,11 @@ /// /// \author Vít Kučera , CERN +#include +#include +#include +#include + #include #include "CommonConstants/PhysicsConstants.h" @@ -59,7 +64,6 @@ struct HfCandidateCreator3Prong { // magnetic field setting from CCDB Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPathLut{"ccdbPathLut", "GLO/Param/MatLUT", "Path for LUT parametrization"}; Configurable ccdbPathGrp{"ccdbPathGrp", "GLO/GRP/GRP", "Path of the grp file (Run 2)"}; Configurable ccdbPathGrpMag{"ccdbPathGrpMag", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object (Run 3)"}; // flags to enable creation for different particle species separately @@ -71,8 +75,6 @@ struct HfCandidateCreator3Prong { HfEventSelection hfEvSel; // event selection and monitoring o2::vertexing::DCAFitterN<3> df; // 3-prong vertex fitter Service ccdb; - o2::base::MatLayerCylSet* lut; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; int runNumber{0}; float toMicrometers = 10000.; // from cm to µm @@ -152,7 +154,6 @@ struct HfCandidateCreator3Prong { ccdb->setURL(ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(ccdbPathLut)); runNumber = 0; /// candidate monitoring @@ -190,7 +191,7 @@ struct HfCandidateCreator3Prong { auto bc = collision.template bc_as(); if (runNumber != bc.runNumber()) { LOG(info) << ">>>>>>>>>>>> Current run number: " << runNumber; - initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, lut, isRun2); + initCCDB(bc, runNumber, ccdb, isRun2 ? ccdbPathGrp : ccdbPathGrpMag, nullptr, isRun2); bz = o2::base::Propagator::Instance()->getNominalBz(); LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; // df.setBz(bz); /// put it outside the 'if'! Otherwise we have a difference wrt bz Configurable (< 1 permille) in Run2 conv. data diff --git a/PWGHF/TableProducer/candidateCreatorBplus.cxx b/PWGHF/TableProducer/candidateCreatorBplus.cxx index b8845945df9..0d4753c6c98 100644 --- a/PWGHF/TableProducer/candidateCreatorBplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorBplus.cxx @@ -18,6 +18,10 @@ /// \author Deepa Thomas , UT Austin /// \author Antonio Palasciano , Università degli Studi di Bari & INFN, Sezione di Bari +#include +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/DCAFitterN.h" #include "Framework/AnalysisTask.h" @@ -79,9 +83,6 @@ struct HfCandidateCreatorBplus { o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; int runNumber; - double massPi{0.}; - double massD0{0.}; - double massBplus{0.}; double invMass2D0PiMin{0.}; double invMass2D0PiMax{0.}; double bz{0.}; @@ -110,11 +111,8 @@ struct HfCandidateCreatorBplus { void init(InitContext const&) { // invariant-mass window cut - massPi = MassPiPlus; - massD0 = MassD0; - massBplus = MassBPlus; - invMass2D0PiMin = (massBplus - invMassWindowBplus) * (massBplus - invMassWindowBplus); - invMass2D0PiMax = (massBplus + invMassWindowBplus) * (massBplus + invMassWindowBplus); + invMass2D0PiMin = (MassBPlus - invMassWindowBplus) * (MassBPlus - invMassWindowBplus); + invMass2D0PiMax = (MassBPlus + invMassWindowBplus) * (MassBPlus + invMassWindowBplus); // Initialise fitter for B vertex dfB.setPropagateToPCA(propagateToPCA); @@ -173,16 +171,8 @@ struct HfCandidateCreatorBplus { aod::BCsWithTimestamps const&) { - static int nCol = 0; - for (const auto& collision : collisions) { auto primaryVertex = getPrimaryVertex(collision); - - if (nCol % 10000 == 0) { - LOG(debug) << nCol << " collisions parsed"; - } - nCol++; - /// Set the magnetic field from ccdb. /// The static instance of the propagator was already modified in the HFTrackIndexSkimCreator, /// but this is not true when running on Run2 data/MC already converted into AO2Ds. @@ -294,7 +284,6 @@ struct HfCandidateCreatorBplus { auto trackParCovPi = getTrackParCov(trackPion); std::array pVecD0 = {0., 0., 0.}; std::array pVecBach = {0., 0., 0.}; - std::array pVecBCand = {0., 0., 0.}; // find the DCA between the D0 and the bachelor track, for B+ hCandidatesB->Fill(SVFitting::BeforeFit); @@ -318,8 +307,6 @@ struct HfCandidateCreatorBplus { auto covMatrixPCA = dfB.calcPCACovMatrixFlat(); hCovSVXX->Fill(covMatrixPCA[0]); // FIXME: Calculation of errorDecayLength(XY) gives wrong values without this line. - pVecBCand = RecoDecay::pVec(pVecD0, pVecBach); - // get track impact parameters // This modifies track momenta! auto covMatrixPV = primaryVertex.getCov(); @@ -336,7 +323,7 @@ struct HfCandidateCreatorBplus { auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.)); // compute invariant mass square and apply selection - auto invMass2D0Pi = RecoDecay::m2(std::array{pVecD0, pVecBach}, std::array{massD0, massPi}); + auto invMass2D0Pi = RecoDecay::m2(std::array{pVecD0, pVecBach}, std::array{MassD0, MassPiPlus}); if ((invMass2D0Pi < invMass2D0PiMin) || (invMass2D0Pi > invMass2D0PiMax)) { continue; } diff --git a/PWGHF/TableProducer/candidateSelectorBsToDsPi.cxx b/PWGHF/TableProducer/candidateSelectorBsToDsPi.cxx index d17f0ada8a0..9fc9fc8bdfc 100644 --- a/PWGHF/TableProducer/candidateSelectorBsToDsPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorBsToDsPi.cxx @@ -15,6 +15,9 @@ /// /// \author Phil Stahlhut +#include +#include + #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" @@ -59,7 +62,7 @@ struct HfCandidateSelectorBsToDsPi { 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 nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::nCutScores), "Number of classes in ML model"}; // CCDB configuration Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTBs"}, "Paths of models on CCDB"}; diff --git a/PWGHF/TableProducer/candidateSelectorD0.cxx b/PWGHF/TableProducer/candidateSelectorD0.cxx index fd249a91e3f..88a8fb017b3 100644 --- a/PWGHF/TableProducer/candidateSelectorD0.cxx +++ b/PWGHF/TableProducer/candidateSelectorD0.cxx @@ -15,6 +15,9 @@ /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -64,7 +67,7 @@ struct HfCandidateSelectorD0 { 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 nClassesMl{"nClassesMl", static_cast(hf_cuts_ml::nCutScores), "Number of classes in ML model"}; Configurable enableDebugMl{"enableDebugMl", false, "Flag to enable histograms to monitor BDT application"}; Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; // CCDB configuration diff --git a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx index 638a25aaf7c..d6d607ba9c4 100644 --- a/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDplusToPiKPi.cxx @@ -15,6 +15,9 @@ /// \author Fabio Catalano , Politecnico and INFN Torino /// \author Vít Kučera , CERN +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -67,7 +70,7 @@ struct HfCandidateSelectorDplusToPiKPi { 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 nClassesMl{"nClassesMl", static_cast(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"}; diff --git a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx index 91df36d441c..6d00e6daee9 100644 --- a/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDsToKKPi.cxx @@ -15,6 +15,9 @@ /// \author Fabio Catalano , Universita and INFN Torino /// \author Stefano Politano , Politecnico and INFN Torino +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -66,7 +69,7 @@ struct HfCandidateSelectorDsToKKPi { 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 nClassesMl{"nClassesMl", static_cast(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"}; diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index 777b095fcbb..6445241d318 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -15,6 +15,10 @@ /// \author Deependra Sharma , IITB /// \author Fabrizio Grosa , CERN +#include +#include +#include + // O2 #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisDataModel.h" @@ -81,7 +85,7 @@ struct HfCandidateSelectorDstarToD0Pi { 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 nClassesMl{"nClassesMl", static_cast(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 diff --git a/PWGHF/TableProducer/candidateSelectorLc.cxx b/PWGHF/TableProducer/candidateSelectorLc.cxx index 6e50e1262a9..818d65bb269 100644 --- a/PWGHF/TableProducer/candidateSelectorLc.cxx +++ b/PWGHF/TableProducer/candidateSelectorLc.cxx @@ -17,6 +17,9 @@ /// \author Vít Kučera , CERN /// \author Grazia Luparello , INFN Trieste +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -77,7 +80,7 @@ struct HfCandidateSelectorLc { 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 nClassesMl{"nClassesMl", static_cast(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"}; diff --git a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx index 7e8d48085f0..c7b17972b8f 100644 --- a/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx +++ b/PWGHF/TableProducer/candidateSelectorLcToK0sP.cxx @@ -17,6 +17,9 @@ /// Daniel Samitz, , Vienna /// Elisa Meninno, , Vienna +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -62,7 +65,7 @@ struct HfCandidateSelectorLcToK0sP { 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 nClassesMl{"nClassesMl", static_cast(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"}; diff --git a/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx b/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx index cb032518305..64ecd5cf65e 100644 --- a/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXicToPKPi.cxx @@ -17,6 +17,9 @@ /// \author Vít Kučera , CERN /// \author Cristina Terrevoli , INFN BARI +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -60,7 +63,7 @@ struct HfCandidateSelectorXicToPKPi { 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 nClassesMl{"nClassesMl", static_cast(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"}; diff --git a/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx index a1a76ac86ea..49b4b2df01b 100644 --- a/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateSelectorXicToXiPiPi.cxx @@ -13,12 +13,17 @@ /// \brief Ξc± → Ξ∓ π± π± candidate selector /// /// \author Phil Lennart Stahlhut , Heidelberg University +/// \author Jaeyoon Cho , Inha University + +#include +#include #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Common/Core/TrackSelectorPID.h" +#include "PWGHF/Core/HfMlResponseXicToXiPiPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -31,6 +36,7 @@ using namespace o2::analysis; struct HfCandidateSelectorXicToXiPiPi { Produces hfSelXicToXiPiPiCandidate; + Produces hfMlXicToXiPiPiCandidate; Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; Configurable ptCandMax{"ptCandMax", 36., "Upper bound of candidate pT"}; @@ -52,7 +58,23 @@ struct HfCandidateSelectorXicToXiPiPi { Configurable ptPidTofMax{"ptPidTofMax", 20., "Upper bound of track pT for TOF PID"}; Configurable nSigmaTofMax{"nSigmaTofMax", 5., "Nsigma cut on TOF only"}; Configurable nSigmaTofCombinedMax{"nSigmaTofCombinedMax", 5., "Nsigma cut on TOF combined with TPC"}; - + // 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/BDTXicToXiPiPi"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_XicToXiPiPi.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"}; + + o2::analysis::HfMlResponseXicToXiPiPi hfMlResponse; + std::vector outputMlXicToXiPiPi = {}; + o2::ccdb::CcdbApi ccdbApi; TrackSelectorPi selectorPion; TrackSelectorPr selectorProton; @@ -93,6 +115,18 @@ struct HfCandidateSelectorXicToXiPiPi { 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 @@ -188,6 +222,9 @@ struct HfCandidateSelectorXicToXiPiPi { { for (const auto& hfCandXic : hfCandsXic) { int statusXicToXiPiPi = 0; + + outputMlXicToXiPiPi.clear(); + auto ptCandXic = hfCandXic.pt(); if (activateQA) { @@ -203,6 +240,9 @@ struct HfCandidateSelectorXicToXiPiPi { // topological cuts if (!selectionTopol(hfCandXic)) { hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); + if (applyMl) { + hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); + } continue; } SETBIT(statusXicToXiPiPi, SelectionStep::RecoTopol); // RecoTopol = 1 --> statusXicToXiPiPi = 3 @@ -233,6 +273,9 @@ struct HfCandidateSelectorXicToXiPiPi { if (!selectionPid(pidTrackPi0, pidTrackPi1, pidTrackPr, pidTrackPiLam, pidTrackPiXi, acceptPIDNotApplicable.value)) { hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); + if (applyMl) { + hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); + } continue; } SETBIT(statusXicToXiPiPi, SelectionStep::RecoPID); // RecoPID = 2 --> statusXicToXiPiPi = 7 @@ -241,6 +284,23 @@ struct HfCandidateSelectorXicToXiPiPi { } } + // ML selections + + if (applyMl) { + bool isSelectedMlXicToXiPiPi = false; + std::vector inputFeaturesXicToXiPiPi = hfMlResponse.getInputFeatures(hfCandXic); + + isSelectedMlXicToXiPiPi = hfMlResponse.isSelectedMl(inputFeaturesXicToXiPiPi, ptCandXic, outputMlXicToXiPiPi); + + hfMlXicToXiPiPiCandidate(outputMlXicToXiPiPi); + + if (!isSelectedMlXicToXiPiPi) { + hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); + continue; + } + SETBIT(statusXicToXiPiPi, aod::SelectionStep::RecoMl); + } + hfSelXicToXiPiPiCandidate(statusXicToXiPiPi); } } diff --git a/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx b/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx new file mode 100644 index 00000000000..6c0ada5de5b --- /dev/null +++ b/PWGHF/TableProducer/derivedDataCreatorBplusToD0Pi.cxx @@ -0,0 +1,557 @@ +// 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 derivedDataCreatorBplusToD0Pi.cxx +/// \brief Producer of derived tables of B+ candidates, collisions and MC particles +/// \note Based on derivedDataCreatorLcToPKPi.cxx +/// +/// \author Vít Kučera , Inha University + +#include +#include +#include + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/DerivedTables.h" +#include "PWGHF/Utils/utilsDerivedData.h" +#include "PWGHF/Utils/utilsPid.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::pid_tpc_tof_utils; +using namespace o2::analysis::hf_derived; + +/// Writes the full information in an output TTree +struct HfDerivedDataCreatorBplusToD0Pi { + // Candidates + Produces rowCandidateBase; + Produces rowCandidatePar; + Produces rowCandidateParD0; + Produces rowCandidateParE; + Produces rowCandidateMl; + Produces rowCandidateMlD0; + Produces rowCandidateId; + Produces rowCandidateMc; + // Collisions + Produces rowCollBase; + Produces rowCollId; + // MC collisions + Produces rowMcCollBase; + Produces rowMcCollId; + Produces rowMcRCollId; + // MC particles + Produces rowParticleBase; + Produces rowParticleId; + + // Switches for filling tables + Configurable fillCandidateBase{"fillCandidateBase", true, "Fill candidate base properties"}; + Configurable fillCandidatePar{"fillCandidatePar", true, "Fill candidate parameters"}; + Configurable fillCandidateParD0{"fillCandidateParD0", true, "Fill D0 candidate parameters"}; + Configurable fillCandidateParE{"fillCandidateParE", true, "Fill candidate extended parameters"}; + Configurable fillCandidateMl{"fillCandidateMl", true, "Fill candidate selection ML scores"}; + Configurable fillCandidateMlD0{"fillCandidateMlD0", true, "Fill D0 candidate selection ML scores"}; + Configurable fillCandidateId{"fillCandidateId", true, "Fill original indices from the candidate table"}; + Configurable fillCandidateMc{"fillCandidateMc", true, "Fill candidate MC info"}; + Configurable fillCollBase{"fillCollBase", true, "Fill collision base properties"}; + Configurable fillCollId{"fillCollId", true, "Fill original collision indices"}; + Configurable fillMcCollBase{"fillMcCollBase", true, "Fill MC collision base properties"}; + Configurable fillMcCollId{"fillMcCollId", true, "Fill original MC collision indices"}; + Configurable fillMcRCollId{"fillMcRCollId", true, "Fill indices of saved derived reconstructed collisions matched to saved derived MC collisions"}; + Configurable fillParticleBase{"fillParticleBase", true, "Fill MC particle properties"}; + Configurable fillParticleId{"fillParticleId", true, "Fill original MC indices"}; + // Parameters for production of training samples + Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of background candidates to keep for ML trainings"}; + Configurable ptMaxForDownSample{"ptMaxForDownSample", 10., "Maximum pt for the application of the downsampling factor"}; + + HfHelper hfHelper; + SliceCache cache; + std::map> matchedCollisions; // indices of derived reconstructed collisions matched to the global indices of MC collisions + std::map hasMcParticles; // flags for MC collisions with HF particles + + using CollisionsWCentMult = soa::Join; + using CollisionsWMcCentMult = soa::Join; + using TracksWPid = soa::Join; + using SelectedCandidates = soa::Filtered>; + using SelectedCandidatesMc = soa::Filtered>; + using SelectedCandidatesMl = soa::Filtered>; + using SelectedCandidatesMcMl = soa::Filtered>; + using MatchedGenCandidatesMc = soa::Filtered>; + using TypeMcCollisions = aod::McCollisions; + using THfCandDaughters = aod::HfCand2ProngWPid; + using THfCandDaughtersMl = soa::Join; + + Filter filterSelectCandidates = aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= 1; + Filter filterMcGenMatching = nabs(aod::hf_cand_bplus::flagMcMatchGen) == static_cast(BIT(aod::hf_cand_bplus::DecayType::BplusToD0Pi)); + + Preslice candidatesPerCollision = aod::hf_cand::collisionId; + Preslice candidatesMcPerCollision = aod::hf_cand::collisionId; + Preslice candidatesMlPerCollision = aod::hf_cand::collisionId; + Preslice candidatesMcMlPerCollision = aod::hf_cand::collisionId; + Preslice mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId; + + // trivial partitions for all candidates to allow "->sliceByCached" inside processCandidates + Partition candidatesAll = aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= 0; + Partition candidatesMcAll = aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= 0; + Partition candidatesMlAll = aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= 0; + Partition candidatesMcMlAll = aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= 0; + // partitions for signal and background + Partition candidatesMcSig = nabs(aod::hf_cand_bplus::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_bplus::DecayType::BplusToD0Pi)); + Partition candidatesMcBkg = nabs(aod::hf_cand_bplus::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_bplus::DecayType::BplusToD0Pi)); + Partition candidatesMcMlSig = nabs(aod::hf_cand_bplus::flagMcMatchRec) == static_cast(BIT(aod::hf_cand_bplus::DecayType::BplusToD0Pi)); + Partition candidatesMcMlBkg = nabs(aod::hf_cand_bplus::flagMcMatchRec) != static_cast(BIT(aod::hf_cand_bplus::DecayType::BplusToD0Pi)); + + void init(InitContext const&) + { + std::array doprocess{doprocessData, doprocessMcSig, doprocessMcBkg, doprocessMcAll, doprocessDataMl, doprocessMcMlSig, doprocessMcMlBkg, doprocessMcMlAll}; + if (std::accumulate(doprocess.begin(), doprocess.end(), 0) != 1) { + LOGP(fatal, "Only one process function can be enabled at a time."); + } + } + + template + // void fillTablesCollision(const T& collision, int isEventReject, int runNumber) + void fillTablesCollision(const T& collision) + { + if (fillCollBase) { + rowCollBase( + collision.posX(), + collision.posY(), + collision.posZ(), + collision.numContrib(), + collision.centFT0A(), + collision.centFT0C(), + collision.centFT0M(), + collision.centFV0A(), + collision.multZeqNTracksPV()); + // isEventReject, + // runNumber); + } + if (fillCollId) { + rowCollId( + collision.globalIndex()); + } + if constexpr (isMC) { + if (fillMcRCollId && collision.has_mcCollision()) { + // Save rowCollBase.lastIndex() at key collision.mcCollisionId() + LOGF(debug, "Rec. collision %d: Filling derived-collision index %d for MC collision %d", collision.globalIndex(), rowCollBase.lastIndex(), collision.mcCollisionId()); + matchedCollisions[collision.mcCollisionId()].push_back(rowCollBase.lastIndex()); // [] inserts an empty element if it does not exist + } + } + } + + template + void fillTablesMcCollision(const T& mcCollision) + { + if (fillMcCollBase) { + rowMcCollBase( + mcCollision.posX(), + mcCollision.posY(), + mcCollision.posZ()); + } + if (fillMcCollId) { + rowMcCollId( + mcCollision.globalIndex()); + } + if (fillMcRCollId) { + // Fill the table with the vector of indices of derived reconstructed collisions matched to mcCollision.globalIndex() + rowMcRCollId( + matchedCollisions[mcCollision.globalIndex()]); + } + } + + template + void fillTablesCandidate(const T& candidate, const U& prongCharm, const V& prongBachelor, int candFlag, double invMass, + double ct, double y, int8_t flagMc, int8_t origin, float mlScore, const std::vector& mlScoresCharm) + { + if (fillCandidateBase) { + rowCandidateBase( + rowCollBase.lastIndex(), + candidate.pt(), + candidate.eta(), + candidate.phi(), + invMass, + y); + } + if (fillCandidatePar) { + rowCandidatePar( + candidate.chi2PCA(), + candidate.cpa(), + candidate.cpaXY(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + prongBachelor.tpcNSigmaPi(), + prongBachelor.tofNSigmaPi(), + prongBachelor.tpcTofNSigmaPi(), + prongBachelor.tpcNSigmaKa(), + prongBachelor.tofNSigmaKa(), + prongBachelor.tpcTofNSigmaKa(), + candidate.maxNormalisedDeltaIP(), + candidate.impactParameterProduct()); + } + if (fillCandidateParD0) { + std::array, 2>, 2> sigmas{}; // PID nSigma [Expected][Hypothesis][TPC/TOF/TPC+TOF] + if (candFlag == 0) { + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion], prongCharm, 0, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon], prongCharm, 0, Ka) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion], prongCharm, 1, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon], prongCharm, 1, Ka) + } else if (candFlag == 1) { + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion], prongCharm, 1, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon], prongCharm, 1, Ka) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion], prongCharm, 0, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon], prongCharm, 0, Ka) + } + rowCandidateParD0( + prongCharm.cpa(), + prongCharm.decayLength(), + prongCharm.impactParameter0(), + prongCharm.impactParameter1(), + prongCharm.impactParameterProduct(), + sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion][0], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion][1], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion][2], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon][0], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon][1], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon][2], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion][0], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion][1], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion][2], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon][0], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon][1], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon][2]); + } + if (fillCandidateParE) { + rowCandidateParE( + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.rSecondaryVertex(), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.errorImpactParameter1(), + hfHelper.cosThetaStarBplus(candidate), + ct); + } + if (fillCandidateMl) { + rowCandidateMl( + mlScore); + } + if (fillCandidateMlD0) { + rowCandidateMlD0( + mlScoresCharm); + } + if (fillCandidateId) { + rowCandidateId( + candidate.collisionId(), + prongCharm.prong0Id(), + prongCharm.prong1Id(), + candidate.prong1Id()); + } + if (fillCandidateMc) { + rowCandidateMc( + flagMc, + origin); + } + } + + template + void fillTablesParticle(const T& particle, U mass) + { + if (fillParticleBase) { + rowParticleBase( + rowMcCollBase.lastIndex(), + particle.pt(), + particle.eta(), + particle.phi(), + RecoDecayPtEtaPhi::y(particle.pt(), particle.eta(), mass), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + if (fillParticleId) { + rowParticleId( + particle.mcCollisionId(), + particle.globalIndex()); + } + } + + template + void processCandidates(CollType const& collisions, + Partition& candidates, + CandCharmType const&, + TracksWPid const&, + aod::BCs const&) + { + // Fill collision properties + if constexpr (isMc) { + if (fillMcRCollId) { + matchedCollisions.clear(); + } + } + auto sizeTableColl = collisions.size(); + reserveTable(rowCollBase, fillCollBase, sizeTableColl); + reserveTable(rowCollId, fillCollId, sizeTableColl); + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto candidatesThisColl = candidates->sliceByCached(aod::hf_cand::collisionId, thisCollId, cache); // FIXME + auto sizeTableCand = candidatesThisColl.size(); + LOGF(debug, "Rec. collision %d has %d candidates", thisCollId, sizeTableCand); + // Skip collisions without HF candidates (and without HF particles in matched MC collisions if saving indices of reconstructed collisions matched to MC collisions) + bool mcCollisionHasMcParticles{false}; + if constexpr (isMc) { + mcCollisionHasMcParticles = fillMcRCollId && collision.has_mcCollision() && hasMcParticles[collision.mcCollisionId()]; + LOGF(debug, "Rec. collision %d has MC collision %d with MC particles? %s", thisCollId, collision.mcCollisionId(), mcCollisionHasMcParticles ? "yes" : "no"); + } + if (sizeTableCand == 0 && (!fillMcRCollId || !mcCollisionHasMcParticles)) { + LOGF(debug, "Skipping rec. collision %d", thisCollId); + continue; + } + LOGF(debug, "Filling rec. collision %d at derived index %d", thisCollId, rowCollBase.lastIndex() + 1); + // fillTablesCollision(collision, 0, collision.bc().runNumber()); + fillTablesCollision(collision); + + // Fill candidate properties + reserveTable(rowCandidateBase, fillCandidateBase, sizeTableCand); + reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); + reserveTable(rowCandidateParD0, fillCandidateParD0, sizeTableCand); + reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); + reserveTable(rowCandidateMlD0, fillCandidateMlD0, sizeTableCand); + reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); + if constexpr (isMc) { + reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); + } + int8_t flagMcRec = 0, origin = 0; + for (const auto& candidate : candidatesThisColl) { + if constexpr (isMc) { + flagMcRec = candidate.flagMcMatchRec(); + origin = candidate.originMcRec(); + if constexpr (onlyBkg) { + if (TESTBIT(std::abs(flagMcRec), aod::hf_cand_bplus::DecayType::BplusToD0Pi)) { + continue; + } + if (downSampleBkgFactor < 1.) { + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); + if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { + continue; + } + } + } + if constexpr (onlySig) { + if (!TESTBIT(std::abs(flagMcRec), aod::hf_cand_bplus::DecayType::BplusToD0Pi)) { + continue; + } + } + } + auto prongCharm = candidate.template prong0_as(); + auto prongBachelor = candidate.template prong1_as(); + double ct = hfHelper.ctBplus(candidate); + double y = hfHelper.yBplus(candidate); + float massBplusToD0Pi = hfHelper.invMassBplusToD0Pi(candidate); + float mlScoreBplusToD0Pi{-1.f}; + std::vector mlScoresD0; + bool isD0 = prongBachelor.sign() < 0; // D0 or D0bar + if constexpr (isMl) { + mlScoreBplusToD0Pi = candidate.mlProbBplusToD0Pi(); + if (isD0) { + std::copy(prongCharm.mlProbD0().begin(), prongCharm.mlProbD0().end(), std::back_inserter(mlScoresD0)); + } else { + std::copy(prongCharm.mlProbD0bar().begin(), prongCharm.mlProbD0bar().end(), std::back_inserter(mlScoresD0)); + } + } + // flag = 0 for D0 pi-, flag = 1 for D0bar pi+ + fillTablesCandidate(candidate, prongCharm, prongBachelor, isD0 ? 0 : 1, massBplusToD0Pi, ct, y, flagMcRec, origin, mlScoreBplusToD0Pi, mlScoresD0); + } + } + } + + template + void preProcessMcCollisions(CollisionType const& mcCollisions, + ParticleType const& mcParticles) + { + if (!fillMcRCollId) { + return; + } + hasMcParticles.clear(); + // Fill MC collision flags + for (const auto& mcCollision : mcCollisions) { + auto thisMcCollId = mcCollision.globalIndex(); + auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); + LOGF(debug, "MC collision %d has %d MC particles (preprocess)", thisMcCollId, particlesThisMcColl.size()); + hasMcParticles[thisMcCollId] = (particlesThisMcColl.size() > 0); + } + } + + template + void processMcParticles(CollisionType const& mcCollisions, + ParticleType const& mcParticles) + { + // Fill MC collision properties + auto sizeTableMcColl = mcCollisions.size(); + reserveTable(rowMcCollBase, fillMcCollBase, sizeTableMcColl); + reserveTable(rowMcCollId, fillMcCollId, sizeTableMcColl); + reserveTable(rowMcRCollId, fillMcRCollId, sizeTableMcColl); + for (const auto& mcCollision : mcCollisions) { + auto thisMcCollId = mcCollision.globalIndex(); + auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); + auto sizeTablePart = particlesThisMcColl.size(); + LOGF(debug, "MC collision %d has %d MC particles", thisMcCollId, sizeTablePart); + // Skip MC collisions without HF particles (and without HF candidates in matched reconstructed collisions if saving indices of reconstructed collisions matched to MC collisions) + LOGF(debug, "MC collision %d has %d saved derived rec. collisions", thisMcCollId, matchedCollisions[thisMcCollId].size()); + if (sizeTablePart == 0 && (!fillMcRCollId || matchedCollisions[thisMcCollId].empty())) { + LOGF(debug, "Skipping MC collision %d", thisMcCollId); + continue; + } + LOGF(debug, "Filling MC collision %d at derived index %d", thisMcCollId, rowMcCollBase.lastIndex() + 1); + fillTablesMcCollision(mcCollision); + + // Fill MC particle properties + reserveTable(rowParticleBase, fillParticleBase, sizeTablePart); + reserveTable(rowParticleId, fillParticleId, sizeTablePart); + for (const auto& particle : particlesThisMcColl) { + fillTablesParticle(particle, o2::constants::physics::MassBPlus); + } + } + } + + void processData(CollisionsWCentMult const& collisions, + SelectedCandidates const&, + THfCandDaughters const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesAll, candidatesDaughters, tracks, bcs); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processData, "Process data", true); + + void processMcSig(CollisionsWMcCentMult const& collisions, + SelectedCandidatesMc const&, + TypeMcCollisions const& mcCollisions, + MatchedGenCandidatesMc const& mcParticles, + THfCandDaughters const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + preProcessMcCollisions(mcCollisions, mcParticles); + processCandidates(collisions, candidatesMcSig, candidatesDaughters, tracks, bcs); + processMcParticles(mcCollisions, mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processMcSig, "Process MC only for signals", false); + + void processMcBkg(CollisionsWMcCentMult const& collisions, + SelectedCandidatesMc const&, + TypeMcCollisions const& mcCollisions, + MatchedGenCandidatesMc const& mcParticles, + THfCandDaughters const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + preProcessMcCollisions(mcCollisions, mcParticles); + processCandidates(collisions, candidatesMcBkg, candidatesDaughters, tracks, bcs); + processMcParticles(mcCollisions, mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processMcBkg, "Process MC only for background", false); + + void processMcAll(CollisionsWMcCentMult const& collisions, + SelectedCandidatesMc const&, + TypeMcCollisions const& mcCollisions, + MatchedGenCandidatesMc const& mcParticles, + THfCandDaughters const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + preProcessMcCollisions(mcCollisions, mcParticles); + processCandidates(collisions, candidatesMcAll, candidatesDaughters, tracks, bcs); + processMcParticles(mcCollisions, mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processMcAll, "Process MC", false); + + // ML versions + + void processDataMl(CollisionsWCentMult const& collisions, + SelectedCandidatesMl const&, + THfCandDaughtersMl const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + processCandidates(collisions, candidatesMlAll, candidatesDaughters, tracks, bcs); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processDataMl, "Process data with ML", false); + + void processMcMlSig(CollisionsWMcCentMult const& collisions, + SelectedCandidatesMcMl const&, + TypeMcCollisions const& mcCollisions, + MatchedGenCandidatesMc const& mcParticles, + THfCandDaughtersMl const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + preProcessMcCollisions(mcCollisions, mcParticles); + processCandidates(collisions, candidatesMcMlSig, candidatesDaughters, tracks, bcs); + processMcParticles(mcCollisions, mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processMcMlSig, "Process MC with ML only for signals", false); + + void processMcMlBkg(CollisionsWMcCentMult const& collisions, + SelectedCandidatesMcMl const&, + TypeMcCollisions const& mcCollisions, + MatchedGenCandidatesMc const& mcParticles, + THfCandDaughtersMl const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + preProcessMcCollisions(mcCollisions, mcParticles); + processCandidates(collisions, candidatesMcMlBkg, candidatesDaughters, tracks, bcs); + processMcParticles(mcCollisions, mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processMcMlBkg, "Process MC with ML only for background", false); + + void processMcMlAll(CollisionsWMcCentMult const& collisions, + SelectedCandidatesMcMl const&, + TypeMcCollisions const& mcCollisions, + MatchedGenCandidatesMc const& mcParticles, + THfCandDaughtersMl const& candidatesDaughters, + TracksWPid const& tracks, + aod::BCs const& bcs) + { + preProcessMcCollisions(mcCollisions, mcParticles); + processCandidates(collisions, candidatesMcMlAll, candidatesDaughters, tracks, bcs); + processMcParticles(mcCollisions, mcParticles); + } + PROCESS_SWITCH(HfDerivedDataCreatorBplusToD0Pi, processMcMlAll, "Process MC with ML", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx index 59480f3b50a..de26dc1dff3 100644 --- a/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorD0ToKPi.cxx @@ -15,6 +15,10 @@ /// /// \author Vít Kučera , Inha University +#include +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -27,10 +31,14 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/DataModel/DerivedTables.h" +#include "PWGHF/Utils/utilsDerivedData.h" +#include "PWGHF/Utils/utilsPid.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::pid_tpc_tof_utils; +using namespace o2::analysis::hf_derived; /// Writes the full information in an output TTree struct HfDerivedDataCreatorD0ToKPi { @@ -132,14 +140,6 @@ struct HfDerivedDataCreatorD0ToKPi { } } - template - void reserveTable(T& table, const Configurable& enabled, const uint64_t size) - { - if (enabled.value) { - table.reserve(size); - } - }; - template // void fillTablesCollision(const T& collision, int isEventReject, int runNumber) void fillTablesCollision(const T& collision) @@ -204,33 +204,18 @@ struct HfDerivedDataCreatorD0ToKPi { invMass, y); } - if (fillCandidatePar) { - float tpcNSigmaPiExpPi = candidate.nSigTpcPi0(); - float tofNSigmaPiExpPi = candidate.nSigTofPi0(); - float tpcTofNSigmaPiExpPi = candidate.tpcTofNSigmaPi0(); - float tpcNSigmaKaExpPi = candidate.nSigTpcKa0(); - float tofNSigmaKaExpPi = candidate.nSigTofKa0(); - float tpcTofNSigmaKaExpPi = candidate.tpcTofNSigmaKa0(); - float tpcNSigmaPiExpKa = candidate.nSigTpcPi1(); - float tofNSigmaPiExpKa = candidate.nSigTofPi1(); - float tpcTofNSigmaPiExpKa = candidate.tpcTofNSigmaPi1(); - float tpcNSigmaKaExpKa = candidate.nSigTpcKa1(); - float tofNSigmaKaExpKa = candidate.nSigTofKa1(); - float tpcTofNSigmaKaExpKa = candidate.tpcTofNSigmaKa1(); - if (candFlag == 1) { - tpcNSigmaPiExpPi = candidate.nSigTpcPi1(); - tofNSigmaPiExpPi = candidate.nSigTofPi1(); - tpcTofNSigmaPiExpPi = candidate.tpcTofNSigmaPi1(); - tpcNSigmaKaExpPi = candidate.nSigTpcKa1(); - tofNSigmaKaExpPi = candidate.nSigTofKa1(); - tpcTofNSigmaKaExpPi = candidate.tpcTofNSigmaKa1(); - tpcNSigmaPiExpKa = candidate.nSigTpcPi0(); - tofNSigmaPiExpKa = candidate.nSigTofPi0(); - tpcTofNSigmaPiExpKa = candidate.tpcTofNSigmaPi0(); - tpcNSigmaKaExpKa = candidate.nSigTpcKa0(); - tofNSigmaKaExpKa = candidate.nSigTofKa0(); - tpcTofNSigmaKaExpKa = candidate.tpcTofNSigmaKa0(); + std::array, 2>, 2> sigmas{}; // PID nSigma [Expected][Hypothesis][TPC/TOF/TPC+TOF] + if (candFlag == 0) { + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion], candidate, 0, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon], candidate, 0, Ka) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion], candidate, 1, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon], candidate, 1, Ka) + } else if (candFlag == 1) { + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion], candidate, 1, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon], candidate, 1, Ka) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion], candidate, 0, Pi) + GET_N_SIGMA_PRONG(sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon], candidate, 0, Ka) } rowCandidatePar( candidate.chi2PCA(), @@ -246,18 +231,18 @@ struct HfDerivedDataCreatorD0ToKPi { candidate.impactParameter1(), candidate.impactParameterNormalised0(), candidate.impactParameterNormalised1(), - tpcNSigmaPiExpPi, - tofNSigmaPiExpPi, - tpcTofNSigmaPiExpPi, - tpcNSigmaKaExpPi, - tofNSigmaKaExpPi, - tpcTofNSigmaKaExpPi, - tpcNSigmaPiExpKa, - tofNSigmaPiExpKa, - tpcTofNSigmaPiExpKa, - tpcNSigmaKaExpKa, - tofNSigmaKaExpKa, - tpcTofNSigmaKaExpKa, + sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion][0], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion][1], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Pion][2], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon][0], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon][1], + sigmas[HfProngSpecies::Pion][HfProngSpecies::Kaon][2], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion][0], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion][1], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Pion][2], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon][0], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon][1], + sigmas[HfProngSpecies::Kaon][HfProngSpecies::Kaon][2], candidate.maxNormalisedDeltaIP(), candidate.impactParameterProduct()); } @@ -363,6 +348,7 @@ struct HfDerivedDataCreatorD0ToKPi { reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); if constexpr (isMc) { reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); @@ -377,7 +363,7 @@ struct HfDerivedDataCreatorD0ToKPi { continue; } if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { continue; } @@ -390,7 +376,7 @@ struct HfDerivedDataCreatorD0ToKPi { } } else { if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { continue; } @@ -448,6 +434,7 @@ struct HfDerivedDataCreatorD0ToKPi { // Fill MC collision properties auto sizeTableMcColl = mcCollisions.size(); reserveTable(rowMcCollBase, fillMcCollBase, sizeTableMcColl); + reserveTable(rowMcCollId, fillMcCollId, sizeTableMcColl); reserveTable(rowMcRCollId, fillMcRCollId, sizeTableMcColl); for (const auto& mcCollision : mcCollisions) { auto thisMcCollId = mcCollision.globalIndex(); diff --git a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx index 645deab1c39..5827f26a1aa 100644 --- a/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/derivedDataCreatorLcToPKPi.cxx @@ -15,6 +15,10 @@ /// /// \author Vít Kučera , Inha University +#include +#include +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -27,10 +31,12 @@ #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" #include "PWGHF/DataModel/DerivedTables.h" +#include "PWGHF/Utils/utilsDerivedData.h" using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::analysis::hf_derived; /// Writes the full information in an output TTree struct HfDerivedDataCreatorLcToPKPi { @@ -115,14 +121,6 @@ struct HfDerivedDataCreatorLcToPKPi { } } - template - void reserveTable(T& table, const Configurable& enabled, const uint64_t size) - { - if (enabled.value) { - table.reserve(size); - } - }; - template // void fillTablesCollision(const T& collision, int isEventReject, int runNumber) void fillTablesCollision(const T& collision) @@ -329,6 +327,7 @@ struct HfDerivedDataCreatorLcToPKPi { reserveTable(rowCandidatePar, fillCandidatePar, sizeTableCand); reserveTable(rowCandidateParE, fillCandidateParE, sizeTableCand); reserveTable(rowCandidateSel, fillCandidateSel, sizeTableCand); + reserveTable(rowCandidateMl, fillCandidateMl, sizeTableCand); reserveTable(rowCandidateId, fillCandidateId, sizeTableCand); if constexpr (isMc) { reserveTable(rowCandidateMc, fillCandidateMc, sizeTableCand); @@ -344,7 +343,7 @@ struct HfDerivedDataCreatorLcToPKPi { continue; } if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { continue; } @@ -402,6 +401,7 @@ struct HfDerivedDataCreatorLcToPKPi { // Fill MC collision properties auto sizeTableMcColl = mcCollisions.size(); reserveTable(rowMcCollBase, fillMcCollBase, sizeTableMcColl); + reserveTable(rowMcCollId, fillMcCollId, sizeTableMcColl); reserveTable(rowMcRCollId, fillMcRCollId, sizeTableMcColl); for (const auto& mcCollision : mcCollisions) { auto thisMcCollId = mcCollision.globalIndex(); diff --git a/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx b/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx index dd863781594..fd11fad78b1 100644 --- a/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/treeCreatorDstarToD0Pi.cxx @@ -293,21 +293,50 @@ struct HfTreeCreatorDstarToD0Pi { originMc = candidate.originMcRec(); } - auto prong0 = candidate.template prong0_as(); - auto prong1 = candidate.template prong1_as(); + TracksWPid::iterator prong0; + TracksWPid::iterator prong1; auto prongSoftPi = candidate.template prongPi_as(); float massD0{-1.f}; float massDStar{-1.f}; float cosThetaD0{-1.f}; + float impParameterProng0{-999.}, impParameterProng1{-999.}; + // float errorImpParameterProng0{-999.}, errorImpParameterProng1{-999.}; + float impParameterNormalisedProng0{-999.}, impParameterNormalisedProng1{-999.}; + float ptProng0{-999.}, ptProng1{-999.}; + float pProng0{-999.}, pProng1{-999.}; if (candidate.signSoftPi() > 0) { massD0 = candidate.invMassD0(); massDStar = candidate.invMassDstar(); cosThetaD0 = candidate.cosThetaStarD0(); + prong0 = candidate.template prong0_as(); // pion + prong1 = candidate.template prong1_as(); // kaon + ptProng0 = candidate.ptProng0(); + ptProng1 = candidate.ptProng1(); + impParameterProng0 = candidate.impactParameter0(); + impParameterProng1 = candidate.impactParameter1(); + // errorImpParameterProng0 = candidate.errorImpactParameter0(); + // errorImpParameterProng1 = candidate.errorImpactParameter1(); + impParameterNormalisedProng0 = candidate.impactParameterNormalised0(); + impParameterNormalisedProng1 = candidate.impactParameterNormalised1(); + pProng0 = RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()); + pProng1 = RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()); } else { massD0 = candidate.invMassD0Bar(); massDStar = candidate.invMassAntiDstar(); cosThetaD0 = candidate.cosThetaStarD0Bar(); + prong0 = candidate.template prong1_as(); // pion + prong1 = candidate.template prong0_as(); // kaon + ptProng0 = candidate.ptProng1(); + ptProng1 = candidate.ptProng0(); + impParameterProng0 = candidate.impactParameter1(); + impParameterProng1 = candidate.impactParameter0(); + // errorImpParameterProng0 = candidate.errorImpactParameter1(); + // errorImpParameterProng1 = candidate.errorImpactParameter0(); + impParameterNormalisedProng0 = candidate.impactParameterNormalised1(); + impParameterNormalisedProng1 = candidate.impactParameterNormalised0(); + pProng0 = RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()); + pProng1 = RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()); } if (fillCandidateLiteTable) { @@ -322,14 +351,14 @@ struct HfTreeCreatorDstarToD0Pi { candidate.deltaIPNormalisedMaxD0(), candidate.impactParameterProductD0(), cosThetaD0, - candidate.ptProng0(), - candidate.ptProng1(), + ptProng0, + ptProng1, candidate.ptSoftPi(), - candidate.impactParameter0(), - candidate.impactParameter1(), + impParameterProng0, + impParameterProng1, candidate.impParamSoftPi(), - candidate.impactParameterNormalised0(), - candidate.impactParameterNormalised1(), + impParameterNormalisedProng0, + impParameterNormalisedProng1, candidate.normalisedImpParamSoftPi(), prong0.tpcNSigmaPi(), prong0.tpcNSigmaKa(), @@ -385,17 +414,17 @@ struct HfTreeCreatorDstarToD0Pi { candidate.deltaIPNormalisedMaxD0(), candidate.impactParameterProductD0(), cosThetaD0, - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + pProng0, + pProng1, RecoDecay::p(candidate.pxSoftPi(), candidate.pySoftPi(), candidate.pzSoftPi()), - candidate.ptProng0(), - candidate.ptProng1(), + ptProng0, + ptProng1, candidate.ptSoftPi(), - candidate.impactParameter0(), - candidate.impactParameter1(), + impParameterProng0, + impParameterProng1, candidate.impParamSoftPi(), - candidate.impactParameterNormalised0(), - candidate.impactParameterNormalised1(), + impParameterNormalisedProng0, + impParameterNormalisedProng1, candidate.normalisedImpParamSoftPi(), candidate.errorImpactParameter0(), candidate.errorImpactParameter1(), @@ -457,7 +486,7 @@ struct HfTreeCreatorDstarToD0Pi { } for (const auto& candidate : candidates) { if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { continue; } @@ -498,7 +527,7 @@ struct HfTreeCreatorDstarToD0Pi { } for (const auto& candidate : reconstructedCandBkg) { if (downSampleBkgFactor < 1.) { - float pseudoRndm = candidate.ptProng0() * 1000. - (int64_t)(candidate.ptProng0() * 1000); + float pseudoRndm = candidate.ptProng0() * 1000. - static_cast(candidate.ptProng0() * 1000); if (candidate.pt() < ptMaxForDownSample && pseudoRndm >= downSampleBkgFactor) { continue; } diff --git a/PWGHF/Utils/utilsDerivedData.h b/PWGHF/Utils/utilsDerivedData.h new file mode 100644 index 00000000000..ad3bf57e25e --- /dev/null +++ b/PWGHF/Utils/utilsDerivedData.h @@ -0,0 +1,42 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file utilsDerivedData.h +/// \brief Utilities for derived-data creators +/// \author Vít Kučera , Inha University + +#ifndef PWGHF_UTILS_UTILSDERIVEDDATA_H_ +#define PWGHF_UTILS_UTILSDERIVEDDATA_H_ + +#include + +// Macro to store nSigma for prong _id_ with PID hypothesis _hyp_ in an array +#define GET_N_SIGMA_PRONG(_array_, _candidate_, _id_, _hyp_) \ + _array_[0] = _candidate_.nSigTpc##_hyp_##_id_(); \ + _array_[1] = _candidate_.nSigTof##_hyp_##_id_(); \ + _array_[2] = _candidate_.tpcTofNSigma##_hyp_##_id_(); + +namespace o2::analysis::hf_derived +{ +/// Reserve space in the filled table for all entries in the source table. +/// \param cursor cursor of the filled table +/// \param enabled switch for filling the table +/// \param size size of the source table +template +void reserveTable(T& cursor, const o2::framework::Configurable& enabled, const uint64_t size) +{ + if (enabled.value) { + cursor.reserve(size); + } +}; +} // namespace o2::analysis::hf_derived + +#endif // PWGHF_UTILS_UTILSDERIVEDDATA_H_ diff --git a/PWGHF/Utils/utilsPid.h b/PWGHF/Utils/utilsPid.h index c0cec3e0ce1..19325426cd6 100644 --- a/PWGHF/Utils/utilsPid.h +++ b/PWGHF/Utils/utilsPid.h @@ -17,15 +17,11 @@ #ifndef PWGHF_UTILS_UTILSPID_H_ #define PWGHF_UTILS_UTILSPID_H_ -namespace o2::aod +namespace o2::aod::pid_tpc_tof_utils { - -namespace pid_tpc_tof_utils -{ - -enum HfProngSpecies : int { Pion = 0, - Kaon, - Proton }; +enum HfProngSpecies : uint8_t { Pion = 0, + Kaon, + Proton }; /// Function to combine TPC and TOF NSigma /// \param tiny switch between full and tiny (binned) PID tables @@ -100,9 +96,6 @@ void fillProngPid(TRK const& track, ROW& rowPid) // fill candidate prong PID rows rowPid(nSigTpc, nSigTof); } - -} // namespace pid_tpc_tof_utils - -} // namespace o2::aod +} // namespace o2::aod::pid_tpc_tof_utils #endif // PWGHF_UTILS_UTILSPID_H_ diff --git a/PWGJE/Core/JetTaggingUtilities.h b/PWGJE/Core/JetTaggingUtilities.h index d6a4ee8f32b..8f5c44362e1 100644 --- a/PWGJE/Core/JetTaggingUtilities.h +++ b/PWGJE/Core/JetTaggingUtilities.h @@ -137,12 +137,13 @@ int jetTrackFromHFShower(T const& jet, U const& /*tracks*/, V const& particles, bool hasMcParticle = false; int origin = -1; for (auto& track : jet.template tracks_as()) { + hftrack = track; // for init if origin is 1 or 2, the track is not hftrack if (!track.has_mcParticle()) { continue; } hasMcParticle = true; auto const& particle = track.template mcParticle_as(); - origin = RecoDecay::getCharmHadronOrigin(particles, particle, searchUpToQuark); + origin = RecoDecay::getParticleOrigin(particles, particle, searchUpToQuark); if (origin == 1 || origin == 2) { // 1=charm , 2=beauty hftrack = track; if (origin == 1) { @@ -153,6 +154,7 @@ int jetTrackFromHFShower(T const& jet, U const& /*tracks*/, V const& particles, } } } + if (hasMcParticle) { return JetTaggingSpecies::lightflavour; } else { @@ -173,7 +175,8 @@ int jetParticleFromHFShower(T const& jet, U const& particles, typename U::iterat int origin = -1; for (const auto& particle : jet.template tracks_as()) { - origin = RecoDecay::getCharmHadronOrigin(particles, particle, searchUpToQuark); + hfparticle = particle; // for init if origin is 1 or 2, the particle is not hfparticle + origin = RecoDecay::getParticleOrigin(particles, particle, searchUpToQuark); if (origin == 1 || origin == 2) { // 1=charm , 2=beauty hfparticle = particle; if (origin == 1) { diff --git a/PWGJE/DataModel/EMCALClusters.h b/PWGJE/DataModel/EMCALClusters.h index 60bb583cfca..af97b559546 100644 --- a/PWGJE/DataModel/EMCALClusters.h +++ b/PWGJE/DataModel/EMCALClusters.h @@ -35,6 +35,9 @@ const EMCALClusterDefinition kV3Default(ClusterAlgorithm_t::kV3, 10, 1, "kV3Defa const EMCALClusterDefinition kV3MostSplit(ClusterAlgorithm_t::kV3, 11, 1, "kV3MostSplit", 0.5, 0.1, -10000, 10000, true, 0.); const EMCALClusterDefinition kV3LowSeed(ClusterAlgorithm_t::kV3, 12, 1, "kV3LowSeed", 0.3, 0.1, -10000, 10000, true, 0.03); const EMCALClusterDefinition kV3MostSplitLowSeed(ClusterAlgorithm_t::kV3, 13, 1, "kV3MostSplitLowSeed", 0.3, 0.1, -10000, 10000, true, 0.); +const EMCALClusterDefinition kV3StrictTime(ClusterAlgorithm_t::kV3, 20, 1, "kV3StrictTime", 0.5, 0.1, -500, 500, true, 0.03); +const EMCALClusterDefinition kV3StricterTime(ClusterAlgorithm_t::kV3, 21, 1, "kV3StricterTime", 0.5, 0.1, -100, 100, true, 0.03); +const EMCALClusterDefinition kV3MostStrictTime(ClusterAlgorithm_t::kV3, 22, 1, "kV3MostStrictTime", 0.5, 0.1, -50, 50, true, 0.03); /// \brief function returns EMCALClusterDefinition for the given name /// \param name name of the cluster definition @@ -55,6 +58,12 @@ const EMCALClusterDefinition getClusterDefinitionFromString(const std::string& c return kV3LowSeed; } else if (clusterDefinitionName == "kV3MostSplitLowSeed") { return kV3MostSplitLowSeed; + } else if (clusterDefinitionName == "kV3StrictTime") { + return kV3StrictTime; + } else if (clusterDefinitionName == "kV3StricterTime") { + return kV3StricterTime; + } else if (clusterDefinitionName == "kV3MostStrictTime") { + return kV3MostStrictTime; } else { throw std::invalid_argument("Cluster definition name not recognized"); } diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index 968e7b86e8c..111841890c8 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include "CCDB/BasicCCDBManager.h" #include "Framework/runDataProcessing.h" @@ -87,7 +90,7 @@ struct EmcalCorrectionTask { Configurable exoticCellInCrossMinAmplitude{"exoticCellInCrossMinAmplitude", 0.1, "Minimum energy of cells in cross, if lower not considered in cross"}; Configurable useWeightExotic{"useWeightExotic", false, "States if weights should be used for exotic cell cut"}; Configurable isMC{"isMC", false, "States if run over MC"}; - Configurable applyCellTimeShift{"applyCellTimeShift", 0, "apply shift to the cell time; 0 = off; 1 = const shift; 2 = eta-dependent shift"}; + Configurable applyCellTimeShift{"applyCellTimeShift", 0, "apply shift to the cell time for data and MC; For data: 0 = off; non-zero = log function extracted from data - For MC: 0 = off; 1 = const shift; 2 = eta-dependent shift"}; // Require EMCAL cells (CALO type 1) Filter emccellfilter = aod::calo::caloType == selectedCellType; @@ -264,7 +267,7 @@ struct EmcalCorrectionTask { } cellsBC.emplace_back(cell.cellNumber(), amplitude, - cell.time() + getCellTimeShift(cell.cellNumber()), + cell.time() + getCellTimeShift(cell.cellNumber(), amplitude), o2::emcal::intToChannelType(cell.cellType())); cellIndicesBC.emplace_back(cell.globalIndex()); } @@ -383,7 +386,7 @@ struct EmcalCorrectionTask { } cellsBC.emplace_back(cell.cellNumber(), amplitude, - cell.time() + getCellTimeShift(cell.cellNumber()), + cell.time() + getCellTimeShift(cell.cellNumber(), amplitude), o2::emcal::intToChannelType(cell.cellType())); cellIndicesBC.emplace_back(cell.globalIndex()); cellLabels.emplace_back(cell.mcParticleIds(), cell.amplitudeA()); @@ -485,7 +488,7 @@ struct EmcalCorrectionTask { for (auto& cell : cellsInBC) { cellsBC.emplace_back(cell.cellNumber(), cell.amplitude(), - cell.time() + getCellTimeShift(cell.cellNumber()), + cell.time() + getCellTimeShift(cell.cellNumber(), cell.amplitude()), o2::emcal::intToChannelType(cell.cellType())); cellIndicesBC.emplace_back(cell.globalIndex()); } @@ -790,9 +793,10 @@ struct EmcalCorrectionTask { } } - // Apply shift of the cell time - // This has to be done to shift the cell time in MC (which is not calibrated to 0 due to the flight time of the particles to the EMCal surface (~15ns)) - float getCellTimeShift(const int16_t cellID) + // Apply shift of the cell time in data and MC + // In MC this has to be done to shift the cell time, which is not calibrated to 0 due to the flight time of the particles to the EMCal surface (~15ns) + // In data this is done to correct for the time walk effect + float getCellTimeShift(const int16_t cellID, const float cellEnergy) { if (isMC) { if (applyCellTimeShift == 1) { // constant shift @@ -810,7 +814,16 @@ struct EmcalCorrectionTask { return 0.f; } } else { // data - return 0.f; + if (applyCellTimeShift != 0) { + if (cellEnergy < 0.3) // Cells with tless than 300 MeV cannot be the leading cell in the cluster, so their time does not require precise calibration + return 0.f; + else if (cellEnergy < 4.) // Low energy regime + return (0.57284 + 0.82194 * TMath::Log(1.30651 * cellEnergy)); // Parameters extracted from LHC22o (pp), but also usable for other periods + else // High energy regime + return (-0.05858 + 1.50593 * TMath::Log(0.97591 * cellEnergy)); // Parameters extracted from LHC22o (pp), but also usable for other periods + } else { // Dont apply cell time shift if applyCellTimeShift == 0 + return 0.f; + } } } }; diff --git a/PWGJE/TableProducer/jetderiveddatawriter.cxx b/PWGJE/TableProducer/jetderiveddatawriter.cxx index 9b09530ce57..eb5858184da 100644 --- a/PWGJE/TableProducer/jetderiveddatawriter.cxx +++ b/PWGJE/TableProducer/jetderiveddatawriter.cxx @@ -151,7 +151,7 @@ struct JetDerivedDataWriter { Preslice D0sPerCollision = aod::jd0indices::collisionId; Preslice LcsPerCollision = aod::jlcindices::collisionId; Preslice DielectronsPerCollision = aod::jdielectronindices::collisionId; - Preslice EMCTrackPerTrack = aod::jemctrack::trackId; + PresliceUnsorted EMCTrackPerTrack = aod::jemctrack::trackId; std::vector collisionFlag; std::vector McCollisionFlag; diff --git a/PWGJE/Tasks/PhotonIsolationQA.cxx b/PWGJE/Tasks/PhotonIsolationQA.cxx index 2d21b63d508..03b8e4f1fe6 100644 --- a/PWGJE/Tasks/PhotonIsolationQA.cxx +++ b/PWGJE/Tasks/PhotonIsolationQA.cxx @@ -142,7 +142,7 @@ struct PhotonIsolationQA { Data_Info.add("hEvsPtIso", "Pt_Iso", o2HistType::kTH2F, {{Energy_Axis}, {PtIso_Axis}}); Data_Info.add("hRho_Perpen_Cone", "Energy vs Density of perpendicular cone", o2HistType::kTH2F, {{Energy_Axis}, {Rho_Axis}}); Data_Info.add("hShowerShape", "Shower shape", o2HistType::kTH2F, {{Shower_Shape_Long_Axis}, {Shower_Shape_Short_Axis}}); - Data_Info.add("hSigmaLongvsPtIso", "Long shower shape vs Pt_Iso", o2HistType::kTH2F, {{Shower_Shape_Long_Axis}, {PtIso_Axis}}); + Data_Info.add("hSigmaLongvsPtIso", "Long shower shape vs Pt_Iso", o2HistType::kTH3F, {{Shower_Shape_Long_Axis}, {PtIso_Axis}, {Energy_Axis}}); Data_Info.add("hABCDControlRegion", "Yield Control Regions", o2HistType::kTH2F, {{ABCD_Axis}, {Energy_Axis}}); Data_Info.add("hCollperBC", "collisions per BC", o2HistType::kTH1F, {BC_Axis}); Data_Info.add("hEnergy_NLM_Flag", "Energy vs NLM", o2HistType::kTH3F, {{Energy_Axis}, {NLM_Axis}, {SM_Flag_Axis}}); @@ -493,7 +493,7 @@ struct PhotonIsolationQA { Data_Info.fill(HIST("hEvsPtIso"), cluster.energy(), Pt_iso); Data_Info.fill(HIST("hRho_Perpen_Cone"), cluster.energy(), Rho_Perpen_Cone); - Data_Info.fill(HIST("hSigmaLongvsPtIso"), cluster.m02(), Pt_iso); + Data_Info.fill(HIST("hSigmaLongvsPtIso"), cluster.m02(), Pt_iso, cluster.energy()); fillABCDHisto(Data_Info, cluster, Pt_iso); } } diff --git a/PWGJE/Tasks/bjetTaggingML.cxx b/PWGJE/Tasks/bjetTaggingML.cxx index e1e9d9e03d0..42f385a5c48 100644 --- a/PWGJE/Tasks/bjetTaggingML.cxx +++ b/PWGJE/Tasks/bjetTaggingML.cxx @@ -114,7 +114,7 @@ struct BJetTaggingML { Configurable> binsPtMl{"binsPtMl", std::vector{5., 1000.}, "pT bin limits for ML application"}; Configurable> cutDirMl{"cutDirMl", std::vector{cuts_ml::CutSmaller, cuts_ml::CutNot}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsMl{"cutsMl", {defaultCutsMl[0], 1, 2, {"pT bin 0"}, {"score for default b-jet tagging", "uncer 1"}}, "ML selections per pT bin"}; - Configurable nClassesMl{"nClassesMl", (int8_t)2, "Number of classes in ML model"}; + Configurable nClassesMl{"nClassesMl", 2, "Number of classes in ML model"}; Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; diff --git a/PWGJE/Tasks/emcclustermonitor.cxx b/PWGJE/Tasks/emcclustermonitor.cxx index 1fc741ec410..bbf29d344e7 100644 --- a/PWGJE/Tasks/emcclustermonitor.cxx +++ b/PWGJE/Tasks/emcclustermonitor.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -75,6 +76,7 @@ struct ClusterMonitor { std::vector mVetoBCIDs; std::vector mSelectBCIDs; + std::vector mCellTime; /// \brief Create output histograms and initialize geometry void init(InitContext const&) @@ -94,6 +96,8 @@ struct ClusterMonitor { const o2Axis supermoduleAxis{20, -0.5, 19.5, "Supermodule ID"}; o2Axis timeAxis{mClusterTimeBinning, "t_{cl} (ns)"}; o2Axis numberClustersAxis{mNumberClusterBinning, "Number of clusters / event"}; + const AxisSpec thAxisCellTimeDiff{3000, -1500, 1500, "#Delta#it{t}_{cell} (ns)"}; + const AxisSpec thAxisCellTimeMean{1500, -600, 900, "#LT#it{t}_{cell}#GT (ns)"}; // event properties mHistManager.add("eventsAll", "Number of events", o2HistType::kTH1F, {{1, 0.5, 1.5}}); @@ -121,6 +125,8 @@ struct ClusterMonitor { mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100}}); mHistManager.add("clusterTimeVsE", "Cluster time vs energy", o2HistType::kTH2F, {timeAxis, energyAxis}); mHistManager.add("clusterAmpFractionLeadingCell", "Fraction of energy in leading cell", o2HistType::kTH1F, {{100, 0, 1}}); + mHistManager.add("clusterCellTimeDiff", "Cell time difference in clusters", o2HistType::kTH1D, {thAxisCellTimeDiff}); + mHistManager.add("clusterCellTimeMean", "Mean cell time per cluster", o2HistType::kTH1D, {thAxisCellTimeMean}); // add histograms per supermodule for (int ism = 0; ism < 20; ++ism) { @@ -238,12 +244,21 @@ struct ClusterMonitor { auto cellsofcluster = emccluscells.sliceBy(perCluster, cluster.globalIndex()); double maxamp = 0; double ampfraction = 0; + mCellTime.clear(); + mCellTime.reserve(cellsofcluster.size()); for (const auto& cell : cellsofcluster) { // example how to get any information of the cell associated with cluster LOG(debug) << "Cell ID:" << cell.calo().amplitude() << " Time " << cell.calo().time(); if (cell.calo().amplitude() > maxamp) { maxamp = cell.calo().amplitude(); } + mCellTime.push_back(cell.calo().time()); + } // end of loop over cells + mHistManager.fill(HIST("clusterCellTimeMean"), std::accumulate(mCellTime.begin(), mCellTime.end(), 0.0f) / mCellTime.size()); + for (int iCell1 = 0; iCell1 < mCellTime.size() - 1; iCell1++) { + for (int iCell2 = iCell1 + 1; iCell2 < mCellTime.size(); iCell2++) { + mHistManager.fill(HIST("clusterCellTimeDiff"), mCellTime[iCell1] - mCellTime[iCell2]); + } } ampfraction = maxamp / cluster.energy(); mHistManager.fill(HIST("clusterAmpFractionLeadingCell"), ampfraction); diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index 65da4f3ded7..df4569a415e 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -14,6 +14,7 @@ // Authors: Daniel Jones #include +#include #include "TRandom3.h" @@ -62,6 +63,7 @@ struct hJetAnalysis { Configurable pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; + Configurable triggerMasks{"triggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; Preslice> PartJetsPerCollision = aod::jet::mcCollisionId; @@ -123,6 +125,7 @@ struct hJetAnalysis { int eventSelection = -1; int trackSelection = -1; + std::vector triggerMaskBits; Service pdg; @@ -130,6 +133,7 @@ struct hJetAnalysis { { eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); + triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); Filter jetCuts = aod::jet::r == nround(jetR.node() * 100.0f); Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); @@ -430,6 +434,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); fillHistograms(jets, jetsWTA, tracks); } @@ -443,6 +450,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); fillHistograms(jets, jetsWTA, tracks); } @@ -457,6 +467,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ(), collision.mcCollision().weight()); fillHistograms(jets, jetsWTA, tracks, collision.mcCollision().weight()); } @@ -500,6 +513,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); for (const auto& mcdjet : mcdjets) { @@ -520,6 +536,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); for (const auto& mcdjet : mcdjets) { @@ -540,6 +559,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); bool ishJetEvent = false; @@ -569,6 +591,9 @@ struct hJetAnalysis { if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(PartJetsPerCollision, collision.mcCollisionId()); bool ishJetEvent = false; diff --git a/PWGJE/Tasks/jetchargedv2.cxx b/PWGJE/Tasks/jetchargedv2.cxx index c3645ec47aa..01184740f28 100644 --- a/PWGJE/Tasks/jetchargedv2.cxx +++ b/PWGJE/Tasks/jetchargedv2.cxx @@ -246,7 +246,7 @@ struct Jetchargedv2Task { AxisSpec axisEvtPl{360, -constants::math::PI, constants::math::PI}; histosQA.add("histCentFull", "Centrality distribution for valid events", HistType::kTH1F, {axisCent}); - for (auto i = 0; i < cfgnMods->size(); i++) { + for (std::size_t i = 0; i < cfgnMods->size(); i++) { histosQA.add(Form("histQvecUncorV%d", cfgnMods->at(i)), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); histosQA.add(Form("histQvecRectrV%d", cfgnMods->at(i)), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); histosQA.add(Form("histQvecTwistV%d", cfgnMods->at(i)), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); @@ -351,7 +351,7 @@ struct Jetchargedv2Task { soa::Join const& jets, aod::JetTracks const& tracks) { - double collnum = 1; + // double collnum = 1; for (const auto& collision : collisions) { double leadingJetPt = -1; double leadingJetPhi = -1; @@ -370,7 +370,7 @@ struct Jetchargedv2Task { } //=====================< evt pln [n=2->\Psi_2, n=3->\Psi_3] >=====================// - for (auto i = 0; i < cfgnMods->size(); i++) { + for (std::size_t i = 0; i < cfgnMods->size(); i++) { int nmode = cfgnMods->at(i); int DetInd = DetId * 4 + cfgnTotalSystem * 4 * (nmode - 2); if (nmode == 2) { @@ -412,8 +412,8 @@ struct Jetchargedv2Task { continue; } phiMinusPsi2 = jet.phi() - evtPl2; - Double_t jetPtCorr = 0.0; - jetPtCorr = jet.pt() - collision.rho() * jet.area(); + // Double_t jetPtCorr = 0.0; + // jetPtCorr = jet.pt() - collision.rho() * jet.area(); if ((phiMinusPsi2 < TMath::Pi() / 4) || (phiMinusPsi2 >= 7 * TMath::Pi() / 4) || (phiMinusPsi2 >= 3 * TMath::Pi() / 4 && phiMinusPsi2 < 5 * TMath::Pi() / 4)) { registry.fill(HIST("h_jet_pt_in_plane_v2"), jet.pt() - (collision.rho() * jet.area()), 1.0); @@ -435,8 +435,8 @@ struct Jetchargedv2Task { continue; } phiMinusPsi3 = jet.phi() - evtPl3; - Double_t jetPtCorr = 0.0; - jetPtCorr = jet.pt() - collision.rho() * jet.area(); + // Double_t jetPtCorr = 0.0; + // jetPtCorr = jet.pt() - collision.rho() * jet.area(); if ((phiMinusPsi3 < TMath::Pi() / 4) || (phiMinusPsi3 >= 7 * TMath::Pi() / 4) || (phiMinusPsi3 >= 3 * TMath::Pi() / 4 && phiMinusPsi3 < 5 * TMath::Pi() / 4)) { registry.fill(HIST("h_jet_pt_in_plane_v3"), jet.pt() - (collision.rho() * jet.area()), 1.0); @@ -475,7 +475,7 @@ struct Jetchargedv2Task { return; } - for (auto i = 0; i < cfgnMods->size(); i++) { + for (std::size_t i = 0; i < cfgnMods->size(); i++) { TRandom3 randomNumber(0); float randomConeEta = randomNumber.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); float randomConePhi = randomNumber.Uniform(0.0, 2 * M_PI); diff --git a/PWGLF/DataModel/LFNonPromptCascadeTables.h b/PWGLF/DataModel/LFNonPromptCascadeTables.h index 4bdca4b9c97..0208c7c027c 100644 --- a/PWGLF/DataModel/LFNonPromptCascadeTables.h +++ b/PWGLF/DataModel/LFNonPromptCascadeTables.h @@ -29,6 +29,7 @@ DECLARE_SOA_COLUMN(ITSClusSize, itsClusSize, float); DECLARE_SOA_COLUMN(IsGoodMatch, isGoodMatch, bool); DECLARE_SOA_COLUMN(IsGoodCascade, isGoodCascade, bool); DECLARE_SOA_COLUMN(PdgCodeMom, pdgCodeMom, int); +DECLARE_SOA_COLUMN(PdgCodeITStrack, pdgCodeITStrack, int); DECLARE_SOA_COLUMN(IsFromBeauty, isFromBeauty, bool); DECLARE_SOA_COLUMN(IsFromCharm, isFromCharm, bool); @@ -165,6 +166,7 @@ DECLARE_SOA_TABLE(NPCascTableMC, "AOD", "NPCASCTABLEMC", NPCascadeTable::IsGoodMatch, NPCascadeTable::IsGoodCascade, NPCascadeTable::PdgCodeMom, + NPCascadeTable::PdgCodeITStrack, NPCascadeTable::IsFromBeauty, NPCascadeTable::IsFromCharm, NPCascadeTable::PvX, diff --git a/PWGLF/DataModel/LFResonanceTables.h b/PWGLF/DataModel/LFResonanceTables.h index 609137d3b16..195acbacaa9 100644 --- a/PWGLF/DataModel/LFResonanceTables.h +++ b/PWGLF/DataModel/LFResonanceTables.h @@ -136,24 +136,24 @@ DECLARE_SOA_COLUMN(CascTransRadius, casctransRadius, float); //! DECLARE_SOA_COLUMN(DecayVtxX, decayVtxX, float); //! X position of the decay vertex DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay vertex DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex -DECLARE_SOA_COLUMN(DaughterTPCNSigmaPi1, daughterTPCNSigmaPi1, float); //! TPC PID of the first daughter as Pion -DECLARE_SOA_COLUMN(DaughterTPCNSigmaKa1, daughterTPCNSigmaKa1, float); //! TPC PID of the first daughter as Kaon -DECLARE_SOA_COLUMN(DaughterTPCNSigmaPr1, daughterTPCNSigmaPr1, float); //! TPC PID of the first daughter as Proton -DECLARE_SOA_COLUMN(DaughterTPCNSigmaPi2, daughterTPCNSigmaPi2, float); //! TPC PID of the second daughter as Pion -DECLARE_SOA_COLUMN(DaughterTPCNSigmaKa2, daughterTPCNSigmaKa2, float); //! TPC PID of the second daughter as Kaon -DECLARE_SOA_COLUMN(DaughterTPCNSigmaPr2, daughterTPCNSigmaPr2, float); //! TPC PID of the second daughter as Proton -DECLARE_SOA_COLUMN(DaughterTPCNSigmaPiBach, daughterTPCNSigmaPiBach, float); //! TPC PID of the bachelor daughter as Pion -DECLARE_SOA_COLUMN(DaughterTPCNSigmaKaBach, daughterTPCNSigmaKaBach, float); //! TPC PID of the bachelor daughter as Kaon -DECLARE_SOA_COLUMN(DaughterTPCNSigmaPrBach, daughterTPCNSigmaPrBach, float); //! TPC PID of the bachelor daughter as Proton -DECLARE_SOA_COLUMN(DaughterTOFNSigmaPi1, daughterTOFNSigmaPi1, float); //! TOF PID of the first daughter as Pion -DECLARE_SOA_COLUMN(DaughterTOFNSigmaKa1, daughterTOFNSigmaKa1, float); //! TOF PID of the first daughter as Kaon -DECLARE_SOA_COLUMN(DaughterTOFNSigmaPr1, daughterTOFNSigmaPr1, float); //! TOF PID of the first daughter as Proton -DECLARE_SOA_COLUMN(DaughterTOFNSigmaPi2, daughterTOFNSigmaPi2, float); //! TOF PID of the second daughter as Pion -DECLARE_SOA_COLUMN(DaughterTOFNSigmaKa2, daughterTOFNSigmaKa2, float); //! TOF PID of the second daughter as Kaon -DECLARE_SOA_COLUMN(DaughterTOFNSigmaPr2, daughterTOFNSigmaPr2, float); //! TOF PID of the second daughter as Proton -DECLARE_SOA_COLUMN(DaughterTOFNSigmaPiBach, daughterTOFNSigmaPiBach, float); //! TOF PID of the bachelor daughter as Pion -DECLARE_SOA_COLUMN(DaughterTOFNSigmaKaBach, daughterTOFNSigmaKaBach, float); //! TOF PID of the bachelor daughter as Kaon -DECLARE_SOA_COLUMN(DaughterTOFNSigmaPrBach, daughterTOFNSigmaPrBach, float); //! TOF PID of the bachelor daughter as Proton +DECLARE_SOA_COLUMN(DaughterTPCNSigmaPosPi, daughterTPCNSigmaPosPi, float); //! TPC PID of the positive daughter as Pion +DECLARE_SOA_COLUMN(DaughterTPCNSigmaPosKa, daughterTPCNSigmaPosKa, float); //! TPC PID of the positive daughter as Kaon +DECLARE_SOA_COLUMN(DaughterTPCNSigmaPosPr, daughterTPCNSigmaPosPr, float); //! TPC PID of the positive daughter as Proton +DECLARE_SOA_COLUMN(DaughterTPCNSigmaNegPi, daughterTPCNSigmaNegPi, float); //! TPC PID of the negative daughter as Pion +DECLARE_SOA_COLUMN(DaughterTPCNSigmaNegKa, daughterTPCNSigmaNegKa, float); //! TPC PID of the negative daughter as Kaon +DECLARE_SOA_COLUMN(DaughterTPCNSigmaNegPr, daughterTPCNSigmaNegPr, float); //! TPC PID of the negative daughter as Proton +DECLARE_SOA_COLUMN(DaughterTPCNSigmaBachPi, daughterTPCNSigmaBachPi, float); //! TPC PID of the bachelor daughter as Pion +DECLARE_SOA_COLUMN(DaughterTPCNSigmaBachKa, daughterTPCNSigmaBachKa, float); //! TPC PID of the bachelor daughter as Kaon +DECLARE_SOA_COLUMN(DaughterTPCNSigmaBachPr, daughterTPCNSigmaBachPr, float); //! TPC PID of the bachelor daughter as Proton +DECLARE_SOA_COLUMN(DaughterTOFNSigmaPosPi, daughterTOFNSigmaPosPi, float); //! TOF PID of the positive daughter as Pion +DECLARE_SOA_COLUMN(DaughterTOFNSigmaPosKa, daughterTOFNSigmaPosKa, float); //! TOF PID of the positive daughter as Kaon +DECLARE_SOA_COLUMN(DaughterTOFNSigmaPosPr, daughterTOFNSigmaPosPr, float); //! TOF PID of the positive daughter as Proton +DECLARE_SOA_COLUMN(DaughterTOFNSigmaNegPi, daughterTOFNSigmaNegPi, float); //! TOF PID of the negative daughter as Pion +DECLARE_SOA_COLUMN(DaughterTOFNSigmaNegKa, daughterTOFNSigmaNegKa, float); //! TOF PID of the negative daughter as Kaon +DECLARE_SOA_COLUMN(DaughterTOFNSigmaNegPr, daughterTOFNSigmaNegPr, float); //! TOF PID of the negative daughter as Proton +DECLARE_SOA_COLUMN(DaughterTOFNSigmaBachPi, daughterTOFNSigmaBachPi, float); //! TOF PID of the bachelor daughter as Pion +DECLARE_SOA_COLUMN(DaughterTOFNSigmaBachKa, daughterTOFNSigmaBachKa, float); //! TOF PID of the bachelor daughter as Kaon +DECLARE_SOA_COLUMN(DaughterTOFNSigmaBachPr, daughterTOFNSigmaBachPr, float); //! TOF PID of the bachelor daughter as Proton // For MC DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! Index of the corresponding MC particle DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, bool); @@ -218,18 +218,18 @@ DECLARE_SOA_TABLE(ResoV0s, "AOD", "RESOV0S", resodaughter::Eta, resodaughter::Phi, resodaughter::Indices, - resodaughter::DaughterTPCNSigmaPi1, - resodaughter::DaughterTPCNSigmaKa1, - resodaughter::DaughterTPCNSigmaPr1, - resodaughter::DaughterTPCNSigmaPi2, - resodaughter::DaughterTPCNSigmaKa2, - resodaughter::DaughterTPCNSigmaPr2, - resodaughter::DaughterTOFNSigmaPi1, - resodaughter::DaughterTOFNSigmaKa1, - resodaughter::DaughterTOFNSigmaPr1, - resodaughter::DaughterTOFNSigmaPi2, - resodaughter::DaughterTOFNSigmaKa2, - resodaughter::DaughterTOFNSigmaPr2, + resodaughter::DaughterTPCNSigmaPosPi, + resodaughter::DaughterTPCNSigmaPosKa, + resodaughter::DaughterTPCNSigmaPosPr, + resodaughter::DaughterTPCNSigmaNegPi, + resodaughter::DaughterTPCNSigmaNegKa, + resodaughter::DaughterTPCNSigmaNegPr, + resodaughter::DaughterTOFNSigmaPosPi, + resodaughter::DaughterTOFNSigmaPosKa, + resodaughter::DaughterTOFNSigmaPosPr, + resodaughter::DaughterTOFNSigmaNegPi, + resodaughter::DaughterTOFNSigmaNegKa, + resodaughter::DaughterTOFNSigmaNegPr, resodaughter::V0CosPA, resodaughter::DaughDCA, v0data::DCAPosToPV, @@ -254,24 +254,24 @@ DECLARE_SOA_TABLE(ResoCascades, "AOD", "RESOCASCADES", resodaughter::Eta, resodaughter::Phi, resodaughter::CascadeIndices, - resodaughter::DaughterTPCNSigmaPi1, - resodaughter::DaughterTPCNSigmaKa1, - resodaughter::DaughterTPCNSigmaPr1, - resodaughter::DaughterTPCNSigmaPi2, - resodaughter::DaughterTPCNSigmaKa2, - resodaughter::DaughterTPCNSigmaPr2, - resodaughter::DaughterTPCNSigmaPiBach, - resodaughter::DaughterTPCNSigmaKaBach, - resodaughter::DaughterTPCNSigmaPrBach, - resodaughter::DaughterTOFNSigmaPi1, - resodaughter::DaughterTOFNSigmaKa1, - resodaughter::DaughterTOFNSigmaPr1, - resodaughter::DaughterTOFNSigmaPi2, - resodaughter::DaughterTOFNSigmaKa2, - resodaughter::DaughterTOFNSigmaPr2, - resodaughter::DaughterTOFNSigmaPiBach, - resodaughter::DaughterTOFNSigmaKaBach, - resodaughter::DaughterTOFNSigmaPrBach, + resodaughter::DaughterTPCNSigmaPosPi, + resodaughter::DaughterTPCNSigmaPosKa, + resodaughter::DaughterTPCNSigmaPosPr, + resodaughter::DaughterTPCNSigmaNegPi, + resodaughter::DaughterTPCNSigmaNegKa, + resodaughter::DaughterTPCNSigmaNegPr, + resodaughter::DaughterTPCNSigmaBachPi, + resodaughter::DaughterTPCNSigmaBachKa, + resodaughter::DaughterTPCNSigmaBachPr, + resodaughter::DaughterTOFNSigmaPosPi, + resodaughter::DaughterTOFNSigmaPosKa, + resodaughter::DaughterTOFNSigmaPosPr, + resodaughter::DaughterTOFNSigmaNegPi, + resodaughter::DaughterTOFNSigmaNegKa, + resodaughter::DaughterTOFNSigmaNegPr, + resodaughter::DaughterTOFNSigmaBachPi, + resodaughter::DaughterTOFNSigmaBachKa, + resodaughter::DaughterTOFNSigmaBachPr, resodaughter::V0CosPA, resodaughter::CascCosPA, resodaughter::DaughDCA, diff --git a/PWGLF/DataModel/LFSigmaTables.h b/PWGLF/DataModel/LFSigmaTables.h index 136f000316f..01ef1354162 100644 --- a/PWGLF/DataModel/LFSigmaTables.h +++ b/PWGLF/DataModel/LFSigmaTables.h @@ -45,12 +45,18 @@ namespace sigma0Core DECLARE_SOA_COLUMN(SigmapT, sigmapT, float); DECLARE_SOA_COLUMN(SigmaMass, sigmaMass, float); DECLARE_SOA_COLUMN(SigmaRapidity, sigmaRapidity, float); +DECLARE_SOA_COLUMN(SigmaOPAngle, sigmaOPAngle, float); +DECLARE_SOA_COLUMN(SigmaDeltaEta, sigmaDeltaEta, float); +DECLARE_SOA_COLUMN(SigmaDeltaPhi, sigmaDeltaPhi, float); } // namespace sigma0Core DECLARE_SOA_TABLE(Sigma0Cores, "AOD", "SIGMA0CORES", sigma0Core::SigmapT, sigma0Core::SigmaMass, - sigma0Core::SigmaRapidity); + sigma0Core::SigmaRapidity, + sigma0Core::SigmaOPAngle, + sigma0Core::SigmaDeltaEta, + sigma0Core::SigmaDeltaPhi); DECLARE_SOA_TABLE(Sigma0CollRefs, "AOD", "SIGMA0COLLREF", //! optional table to refer back to a collision o2::soa::Index<>, sigma0Core::Sigma0CollisionId); @@ -70,6 +76,7 @@ DECLARE_SOA_COLUMN(PhotonDCAPosPV, photonDCAPosPV, float); DECLARE_SOA_COLUMN(PhotonZconv, photonZconv, float); DECLARE_SOA_COLUMN(PhotonEta, photonEta, float); DECLARE_SOA_COLUMN(PhotonY, photonY, float); +DECLARE_SOA_COLUMN(PhotonPhi, photonPhi, float); DECLARE_SOA_COLUMN(PhotonPosTPCNSigma, photonPosTPCNSigma, float); DECLARE_SOA_COLUMN(PhotonNegTPCNSigma, photonNegTPCNSigma, float); DECLARE_SOA_COLUMN(PhotonPosTPCCrossedRows, photonPosTPCCrossedRows, uint8_t); @@ -103,6 +110,7 @@ DECLARE_SOA_TABLE(SigmaPhotonExtras, "AOD", "SIGMA0PHOTON", sigmaPhotonExtra::PhotonZconv, sigmaPhotonExtra::PhotonEta, sigmaPhotonExtra::PhotonY, + sigmaPhotonExtra::PhotonPhi, sigmaPhotonExtra::PhotonPosTPCNSigma, sigmaPhotonExtra::PhotonNegTPCNSigma, sigmaPhotonExtra::PhotonPosTPCCrossedRows, @@ -136,10 +144,15 @@ DECLARE_SOA_COLUMN(LambdaDCANegPV, lambdaDCANegPV, float); DECLARE_SOA_COLUMN(LambdaDCAPosPV, lambdaDCAPosPV, float); DECLARE_SOA_COLUMN(LambdaEta, lambdaEta, float); DECLARE_SOA_COLUMN(LambdaY, lambdaY, float); +DECLARE_SOA_COLUMN(LambdaPhi, lambdaPhi, float); DECLARE_SOA_COLUMN(LambdaPosPrTPCNSigma, lambdaPosPrTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaPosPiTPCNSigma, lambdaPosPiTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaNegPrTPCNSigma, lambdaNegPrTPCNSigma, float); DECLARE_SOA_COLUMN(LambdaNegPiTPCNSigma, lambdaNegPiTPCNSigma, float); +DECLARE_SOA_COLUMN(LambdaPrTOFNSigma, lambdaPrTOFNSigma, float); +DECLARE_SOA_COLUMN(LambdaPiTOFNSigma, lambdaPiTOFNSigma, float); +DECLARE_SOA_COLUMN(ALambdaPrTOFNSigma, aLambdaPrTOFNSigma, float); +DECLARE_SOA_COLUMN(ALambdaPiTOFNSigma, aLambdaPiTOFNSigma, float); DECLARE_SOA_COLUMN(LambdaPosTPCCrossedRows, lambdaPosTPCCrossedRows, uint8_t); DECLARE_SOA_COLUMN(LambdaNegTPCCrossedRows, lambdaNegTPCCrossedRows, uint8_t); DECLARE_SOA_COLUMN(LambdaPosPt, lambdaPosPt, float); @@ -173,10 +186,15 @@ DECLARE_SOA_TABLE(SigmaLambdaExtras, "AOD", "SIGMA0LAMBDA", sigmaLambdaExtra::LambdaDCAPosPV, sigmaLambdaExtra::LambdaEta, sigmaLambdaExtra::LambdaY, + sigmaLambdaExtra::LambdaPhi, sigmaLambdaExtra::LambdaPosPrTPCNSigma, sigmaLambdaExtra::LambdaPosPiTPCNSigma, sigmaLambdaExtra::LambdaNegPrTPCNSigma, sigmaLambdaExtra::LambdaNegPiTPCNSigma, + sigmaLambdaExtra::LambdaPrTOFNSigma, + sigmaLambdaExtra::LambdaPiTOFNSigma, + sigmaLambdaExtra::ALambdaPrTOFNSigma, + sigmaLambdaExtra::ALambdaPiTOFNSigma, sigmaLambdaExtra::LambdaPosTPCCrossedRows, sigmaLambdaExtra::LambdaNegTPCCrossedRows, sigmaLambdaExtra::LambdaPosPt, @@ -198,14 +216,26 @@ DECLARE_SOA_TABLE(SigmaLambdaExtras, "AOD", "SIGMA0LAMBDA", // for MC data namespace sigmaMCCore { -DECLARE_SOA_COLUMN(IsSigma, isSigma, bool); +DECLARE_SOA_COLUMN(IsSigma, isSigma, bool); // TODO: include PDG + IsPhysicalPrimary DECLARE_SOA_COLUMN(IsAntiSigma, isAntiSigma, bool); +DECLARE_SOA_COLUMN(PhotonCandPDGCode, photonCandPDGCode, int); +DECLARE_SOA_COLUMN(PhotonCandPDGCodeMother, photonCandPDGCodeMother, int); +DECLARE_SOA_COLUMN(IsPhotonCandPrimary, isPhotonCandPrimary, bool); +DECLARE_SOA_COLUMN(LambdaCandPDGCode, lambdaCandPDGCode, int); +DECLARE_SOA_COLUMN(LambdaCandPDGCodeMother, lambdaCandPDGCodeMother, int); +DECLARE_SOA_COLUMN(IsLambdaCandPrimary, isLambdaCandPrimary, bool); } // namespace sigmaMCCore DECLARE_SOA_TABLE(SigmaMCCores, "AOD", "SIGMA0MCCORES", sigmaMCCore::IsSigma, - sigmaMCCore::IsAntiSigma); + sigmaMCCore::IsAntiSigma, + sigmaMCCore::PhotonCandPDGCode, + sigmaMCCore::PhotonCandPDGCodeMother, + sigmaMCCore::IsPhotonCandPrimary, + sigmaMCCore::LambdaCandPDGCode, + sigmaMCCore::LambdaCandPDGCodeMother, + sigmaMCCore::IsLambdaCandPrimary); } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSIGMATABLES_H_ diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index a9ad398c043..fc7f3b950d7 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -22,6 +22,7 @@ #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/McCollisionExtra.h" #include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGLF/DataModel/SPCalibrationTables.h" #include "PWGUD/DataModel/UDTables.h" namespace o2::aod @@ -221,6 +222,8 @@ DECLARE_SOA_TABLE(StraTPCQVs, "AOD", "STRATPCQVS", //! tpc Qvec qvec::QvecBPosRe, qvec::QvecBPosIm, epcalibrationtable::QTPCR); DECLARE_SOA_TABLE(StraFT0CQVsEv, "AOD", "STRAFT0CQVSEv", //! events used to compute t0c Qvec epcalibrationtable::TriggerEventEP); +DECLARE_SOA_TABLE(StraZDCSP, "AOD", "STRAZDCSP", //! events used to compute the ZDC spectator plane + spcalibrationtable::TriggerEventSP, spcalibrationtable::PsiZDCA, spcalibrationtable::PsiZDCC); DECLARE_SOA_TABLE(StraStamps, "AOD", "STRASTAMPS", //! information for ID-ing mag field if needed bc::RunNumber, timestamp::Timestamp); @@ -232,9 +235,14 @@ using StraCent = StraCents::iterator; //______________________________________________________ // for correlating information with MC // also allows for collision association cross-checks -DECLARE_SOA_TABLE(StraMCCollisions, "AOD", "STRAMCCOLLISION", //! MC collision properties +DECLARE_SOA_TABLE(StraMCCollisions_000, "AOD", "STRAMCCOLLISION", //! MC collision properties o2::soa::Index<>, mccollision::PosX, mccollision::PosY, mccollision::PosZ, mccollision::ImpactParameter); +DECLARE_SOA_TABLE_VERSIONED(StraMCCollisions_001, "AOD", "STRAMCCOLLISION", 1, //! debug information + o2::soa::Index<>, mccollision::PosX, mccollision::PosY, mccollision::PosZ, + mccollision::ImpactParameter, mccollision::EventPlaneAngle); +using StraMCCollisions = StraMCCollisions_001; + DECLARE_SOA_TABLE(StraMCCollMults, "AOD", "STRAMCCOLLMULTS", //! MC collision multiplicities mult::MultMCFT0A, mult::MultMCFT0C, mult::MultMCNParticlesEta05, mult::MultMCNParticlesEta08, mult::MultMCNParticlesEta10, o2::soa::Marker<2>); diff --git a/PWGLF/DataModel/LFhe3HadronTables.h b/PWGLF/DataModel/LFhe3HadronTables.h index eb923a31746..9074fb8b20c 100644 --- a/PWGLF/DataModel/LFhe3HadronTables.h +++ b/PWGLF/DataModel/LFhe3HadronTables.h @@ -57,7 +57,7 @@ DECLARE_SOA_COLUMN(ItsClusterSizeHad, itsClusterSizeHad, uint32_t); DECLARE_SOA_COLUMN(SharedClustersHe3, sharedClustersHe3, uint8_t); DECLARE_SOA_COLUMN(SharedClustersHad, sharedClustersHad, uint8_t); -DECLARE_SOA_COLUMN(IsBkgLS, isBkgLS, bool); +DECLARE_SOA_COLUMN(IsBkgUS, isBkgUS, bool); DECLARE_SOA_COLUMN(IsBkgEM, isBkgEM, bool); DECLARE_SOA_COLUMN(PtMCHe3, ptMCHe3, float); @@ -69,6 +69,8 @@ DECLARE_SOA_COLUMN(PhiMCHad, phiMCHad, float); DECLARE_SOA_COLUMN(SignedPtMC, signedPtMC, float); DECLARE_SOA_COLUMN(MassMC, massMC, float); +DECLARE_SOA_COLUMN(CollisionId, collisionId, int64_t); +DECLARE_SOA_COLUMN(ZVertex, zVertex, float); DECLARE_SOA_COLUMN(Multiplicity, multiplicity, uint16_t); DECLARE_SOA_COLUMN(CentralityFT0C, centFT0C, float); DECLARE_SOA_COLUMN(MultiplicityFT0C, multiplicityFT0C, float); @@ -103,7 +105,7 @@ DECLARE_SOA_TABLE(he3HadronTable, "AOD", "HE3HADTABLE", he3HadronTablesNS::ItsClusterSizeHad, he3HadronTablesNS::SharedClustersHe3, he3HadronTablesNS::SharedClustersHad, - he3HadronTablesNS::IsBkgLS, + he3HadronTablesNS::IsBkgUS, he3HadronTablesNS::IsBkgEM) DECLARE_SOA_TABLE(he3HadronTableMC, "AOD", "HE3HADTABLEMC", he3HadronTablesNS::PtMCHe3, @@ -115,6 +117,8 @@ DECLARE_SOA_TABLE(he3HadronTableMC, "AOD", "HE3HADTABLEMC", he3HadronTablesNS::SignedPtMC, he3HadronTablesNS::MassMC) DECLARE_SOA_TABLE(he3HadronMult, "AOD", "HE3HADMULT", + he3HadronTablesNS::CollisionId, + he3HadronTablesNS::ZVertex, he3HadronTablesNS::Multiplicity, he3HadronTablesNS::CentralityFT0C, he3HadronTablesNS::MultiplicityFT0C) diff --git a/PWGLF/DataModel/SPCalibrationTables.h b/PWGLF/DataModel/SPCalibrationTables.h index bc92d39a4b7..2b417ce8758 100644 --- a/PWGLF/DataModel/SPCalibrationTables.h +++ b/PWGLF/DataModel/SPCalibrationTables.h @@ -28,7 +28,7 @@ namespace o2::aod { namespace spcalibrationtable { -DECLARE_SOA_COLUMN(TriggerEvent, triggerevent, bool); +DECLARE_SOA_COLUMN(TriggerEventSP, triggereventsp, bool); DECLARE_SOA_COLUMN(TriggerEventRunNo, triggereventrunno, int); DECLARE_SOA_COLUMN(Cent, cent, float); DECLARE_SOA_COLUMN(Vx, vx, float); @@ -52,7 +52,7 @@ DECLARE_SOA_COLUMN(PsiZDCC, psiZDCC, float); DECLARE_SOA_COLUMN(PsiZDCA, psiZDCA, float); } // namespace spcalibrationtable DECLARE_SOA_TABLE(SPCalibrationTables, "AOD", "SPCALCOLS", - spcalibrationtable::TriggerEvent, + spcalibrationtable::TriggerEventSP, spcalibrationtable::TriggerEventRunNo, spcalibrationtable::Cent, spcalibrationtable::Vx, diff --git a/PWGLF/DataModel/Vtx3BodyTables.h b/PWGLF/DataModel/Vtx3BodyTables.h index 49255b54da1..51e155206bd 100644 --- a/PWGLF/DataModel/Vtx3BodyTables.h +++ b/PWGLF/DataModel/Vtx3BodyTables.h @@ -386,9 +386,10 @@ DECLARE_SOA_COLUMN(TPCInnerParamTrack0, tpcinnerparamtrack0, float); //! mom DECLARE_SOA_COLUMN(TPCInnerParamTrack1, tpcinnerparamtrack1, float); //! momentum at inner wall of TPC of pion daughter DECLARE_SOA_COLUMN(TPCInnerParamTrack2, tpcinnerparamtrack2, float); //! momentum at inner wall of TPC of deuteron daughter // PID -DECLARE_SOA_COLUMN(TPCNSigmaProton, tpcnsigmaproton, float); //! nsigma of TPC PID of the proton daughter -DECLARE_SOA_COLUMN(TPCNSigmaPion, tpcnsigmapion, float); //! nsigma of TPC PID of the pion daughter -DECLARE_SOA_COLUMN(TPCNSigmaDeuteron, tpcnsigmadeuteron, float); //! nsigma of TPC PID of the bachelor daughter +DECLARE_SOA_COLUMN(TPCNSigmaProton, tpcnsigmaproton, float); //! nsigma proton of TPC PID of the proton daughter +DECLARE_SOA_COLUMN(TPCNSigmaPion, tpcnsigmapion, float); //! nsigma pion of TPC PID of the pion daughter +DECLARE_SOA_COLUMN(TPCNSigmaDeuteron, tpcnsigmadeuteron, float); //! nsigma deuteron of TPC PID of the bachelor daughter +DECLARE_SOA_COLUMN(TPCNSigmaPionBach, tpcnsigmapionbach, float); //! nsigma pion of TPC PID of the bachelor daughter DECLARE_SOA_COLUMN(TPCdEdxProton, tpcdedxproton, float); //! TPC dEdx of the proton daughter DECLARE_SOA_COLUMN(TPCdEdxPion, tpcdedxpion, float); //! TPC dEdx of the pion daughter DECLARE_SOA_COLUMN(TPCdEdxDeuteron, tpcdedxdeuteron, float); //! TPC dEdx of the bachelor daughter @@ -406,6 +407,12 @@ DECLARE_SOA_COLUMN(GenCtau, genctau, double); //! generated ctau DECLARE_SOA_COLUMN(GenPhi, genphi, float); //! generated phi DECLARE_SOA_COLUMN(GenEta, geneta, float); //! generated eta DECLARE_SOA_COLUMN(GenRapidity, genrapidity, float); //! generated rapidity +DECLARE_SOA_COLUMN(GenPosP, genposp, float); //! generated momentum pos daughter particle +DECLARE_SOA_COLUMN(GenPosPt, genpospt, float); //! generated transverse momentum pos daughter particle +DECLARE_SOA_COLUMN(GenNegP, gennegp, float); //! generated momentum neg daughter particle +DECLARE_SOA_COLUMN(GenNegPt, gennegpt, float); //! generated transverse momentum neg daughter particle +DECLARE_SOA_COLUMN(GenBachP, genbachp, float); //! generated momentum bachelor daughter particle +DECLARE_SOA_COLUMN(GenBachPt, genbachpt, float); //! generated transverse momentum bachelor daughter particle DECLARE_SOA_COLUMN(IsTrueH3L, istrueh3l, bool); //! flag for true hypertriton candidate DECLARE_SOA_COLUMN(IsTrueAntiH3L, istrueantih3l, bool); //! flag for true anti-hypertriton candidate DECLARE_SOA_COLUMN(PdgCode, pdgcode, int); //! MC particle PDG code @@ -452,31 +459,11 @@ DECLARE_SOA_TABLE(KFVtx3BodyDatas, "AOD", "KFVTX3BODYDATA", kfvtx3body::DCAxyTrackPosToPV, kfvtx3body::DCAxyTrackNegToPV, kfvtx3body::DCAxyTrackBachToPV, kfvtx3body::DCATrackPosToPV, kfvtx3body::DCATrackNegToPV, kfvtx3body::DCATrackBachToPV, kfvtx3body::Track0Sign, kfvtx3body::Track1Sign, kfvtx3body::Track2Sign, // track sing: proton, pion, deuteron - kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, + kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, kfvtx3body::TPCNSigmaPionBach, kfvtx3body::TPCdEdxProton, kfvtx3body::TPCdEdxPion, kfvtx3body::TPCdEdxDeuteron, kfvtx3body::TOFNSigmaDeuteron, kfvtx3body::ITSClusSizeDeuteron, - kfvtx3body::PIDTrackingDeuteron, - - // dynamic columns - vtx3body::VtxRadius, - vtx3body::DistOverTotMom, - vtx3body::VtxCosPA, - vtx3body::DCAVtxToPV, - - // Longitudinal - vtx3body::YHypertriton, - vtx3body::Eta, - vtx3body::Phi, - vtx3body::Track0Pt, // proton pT - vtx3body::Track0Eta, // proton eta - vtx3body::Track0Phi, // proton phi - vtx3body::Track1Pt, // pion pT - vtx3body::Track1Eta, // pion eta - vtx3body::Track1Phi, // pion phi - vtx3body::Track2Pt, // deuteron pT - vtx3body::Track2Eta, // deuteron eta - vtx3body::Track2Phi); // deuteron phi + kfvtx3body::PIDTrackingDeuteron); using KFVtx3BodyData = KFVtx3BodyDatas::iterator; namespace kfvtx3body @@ -518,31 +505,11 @@ DECLARE_SOA_TABLE(KFVtx3BodyDatasLite, "AOD", "KF3BODYLITE", kfvtx3body::DCAxyTrack0ToTrack1KF, kfvtx3body::DCAxyTrack0ToTrack2KF, kfvtx3body::DCAxyTrack1ToTrack2KF, kfvtx3body::DCAVtxDaughtersKF, kfvtx3body::Track0Sign, kfvtx3body::Track1Sign, kfvtx3body::Track2Sign, // track sing: proton, pion, deuteron - kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, + kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, kfvtx3body::TPCNSigmaPionBach, kfvtx3body::TPCdEdxProton, kfvtx3body::TPCdEdxPion, kfvtx3body::TPCdEdxDeuteron, kfvtx3body::TOFNSigmaDeuteron, kfvtx3body::ITSClusSizeDeuteron, - kfvtx3body::PIDTrackingDeuteron, - - // dynamic columns - vtx3body::VtxRadius, - vtx3body::DistOverTotMom, - vtx3body::VtxCosPA, - vtx3body::DCAVtxToPV, - - // Longitudinal - vtx3body::YHypertriton, - vtx3body::Eta, - vtx3body::Phi, - vtx3body::Track0Pt, // proton pT - vtx3body::Track0Eta, // proton eta - vtx3body::Track0Phi, // proton phi - vtx3body::Track1Pt, // pion pT - vtx3body::Track1Eta, // pion eta - vtx3body::Track1Phi, // pion phi - vtx3body::Track2Pt, // deuteron pT - vtx3body::Track2Eta, // deuteron eta - vtx3body::Track2Phi); // deuteron phi + kfvtx3body::PIDTrackingDeuteron); using KFVtx3BodyDataLite = KFVtx3BodyDatasLite::iterator; @@ -579,7 +546,7 @@ DECLARE_SOA_TABLE(McKFVtx3BodyDatas, "AOD", "MCKF3BODYDATAS", kfvtx3body::DCAxyTrackPosToPV, kfvtx3body::DCAxyTrackNegToPV, kfvtx3body::DCAxyTrackBachToPV, kfvtx3body::DCATrackPosToPV, kfvtx3body::DCATrackNegToPV, kfvtx3body::DCATrackBachToPV, kfvtx3body::Track0Sign, kfvtx3body::Track1Sign, kfvtx3body::Track2Sign, // track sing: proton, pion, deuteron - kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, + kfvtx3body::TPCNSigmaProton, kfvtx3body::TPCNSigmaPion, kfvtx3body::TPCNSigmaDeuteron, kfvtx3body::TPCNSigmaPionBach, kfvtx3body::TPCdEdxProton, kfvtx3body::TPCdEdxPion, kfvtx3body::TPCdEdxDeuteron, kfvtx3body::TOFNSigmaDeuteron, kfvtx3body::ITSClusSizeDeuteron, @@ -593,30 +560,13 @@ DECLARE_SOA_TABLE(McKFVtx3BodyDatas, "AOD", "MCKF3BODYDATAS", kfvtx3body::GenPhi, kfvtx3body::GenEta, kfvtx3body::GenRapidity, + kfvtx3body::GenPosP, kfvtx3body::GenPosPt, + kfvtx3body::GenNegP, kfvtx3body::GenNegPt, + kfvtx3body::GenBachP, kfvtx3body::GenBachPt, kfvtx3body::IsTrueH3L, kfvtx3body::IsTrueAntiH3L, kfvtx3body::PdgCode, kfvtx3body::IsReco, - kfvtx3body::SurvEvSel, - - // dynamic columns - vtx3body::VtxRadius, - vtx3body::DistOverTotMom, - vtx3body::VtxCosPA, - vtx3body::DCAVtxToPV, - - // Longitudinal - vtx3body::YHypertriton, - vtx3body::Eta, - vtx3body::Phi, - vtx3body::Track0Pt, // proton pT - vtx3body::Track0Eta, // proton eta - vtx3body::Track0Phi, // proton phi - vtx3body::Track1Pt, // pion pT - vtx3body::Track1Eta, // pion eta - vtx3body::Track1Phi, // pion phi - vtx3body::Track2Pt, // deuteron pT - vtx3body::Track2Eta, // deuteron eta - vtx3body::Track2Phi); // deuteron phi + kfvtx3body::SurvEvSel); // Definition of labels for KFVtx3BodyDatas namespace mckfvtx3bodylabel diff --git a/PWGLF/DataModel/pidTOFGeneric.h b/PWGLF/DataModel/pidTOFGeneric.h index 2c1c9960a21..b43d4ecc9ff 100644 --- a/PWGLF/DataModel/pidTOFGeneric.h +++ b/PWGLF/DataModel/pidTOFGeneric.h @@ -51,7 +51,7 @@ namespace pidtofgeneric static constexpr float kCSPEED = TMath::C() * 1.0e2f * 1.0e-12f; // c in cm/ps -template +template class TofPidNewCollision { public: @@ -83,85 +83,95 @@ class TofPidNewCollision pidType = pidId; } - float GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true) - { - float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; - float expTime = track.length() * sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v + template + float GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true); - float evTime = correctedcol.evTime(); - float evTimeErr = correctedcol.evTimeErr(); - float tofsignal = track.trackTime() * 1000 + expTime; // in ps - float expSigma, tofNsigma; + template + float GetTOFNSigma(TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true); +}; - if (originalcol.globalIndex() == correctedcol.globalIndex()) { - evTime = track.evTimeForTrack(); - evTimeErr = track.evTimeErrForTrack(); +template +template +float TofPidNewCollision::GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D) +{ + float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; + float expTime = track.length() * sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v + + float evTime = correctedcol.evTime(); + float evTimeErr = correctedcol.evTimeErr(); + float tofsignal = track.trackTime() * 1000 + expTime; // in ps + float expSigma, tofNsigma; + + if (originalcol.globalIndex() == correctedcol.globalIndex()) { + evTime = track.evTimeForTrack(); + evTimeErr = track.evTimeErrForTrack(); + } else { + if (EnableBCAO2D) { + auto originalbc = originalcol.template bc_as(); + auto correctedbc = correctedcol.template bc_as(); + o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); + o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); + tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; } else { - if (EnableBCAO2D) { - auto originalbc = originalcol.template bc_as(); - auto correctedbc = correctedcol.template bc_as(); - o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); - o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); - tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; - } else { - auto originalbc = originalcol.template foundBC_as(); - auto correctedbc = correctedcol.template foundBC_as(); - o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); - o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); - tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; - } + auto originalbc = originalcol.template foundBC_as(); + auto correctedbc = correctedcol.template foundBC_as(); + o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); + o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); + tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; } - - switch (pidId) { - case 0: - expSigma = responseEl.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseEl.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 1: - expSigma = responseMu.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseMu.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 2: - expSigma = responsePi.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responsePi.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 3: - expSigma = responseKa.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseKa.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 4: - expSigma = responsePr.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responsePr.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 5: - expSigma = responseDe.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseDe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 6: - expSigma = responseTr.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseTr.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 7: - expSigma = responseHe.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseHe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 8: - expSigma = responseAl.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseAl.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - default: - LOG(fatal) << "Wrong particle ID in TofPidSecondary class"; - return -999; - } - - return tofNsigma; } - float GetTOFNSigma(TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true) - { - return GetTOFNSigma(pidType, track, originalcol, correctedcol, EnableBCAO2D); + switch (pidId) { + case 0: + expSigma = responseEl.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseEl.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 1: + expSigma = responseMu.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseMu.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 2: + expSigma = responsePi.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responsePi.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 3: + expSigma = responseKa.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseKa.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 4: + expSigma = responsePr.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responsePr.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 5: + expSigma = responseDe.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseDe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 6: + expSigma = responseTr.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseTr.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 7: + expSigma = responseHe.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseHe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + case 8: + expSigma = responseAl.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseAl.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; + break; + default: + LOG(fatal) << "Wrong particle ID in TofPidSecondary class"; + return -999; } -}; + + return tofNsigma; +} + +template +template +float TofPidNewCollision::GetTOFNSigma(TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D) +{ + return GetTOFNSigma(pidType, track, originalcol, correctedcol, EnableBCAO2D); +} } // namespace pidtofgeneric } // namespace o2::aod diff --git a/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx b/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx index 676572e035d..ca382c8d2be 100644 --- a/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx +++ b/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx @@ -45,6 +45,7 @@ #include "Common/TableProducer/PID/pidTOFBase.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" #include "DCAFitter/DCAFitterN.h" #include "PWGLF/DataModel/LFClusterStudiesTable.h" @@ -234,6 +235,12 @@ struct LfTreeCreatorClusterStudies { {"nSigmaTOFDe", "nSigma TOF Deuteron; signed #it{p} (GeV/#it{c}); n#sigma_{TOF} d", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, {"TOFmassDe", "TOF mass De; signed #it{p}_{T} (GeV/#it{c}); mass_{TOF} ^{3}He (GeV/#it{c}^2)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 1.0f, 5.0f}}}}, {"TOFmassHe", "TOF mass He3; signed #it{p}_{T} (GeV/#it{c}); mass_{TOF} ^{3}He (GeV/#it{c}^2)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, 1.0f, 5.0f}}}}, + {"nSigmaITSEl", "nSigma ITS Electron; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} e", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -2.0f, 2.0f}}}}, + {"nSigmaITSPi", "nSigma ITS Pion; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} #pi", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}}}, + {"nSigmaITSKa", "nSigma ITS Kaon; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} e", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -4.0f, 4.0f}}}}, + {"nSigmaITSPr", "nSigma ITS Proton; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} p", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {60, -3.0f, 3.0f}}}}, + {"nSigmaITSDe", "nSigma ITS Deuteron; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} d", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, + {"nSigmaITSHe", "nSigma ITS He3; signed #it{p} (GeV/#it{c}); n#sigma_{ITS} ^{3}He", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {100, -3.0f, 3.0f}}}}, {"pmatchingEl", "#it{p} matching e; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, {"pmatchingPi", "#it{p} matching #pi; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, {"pmatchingKa", "#it{p} matching K; signed #it{p}_{TPC} (GeV/#it{c}); #frac{#it{p}_{TPC} - #it{p}}{#it{p}_{TPC}}", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {100, -0.5f, 0.5f}}}}, @@ -260,6 +267,7 @@ struct LfTreeCreatorClusterStudies { o2::vertexing::DCAFitterN<2> m_fitter; o2::pid::tof::Beta m_responseBeta; o2::pid::tof::Beta m_responseBetaMc; + o2::aod::ITSResponse m_responseITS; template bool initializeFitter(const T& trackParCovA, const T& trackParCovB) @@ -705,7 +713,9 @@ struct LfTreeCreatorClusterStudies { m_hAnalysis.fill(HIST("massLambda"), std::hypot(momMother[0], momMother[1], momMother[2]), massLambdaV0); m_hAnalysis.fill(HIST("armenteros_plot_lambda"), alphaAP, qtAP); m_hAnalysis.fill(HIST("nSigmaTPCPr"), std::hypot(momPos[0], momPos[1], momPos[2]), posTrack.tpcNSigmaPr()); + m_hAnalysis.fill(HIST("nSigmaITSPr"), std::hypot(momPos[0], momPos[1], momPos[2]), m_responseITS.nSigmaITS(posTrack.itsClusterSizes(), posTrack.p(), posTrack.eta())); m_hAnalysis.fill(HIST("nSigmaTPCPi"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, negTrack.tpcNSigmaPi()); + m_hAnalysis.fill(HIST("nSigmaITSPi"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, m_responseITS.nSigmaITS(negTrack.itsClusterSizes(), negTrack.p(), negTrack.eta())); m_hAnalysis.fill(HIST("pmatchingPr"), posTrack.tpcInnerParam(), (posTrack.tpcInnerParam() - posTrack.p()) / posTrack.tpcInnerParam()); m_hAnalysis.fill(HIST("pmatchingPi"), -negTrack.tpcInnerParam(), (negTrack.tpcInnerParam() - negTrack.p()) / negTrack.tpcInnerParam()); @@ -715,7 +725,9 @@ struct LfTreeCreatorClusterStudies { // "signed" pt for antimatter m_hAnalysis.fill(HIST("armenteros_plot_lambda"), alphaAP, qtAP); m_hAnalysis.fill(HIST("nSigmaTPCPi"), std::hypot(momPos[0], momPos[1], momPos[2]), posTrack.tpcNSigmaPi()); - m_hAnalysis.fill(HIST("nSigmaTPCPi"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, negTrack.tpcNSigmaPr()); + m_hAnalysis.fill(HIST("nSigmaITSPi"), std::hypot(momPos[0], momPos[1], momPos[2]), m_responseITS.nSigmaITS(posTrack.itsClusterSizes(), posTrack.p(), posTrack.eta())); + m_hAnalysis.fill(HIST("nSigmaTPCPr"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, negTrack.tpcNSigmaPr()); + m_hAnalysis.fill(HIST("nSigmaITSPr"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, m_responseITS.nSigmaITS(negTrack.itsClusterSizes(), negTrack.p(), negTrack.eta())); m_hAnalysis.fill(HIST("pmatchingPi"), posTrack.tpcInnerParam(), (posTrack.tpcInnerParam() - posTrack.p()) / posTrack.tpcInnerParam()); m_hAnalysis.fill(HIST("pmatchingPr"), -negTrack.tpcInnerParam(), (negTrack.tpcInnerParam() - negTrack.p()) / negTrack.tpcInnerParam()); @@ -723,6 +735,8 @@ struct LfTreeCreatorClusterStudies { massV0 = 0.f; m_hAnalysis.fill(HIST("nSigmaTPCEl"), std::hypot(momPos[0], momPos[1], momPos[2]), posTrack.tpcNSigmaEl()); m_hAnalysis.fill(HIST("nSigmaTPCEl"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, negTrack.tpcNSigmaEl()); + m_hAnalysis.fill(HIST("nSigmaITSEl"), std::hypot(momPos[0], momPos[1], momPos[2]), m_responseITS.nSigmaITS(posTrack.itsClusterSizes(), posTrack.p(), posTrack.eta())); + m_hAnalysis.fill(HIST("nSigmaITSEl"), std::hypot(momNeg[0], momNeg[1], momNeg[2]) * -1.f, m_responseITS.nSigmaITS(negTrack.itsClusterSizes(), negTrack.p(), negTrack.eta())); m_hAnalysis.fill(HIST("armenteros_plot_gamma"), alphaAP, qtAP); m_hAnalysis.fill(HIST("pmatchingEl"), posTrack.tpcInnerParam(), (posTrack.tpcInnerParam() - posTrack.p()) / posTrack.tpcInnerParam()); m_hAnalysis.fill(HIST("pmatchingEl"), -negTrack.tpcInnerParam(), (negTrack.tpcInnerParam() - negTrack.p()) / negTrack.tpcInnerParam()); @@ -972,6 +986,7 @@ struct LfTreeCreatorClusterStudies { } m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDePIDtof); m_hAnalysis.fill(HIST("nSigmaTPCDe"), track.p() * track.sign(), computeNSigmaDe(track)); + m_hAnalysis.fill(HIST("nSigmaITSDe"), track.p() * track.sign(), m_responseITS.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta())); m_hAnalysis.fill(HIST("nSigmaTOFDe"), track.p() * track.sign(), track.tofNSigmaDe()); m_hAnalysis.fill(HIST("TOFmassDe"), track.p() * track.sign(), computeTOFmassDe(track)); m_hAnalysis.fill(HIST("pmatchingDe"), track.sign() * track.tpcInnerParam(), (track.tpcInnerParam() - track.p()) / track.tpcInnerParam()); @@ -1060,6 +1075,7 @@ struct LfTreeCreatorClusterStudies { m_hAnalysis.fill(HIST("he3_selections"), He3Selections::kHe3PIDtof); m_hAnalysis.fill(HIST("nSigmaTPCHe"), track.p() * track.sign(), computeNSigmaHe3(track)); + m_hAnalysis.fill(HIST("nSigmaITSHe"), track.p() * track.sign(), m_responseITS.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta())); m_hAnalysis.fill(HIST("TOFmassHe"), track.p() * track.sign(), tofMass); m_hAnalysis.fill(HIST("pmatchingHe"), track.sign() * correctedTPCinnerParam, (correctedTPCinnerParam - track.p()) / correctedTPCinnerParam); diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index 5216a99844c..8bcbc20c98a 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -66,11 +67,28 @@ using FullTracksExtIU = soa::Join; using ColwithEvTimes = o2::soa::Join; +using FullCols = o2::soa::Join; using TrackExtIUwithEvTimes = soa::Join; using TrackExtPIDIUwithEvTimes = soa::Join; using MCLabeledTracksIU = soa::Join; +struct vtxCandidate { + int track0Id; + int track1Id; + int track2Id; + int collisionId; + int decay3bodyId; + float vtxPos[3]; + float track0P[3]; + float track1P[3]; + float track2P[3]; + float dcadaughters; + float daudcaxytopv[3]; // 0 - proton, 1 - pion, 2 - bachelor + float daudcatopv[3]; // 0 - proton, 1 - pion, 2 - bachelor + float bachelortofNsigma; +}; + struct decay3bodyBuilder { Produces vtx3bodydata; @@ -78,6 +96,7 @@ struct decay3bodyBuilder { Produces kfvtx3bodydatalite; Service ccdb; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + std::vector vtxCandidates; // Configurables Configurable d_UseAbsDCA{"d_UseAbsDCA", true, "Use Abs DCAs"}; @@ -123,9 +142,10 @@ struct decay3bodyBuilder { HistogramRegistry registry{"registry", {}}; // hypothesis - Configurable motherhyp{"motherhyp", 0, "hypothesis of the 3body decayed particle"}; // corresponds to hyp3body - int bachelorcharge = 1; // to be updated in Init base on the hypothesis - o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; // to be updated in Init base on the hypothesis + Configurable motherhyp{"motherhyp", 0, "hypothesis of the 3body decayed particle"}; // corresponds to hyp3body + int bachelorcharge = 1; // to be updated in Init base on the hypothesis + // o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; // to be updated in Init base on the hypothesis + o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; // to be updated in Init base on the hypothesis // Selection criteria Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; @@ -197,6 +217,30 @@ struct decay3bodyBuilder { Configurable maxChi2topo{"kfparticleConfigurations.maxChi2topo", 1000., "Maximum chi2 topological with KFParticle"}; } kfparticleConfigurations; + //------------------------------------------------------------------ + // Sets for event mixing + struct : ConfigurableGroup { + Configurable nUseMixedEvent{"nUseMixedEvent", 5, "nUseMixedEvent"}; + Configurable em_event_sel8_selection{"em_event_sel8_selection", true, "event selection count post sel8 cut"}; + Configurable etacut{"etacut", 0.9, "etacut"}; + 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 mintpcNClsproton{"mintpcNClsproton", 90, "min tpc Nclusters for proton"}; + Configurable mintpcNClspion{"mintpcNClspion", 70, "min tpc Nclusters for pion"}; + Configurable mintpcNClsbachelor{"mintpcNClsbachelor", 100, "min tpc Nclusters for bachelor"}; + Configurable emTpcPidNsigmaCut{"emTpcPidNsigmaCut", 5, "emTpcPidNsigmaCut"}; + } EMTrackSel; + + Preslice tracksperCol = aod::track::collisionId; + SliceCache cache; + ConfigurableAxis axisPosZ{"axisPosZ", {40, -10, 10}, "Mixing bins - posZ"}; + ConfigurableAxis axisCentrality{"axisCentrality", {10, 0, 100}, "Mixing bins - centrality"}; + using BinningType = ColumnBinningPolicy; + // Filters and slices // Filter collisionFilter = (aod::evsel::sel8 == true && nabs(aod::collision::posZ) < 10.f); Preslice perCollision = o2::aod::decay3body::collisionId; @@ -273,7 +317,7 @@ struct decay3bodyBuilder { fitter3body.setMatCorrType(matCorr); // Add histograms separately for different process functions - if (doprocessRun3 == true) { + if (doprocessRun3 == true || doprocessRun3EM == true || doprocessRun3EMLikeSign == true) { registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{1, 0.0f, 1.0f}}); auto hVtx3BodyCounter = registry.add("hVtx3BodyCounter", "hVtx3BodyCounter", HistType::kTH1F, {{6, 0.0f, 6.0f}}); hVtx3BodyCounter->GetXaxis()->SetBinLabel(1, "Total"); @@ -512,110 +556,139 @@ struct decay3bodyBuilder { //------------------------------------------------------------------ // 3body candidate builder - template - // void buildVtx3BodyDataTable(TCollisionTable const& /*allcollisions*/, TCollisionTable::iterator const& collision, TTrackTable const& /*tracks*/, aod::Decay3Bodys const& decay3bodys, int bachelorcharge = 1) - void buildVtx3BodyDataTable(TCollisionTable const& collision, TTrackTable const& /*tracks*/, aod::Decay3Bodys const& decay3bodys, int bachelorcharge = 1) + template + void fillVtxCand(TCollisionTable const& collision, TTrackTable const& t0, TTrackTable const& t1, TTrackTable const& t2, int64_t decay3bodyId, int bachelorcharge = 1) { - for (auto& vtx3body : decay3bodys) { - - registry.fill(HIST("hVtx3BodyCounter"), kVtxAll); - - auto t0 = vtx3body.template track0_as(); - auto t1 = vtx3body.template track1_as(); - auto t2 = vtx3body.template track2_as(); - - if (t0.tpcNClsFound() < mintpcNCls || t1.tpcNClsFound() < mintpcNCls || t2.tpcNClsFound() < mintpcNCls) { - continue; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxTPCNcls); + registry.fill(HIST("hVtx3BodyCounter"), kVtxAll); - // Recalculate the TOF PID - double tofNSigmaBach = -999; - if (t2.has_collision() && t2.hasTOF()) { + if (t0.tpcNClsFound() < mintpcNCls || t1.tpcNClsFound() < mintpcNCls || t2.tpcNClsFound() < mintpcNCls) { + return; + } + registry.fill(HIST("hVtx3BodyCounter"), kVtxTPCNcls); + + // Recalculate the TOF PID + double tofNSigmaBach = -999; + if (t2.has_collision() && t2.hasTOF()) { + if (decay3bodyId == -1) { + // for event-mixing, the collisionId of tracks not equal to global index + tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(t2, collision, collision); + } else { auto originalcol = t2.template collision_as(); tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(t2, originalcol, collision); } + } - if (enablePidCut) { - if (t2.sign() > 0) { - if (!checkPIDH3L(t0, t1, t2, tofNSigmaBach)) - continue; - } else { - if (!checkPIDH3L(t1, t0, t2, tofNSigmaBach)) - continue; - } + if (enablePidCut) { + if (t2.sign() > 0) { + if (!checkPIDH3L(t0, t1, t2, tofNSigmaBach)) + return; + } else { + if (!checkPIDH3L(t1, t0, t2, tofNSigmaBach)) + return; } + } - registry.fill(HIST("hVtx3BodyCounter"), kVtxPIDCut); + registry.fill(HIST("hVtx3BodyCounter"), kVtxPIDCut); - // Calculate DCA with respect to the collision associated to the V0, not individual tracks - gpu::gpustd::array dcaInfo; + // 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({collision.posX(), collision.posY(), collision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track0dcaXY = dcaInfo[0]; - auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]); + auto Track0Par = getTrackPar(t0); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); + auto Track0dcaXY = dcaInfo[0]; + auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]); - auto Track1Par = getTrackPar(t1); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track1dcaXY = dcaInfo[0]; - auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]); + auto Track1Par = getTrackPar(t1); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); + auto Track1dcaXY = dcaInfo[0]; + auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]); - auto Track2Par = getTrackPar(t2); - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track2dcaXY = dcaInfo[0]; - auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]); + auto Track2Par = getTrackPar(t2); + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); + auto Track2dcaXY = dcaInfo[0]; + auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]); - auto Track0 = getTrackParCov(t0); - auto Track1 = getTrackParCov(t1); - auto Track2 = getTrackParCov(t2); - int n3bodyVtx = fitter3body.process(Track0, Track1, Track2); - if (n3bodyVtx == 0) { // discard this pair - continue; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxhasSV); + auto Track0 = getTrackParCov(t0); + auto Track1 = getTrackParCov(t1); + auto Track2 = getTrackParCov(t2); + int n3bodyVtx = fitter3body.process(Track0, Track1, Track2); + if (n3bodyVtx == 0) { // discard this pair + return; + } + registry.fill(HIST("hVtx3BodyCounter"), kVtxhasSV); - std::array pos = {0.}; - const auto& vtxXYZ = fitter3body.getPCACandidate(); - for (int i = 0; i < 3; i++) { - pos[i] = vtxXYZ[i]; - } + std::array pos = {0.}; + const auto& vtxXYZ = fitter3body.getPCACandidate(); + for (int i = 0; i < 3; i++) { + pos[i] = vtxXYZ[i]; + } - std::array p0 = {0.}, p1 = {0.}, p2{0.}; - 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); - for (int i = 0; i < 3; i++) { - p2[i] *= bachelorcharge; - } - std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; + std::array p0 = {0.}, p1 = {0.}, p2{0.}; + 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); + for (int i = 0; i < 3; i++) { + p2[i] *= bachelorcharge; + } + 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) { - continue; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxDcaDau); + if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { + return; + } + registry.fill(HIST("hVtx3BodyCounter"), kVtxDcaDau); - float VtxcosPA = RecoDecay::cpa(array{collision.posX(), collision.posY(), collision.posZ()}, array{pos[0], pos[1], pos[2]}, array{p3B[0], p3B[1], p3B[2]}); - if (VtxcosPA < minCosPA3body) { - continue; - } - registry.fill(HIST("hVtx3BodyCounter"), kVtxCosPA); - - registry.fill(HIST("hBachelorTOFNSigmaDe"), t2.sign() * t2.p(), tofNSigmaBach); - - vtx3bodydata( - t0.globalIndex(), t1.globalIndex(), t2.globalIndex(), collision.globalIndex(), vtx3body.globalIndex(), - pos[0], pos[1], pos[2], - p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], - fitter3body.getChi2AtPCACandidate(), - Track0dcaXY, Track1dcaXY, Track2dcaXY, - Track0dca, Track1dca, Track2dca, - tofNSigmaBach); + float VtxcosPA = RecoDecay::cpa(array{collision.posX(), collision.posY(), collision.posZ()}, array{pos[0], pos[1], pos[2]}, array{p3B[0], p3B[1], p3B[2]}); + if (VtxcosPA < minCosPA3body) { + return; } + registry.fill(HIST("hVtx3BodyCounter"), kVtxCosPA); + + registry.fill(HIST("hBachelorTOFNSigmaDe"), t2.sign() * t2.p(), tofNSigmaBach); + + vtxCandidate candVtx; + candVtx.track0Id = t0.globalIndex(); + candVtx.track1Id = t1.globalIndex(); + candVtx.track2Id = t2.globalIndex(); + candVtx.collisionId = collision.globalIndex(); + candVtx.decay3bodyId = decay3bodyId; + candVtx.vtxPos[0] = pos[0]; + candVtx.vtxPos[1] = pos[1]; + candVtx.vtxPos[2] = pos[2]; + candVtx.track0P[0] = p0[0]; + candVtx.track0P[1] = p0[1]; + candVtx.track0P[2] = p0[2]; + candVtx.track1P[0] = p1[0]; + candVtx.track1P[1] = p1[1]; + candVtx.track1P[2] = p1[2]; + candVtx.track2P[0] = p2[0]; + candVtx.track2P[1] = p2[1]; + candVtx.track2P[2] = p2[2]; + candVtx.dcadaughters = fitter3body.getChi2AtPCACandidate(); + candVtx.daudcaxytopv[0] = Track0dcaXY; + candVtx.daudcaxytopv[1] = Track1dcaXY; + candVtx.daudcaxytopv[2] = Track2dcaXY; + candVtx.daudcatopv[0] = Track0dca; + candVtx.daudcatopv[1] = Track1dca; + candVtx.daudcatopv[2] = Track2dca; + candVtx.bachelortofNsigma = tofNSigmaBach; + vtxCandidates.push_back(candVtx); + } + //------------------------------------------------------------------ + // fill the StoredVtx3BodyDatas table + void fillVtx3BodyTable(vtxCandidate const& candVtx) + { + vtx3bodydata( + candVtx.track0Id, candVtx.track1Id, candVtx.track2Id, candVtx.collisionId, candVtx.decay3bodyId, + candVtx.vtxPos[0], candVtx.vtxPos[1], candVtx.vtxPos[2], + candVtx.track0P[0], candVtx.track0P[1], candVtx.track0P[2], candVtx.track1P[0], candVtx.track1P[1], candVtx.track1P[2], candVtx.track2P[0], candVtx.track2P[1], candVtx.track2P[2], + candVtx.dcadaughters, + candVtx.daudcaxytopv[0], candVtx.daudcaxytopv[1], candVtx.daudcaxytopv[2], + candVtx.daudcatopv[0], candVtx.daudcatopv[1], candVtx.daudcatopv[2], + candVtx.bachelortofNsigma); } //------------------------------------------------------------------ @@ -739,6 +812,7 @@ struct decay3bodyBuilder { float dEdxProton; float dEdxPion; float tpcNsigmaDeuteron = trackBach.tpcNSigmaDe(); + float tpcNsigmaPionBach = trackBach.tpcNSigmaPi(); float dEdxDeuteron = trackBach.tpcSignal(); if (isMatter) { // hypertriton (proton, pi-, deuteron) tpcNsigmaProton = trackPos.tpcNSigmaPr(); @@ -1047,12 +1121,8 @@ struct decay3bodyBuilder { kfpPion.GetQ(), trackBach.sign(), // daughter PID - tpcNsigmaProton, - tpcNsigmaPion, - tpcNsigmaDeuteron, - dEdxProton, - dEdxPion, - dEdxDeuteron, + tpcNsigmaProton, tpcNsigmaPion, tpcNsigmaDeuteron, tpcNsigmaPionBach, + dEdxProton, dEdxPion, dEdxDeuteron, tofNSigmaDeuteron, averageClusterSizeDeuteron, trackBach.pidForTracking()); @@ -1099,12 +1169,8 @@ struct decay3bodyBuilder { kfpPion.GetQ(), trackBach.sign(), // daughter PID - tpcNsigmaProton, - tpcNsigmaPion, - tpcNsigmaDeuteron, - dEdxProton, - dEdxPion, - dEdxDeuteron, + tpcNsigmaProton, tpcNsigmaPion, tpcNsigmaDeuteron, tpcNsigmaPionBach, + dEdxProton, dEdxPion, dEdxDeuteron, tofNSigmaDeuteron, averageClusterSizeDeuteron, trackBach.pidForTracking()); @@ -1117,20 +1183,143 @@ struct decay3bodyBuilder { } //------------------------------------------------------------------ - void processRun3(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const& tracksIU, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) + void processRun3(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const& /*tracksIU*/, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) { + vtxCandidates.clear(); + for (const auto& collision : collisions) { auto bc = collision.bc_as(); initCCDB(bc); registry.fill(HIST("hEventCounter"), 0.5); const auto& d3bodysInCollision = decay3bodys.sliceBy(perCollision, collision.globalIndex()); - // buildVtx3BodyDataTable(collisions, collision, tracksIU, d3bodysInCollision, bachelorcharge); - buildVtx3BodyDataTable(collision, tracksIU, d3bodysInCollision, bachelorcharge); + for (auto& d3body : d3bodysInCollision) { + auto t0 = d3body.template track0_as(); + auto t1 = d3body.template track1_as(); + auto t2 = d3body.template track2_as(); + fillVtxCand(collision, t0, t1, t2, d3body.globalIndex(), bachelorcharge); + } + } + + for (auto& candVtx : vtxCandidates) { + fillVtx3BodyTable(candVtx); } } PROCESS_SWITCH(decay3bodyBuilder, processRun3, "Produce DCA fitter decay3body tables", true); + //------------------------------------------------------------------ + // Event-mixing background + void processRun3EM(FullCols const& collisions, TrackExtPIDIUwithEvTimes const& tracksIU, aod::BCsWithTimestamps const&) + { + + vtxCandidates.clear(); + + auto tracksTuple = std::make_tuple(tracksIU); + BinningType binningEvent{{axisPosZ, axisCentrality}, true}; + SameKindPair pair{binningEvent, EMTrackSel.nUseMixedEvent, -1, collisions, tracksTuple, &cache}; + + Partition candProtons = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candAntiProtons = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candPionPlus = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candPionMinus = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candBachelors = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candAntiBachelors = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; + candProtons.bindTable(tracksIU); + candPionPlus.bindTable(tracksIU); + candAntiProtons.bindTable(tracksIU); + candPionMinus.bindTable(tracksIU); + candBachelors.bindTable(tracksIU); + candAntiBachelors.bindTable(tracksIU); + + for (auto& [c1, tracks1, c2, tracks2] : pair) { + if (EMTrackSel.em_event_sel8_selection && (!c1.sel8() || !c2.sel8())) { + continue; + } + auto bc = c1.bc_as(); + initCCDB(bc); + auto protons = candProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto pionsplus = candPionPlus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto antiprotons = candAntiProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto pionsminus = candPionMinus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto bachelors = candBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); + auto antibachelors = candAntiBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); + + for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(protons, pionsminus, bachelors))) { + fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge); + } + for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(pionsplus, antiprotons, antibachelors))) { + fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge); + } + } + + // Aviod break of preslice in following workflow + std::sort(vtxCandidates.begin(), vtxCandidates.end(), [](const vtxCandidate a, const vtxCandidate b) { + return a.collisionId < b.collisionId; + }); + + for (auto& candVtx : vtxCandidates) { + fillVtx3BodyTable(candVtx); + } + } + PROCESS_SWITCH(decay3bodyBuilder, processRun3EM, "Produce event-mix background", false); + + //------------------------------------------------------------------ + // Event-mixing background + like-sign (to aviod deuteron with wrong collisionId) + void processRun3EMLikeSign(FullCols const& collisions, TrackExtPIDIUwithEvTimes const& tracksIU, aod::BCsWithTimestamps const&) + { + + vtxCandidates.clear(); + + auto tracksTuple = std::make_tuple(tracksIU); + BinningType binningEvent{{axisPosZ, axisCentrality}, true}; + SameKindPair pair{binningEvent, 5, -1, collisions, tracksTuple, &cache}; + + Partition candProtons = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candPionPlus = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candAntiProtons = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minProtonPt && aod::track::pt <= EMTrackSel.maxProtonPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsproton && nabs(aod::pidtpc::tpcNSigmaPr) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candPionMinus = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minPionPt && aod::track::pt <= EMTrackSel.maxPionPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClspion && nabs(aod::pidtpc::tpcNSigmaPi) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candBachelors = aod::track::signed1Pt > 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; + Partition candAntiBachelors = aod::track::signed1Pt < 0.f && nabs(aod::track::eta) <= EMTrackSel.etacut && aod::track::pt >= EMTrackSel.minDeuteronPt && aod::track::pt <= EMTrackSel.maxDeuteronPt && aod::track::tpcNClsFindable >= (uint8_t)EMTrackSel.mintpcNClsbachelor && nabs(aod::pidtpc::tpcNSigmaDe) <= EMTrackSel.emTpcPidNsigmaCut; + candProtons.bindTable(tracksIU); + candPionPlus.bindTable(tracksIU); + candAntiProtons.bindTable(tracksIU); + candPionMinus.bindTable(tracksIU); + candBachelors.bindTable(tracksIU); + candAntiBachelors.bindTable(tracksIU); + + for (auto& [c1, tracks1, c2, tracks2] : pair) { + if (EMTrackSel.em_event_sel8_selection && (!c1.sel8() || !c2.sel8())) { + continue; + } + auto bc = c1.bc_as(); + initCCDB(bc); + auto protons = candProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto pionsplus = candPionPlus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto antiprotons = candAntiProtons->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto pionsminus = candPionMinus->sliceByCached(aod::track::collisionId, c1.globalIndex(), cache); + auto bachelors = candBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); + auto antibachelors = candAntiBachelors->sliceByCached(aod::track::collisionId, c2.globalIndex(), cache); + + for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(protons, pionsminus, antibachelors))) { + fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge); + } + for (auto const& [tpos, tneg, tbach] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(pionsplus, antiprotons, bachelors))) { + fillVtxCand(c1, tpos, tneg, tbach, -1, bachelorcharge); + } + } + + // Aviod break of preslice in following workflow + std::sort(vtxCandidates.begin(), vtxCandidates.end(), [](const vtxCandidate a, const vtxCandidate b) { + return a.collisionId < b.collisionId; + }); + + for (auto& candVtx : vtxCandidates) { + fillVtx3BodyTable(candVtx); + } + } + PROCESS_SWITCH(decay3bodyBuilder, processRun3EMLikeSign, "Produce event-mix background with like-sign method", false); + //------------------------------------------------------------------ + void processRun3withKFParticle(ColwithEvTimes const& collisions, TrackExtPIDIUwithEvTimes const&, aod::Decay3Bodys const& decay3bodys, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { @@ -1161,6 +1350,7 @@ struct decay3bodyBuilder { PROCESS_SWITCH(decay3bodyBuilder, processRun3withKFParticle, "Produce KFParticle decay3body tables", false); }; +// build link from decay3body -> vtx3body struct decay3bodyDataLinkBuilder { Produces vtxdataLink; @@ -1173,7 +1363,9 @@ struct decay3bodyDataLinkBuilder { for (int ii = 0; ii < decay3bodytable.size(); ii++) lIndices[ii] = -1; for (auto& vtxdata : vtxdatatable) { - lIndices[vtxdata.decay3bodyId()] = vtxdata.globalIndex(); + if (vtxdata.decay3bodyId() != -1) { + lIndices[vtxdata.decay3bodyId()] = vtxdata.globalIndex(); + } } for (int ii = 0; ii < decay3bodytable.size(); ii++) { vtxdataLink(lIndices[ii]); @@ -1380,7 +1572,6 @@ struct decay3bodyLabelBuilder { struct decay3bodyInitializer { Spawns vtx3bodydatas; - // Spawns kfvtx3bodydatas; void init(InitContext const&) {} }; diff --git a/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx b/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx index da20c2ac8eb..0c042c5f84b 100644 --- a/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx +++ b/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx @@ -101,17 +101,18 @@ enum Selections { struct he3HadCandidate { - float recoPtHe3() const { return sign * std::hypot(momHe3[0], momHe3[1]); } + float recoPtHe3() const { return signHe3 * std::hypot(momHe3[0], momHe3[1]); } float recoPhiHe3() const { return std::atan2(momHe3[1], momHe3[0]); } float recoEtaHe3() const { return std::asinh(momHe3[2] / recoPtHe3()); } - float recoPtHad() const { return sign * std::hypot(momHad[0], momHad[1]); } + float recoPtHad() const { return signHad * std::hypot(momHad[0], momHad[1]); } float recoPhiHad() const { return std::atan2(momHad[1], momHad[0]); } float recoEtaHad() const { return std::asinh(momHad[2] / recoPtHad()); } std::array momHe3 = {99.f, 99.f, 99.f}; std::array momHad = {99.f, 99.f, 99.f}; - float sign = 1.f; + float signHe3 = 1.f; + float signHad = 1.f; float invMass = -10.f; float DCAxyHe3 = -10.f; float DCAzHe3 = -10.f; @@ -225,9 +226,6 @@ struct he3hadronfemto { Zorro m_zorro; OutputObj m_zorroSummary{"zorroSummary"}; - // check for mixed event to same event distribution compatibility - std::vector m_trackIdx2; - HistogramRegistry m_qaRegistry{ "QA", { @@ -394,7 +392,6 @@ struct he3hadronfemto { float tpcNSigmaHad = 0; if (setting_HadPDGCode == 211) { tpcNSigmaHad = candidate.tpcNSigmaPi(); - LOG(info) << "pion"; } else if (setting_HadPDGCode == 2212) { tpcNSigmaHad = candidate.tpcNSigmaPr(); } else { @@ -409,7 +406,6 @@ struct he3hadronfemto { float tofNSigmaHad = 0; if (setting_HadPDGCode == 211) { tofNSigmaHad = candidate.tofNSigmaPi(); - LOG(info) << "piontof"; } else if (setting_HadPDGCode == 2212) { tofNSigmaHad = candidate.tofNSigmaPr(); } else { @@ -429,12 +425,12 @@ struct he3hadronfemto { if (std::abs(tpcNSigmaHad) > setting_cutNsigmaTPC) { return false; } - m_qaRegistry.fill(HIST("h2NsigmaHadronTOF_preselection"), candidate.p(), tpcNSigmaHad); - if (std::abs(tpcNSigmaHad) > setting_cutNsigmaTOF) { + m_qaRegistry.fill(HIST("h2NsigmaHadronTOF_preselection"), candidate.p(), tofNSigmaHad); + if (std::abs(tofNSigmaHad) > setting_cutNsigmaTOF) { return false; } m_qaRegistry.fill(HIST("h2NsigmaHadronTPC"), candidate.tpcInnerParam(), tpcNSigmaHad); - m_qaRegistry.fill(HIST("h2NsigmaHadronTOF"), candidate.p(), tpcNSigmaHad); + m_qaRegistry.fill(HIST("h2NsigmaHadronTOF"), candidate.p(), tofNSigmaHad); return true; } else if (std::abs(tpcNSigmaHad) < setting_cutNsigmaTPC) { m_qaRegistry.fill(HIST("h2NsigmaHadronTPC"), candidate.tpcInnerParam(), tpcNSigmaHad); @@ -557,7 +553,8 @@ struct he3hadronfemto { return false; } - he3Hadcand.sign = trackHe3.sign(); + he3Hadcand.signHe3 = trackHe3.sign(); + he3Hadcand.signHad = trackHad.sign(); he3Hadcand.DCAxyHe3 = trackHe3.dcaXY(); he3Hadcand.DCAzHe3 = trackHe3.dcaZ(); @@ -649,16 +646,11 @@ struct he3hadronfemto { continue; } - if (!setting_enableBkgUS) { - if (track0.sign() * track1.sign() < 0) { - continue; - } - } else if (setting_enableBkgUS) { - if (track0.sign() * track1.sign() > 0) { - continue; - } - } else { - LOG(info) << "setting_enableBkgUS has to be 0 or 1"; + if (!setting_enableBkgUS && (track0.sign() * track1.sign() < 0)) { + continue; + } + if (setting_enableBkgUS && (track0.sign() * track1.sign() > 0)) { + continue; } if (!selectTrack(track1) || !selectionPIDHadron(track1)) { @@ -745,6 +737,8 @@ struct he3hadronfemto { } if (setting_fillMultiplicity) { m_outputMultiplicityTable( + collision.globalIndex(), + collision.posZ(), collision.numContrib(), collision.centFT0C(), collision.multFT0C()); diff --git a/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx index b24e14a6115..7dad8981ee7 100644 --- a/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx +++ b/PWGLF/TableProducer/Nuspex/threebodyKFTask.cxx @@ -186,6 +186,12 @@ struct threebodyKFTask { std::array genDecVtx{-1.f}; int vtx3bodyPDGcode = -1; double MCmassPrPi = -1.; + float genPosP = -1.; + float genPosPt = -1.; + float genNegP = -1.; + float genNegPt = -1.; + float genBachP = -1.; + float genBachPt = -1.; auto track0 = vtx3bodydata.track0_as(); auto track1 = vtx3bodydata.track1_as(); @@ -209,6 +215,12 @@ struct threebodyKFTask { genRap = MCvtx3body.y(); genP = MCvtx3body.p(); genPt = MCvtx3body.pt(); + genPosP = lMCTrack0.p(); + genPosPt = lMCTrack0.pt(); + genNegP = lMCTrack1.p(); + genNegPt = lMCTrack1.pt(); + genBachP = lMCTrack2.p(); + genBachPt = lMCTrack2.pt(); filledMothers.push_back(MCvtx3body.globalIndex()); } // end is H3L or Anti-H3L if (MCvtx3body.pdgCode() == motherPdgCode && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == bachelorPdgCode) { @@ -261,7 +273,7 @@ struct threebodyKFTask { vtx3bodydata.dcaxytrackpostopv(), vtx3bodydata.dcaxytracknegtopv(), vtx3bodydata.dcaxytrackbachtopv(), vtx3bodydata.dcatrackpostopv(), vtx3bodydata.dcatracknegtopv(), vtx3bodydata.dcatrackbachtopv(), vtx3bodydata.track0sign(), vtx3bodydata.track1sign(), vtx3bodydata.track2sign(), // proton, pion, deuteron - vtx3bodydata.tpcnsigmaproton(), vtx3bodydata.tpcnsigmapion(), vtx3bodydata.tpcnsigmadeuteron(), + vtx3bodydata.tpcnsigmaproton(), vtx3bodydata.tpcnsigmapion(), vtx3bodydata.tpcnsigmadeuteron(), vtx3bodydata.tpcnsigmapionbach(), vtx3bodydata.tpcdedxproton(), vtx3bodydata.tpcdedxpion(), vtx3bodydata.tpcdedxdeuteron(), vtx3bodydata.tofnsigmadeuteron(), vtx3bodydata.itsclussizedeuteron(), @@ -274,6 +286,7 @@ struct threebodyKFTask { genPhi, genEta, genRap, + genPosP, genPosPt, genNegP, genNegPt, genBachP, genBachPt, isTrueH3L, isTrueAntiH3L, vtx3bodyPDGcode, true, // is reconstructed @@ -288,6 +301,12 @@ struct threebodyKFTask { double genMCmassPrPi = -1.; bool isTrueGenH3L = false; bool isTrueGenAntiH3L = false; + float genPBach = -1.; + float genPtBach = -1.; + float genPPos = -1.; + float genPtPos = -1.; + float genPNeg = -1.; + float genPtNeg = -1.; // check if mcparticle was reconstructed and already filled in the table if (std::find(filledMothers.begin(), filledMothers.end(), mcparticle.globalIndex()) != std::end(filledMothers)) { @@ -327,8 +346,12 @@ struct threebodyKFTask { for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { if (mcparticleDaughter.pdgCode() == 2212) { protonMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; + genPPos = mcparticleDaughter.p(); + genPtPos = mcparticleDaughter.pt(); } else if (mcparticleDaughter.pdgCode() == -211) { piMinusMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; + genPNeg = mcparticleDaughter.p(); + genPtNeg = mcparticleDaughter.pt(); } } genMCmassPrPi = RecoDecay::m(array{protonMom, piMinusMom}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); @@ -343,8 +366,12 @@ struct threebodyKFTask { for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { if (mcparticleDaughter.pdgCode() == -2212) { antiProtonMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; + genPNeg = mcparticleDaughter.p(); + genPtNeg = mcparticleDaughter.pt(); } else if (mcparticleDaughter.pdgCode() == 211) { piPlusMom = {mcparticleDaughter.px(), mcparticleDaughter.py(), mcparticleDaughter.pz()}; + genPPos = mcparticleDaughter.p(); + genPtPos = mcparticleDaughter.pt(); } } genMCmassPrPi = RecoDecay::m(array{antiProtonMom, piPlusMom}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); @@ -360,6 +387,8 @@ struct threebodyKFTask { for (auto& mcDaughter : mcparticle.daughters_as()) { if (std::abs(mcDaughter.pdgCode()) == bachelorPdgCode) { genDecayVtx = {mcDaughter.vx(), mcDaughter.vy(), mcDaughter.vz()}; + genPBach = mcDaughter.p(); + genPtBach = mcDaughter.pt(); } } double genMClifetime = RecoDecay::sqrtSumOfSquares(genDecayVtx[0] - mcparticle.vx(), genDecayVtx[1] - mcparticle.vy(), genDecayVtx[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); @@ -390,7 +419,7 @@ struct threebodyKFTask { -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -403,6 +432,7 @@ struct threebodyKFTask { mcparticle.phi(), mcparticle.eta(), mcparticle.y(), + genPPos, genPtPos, genPNeg, genPtNeg, genPBach, genPtBach, isTrueGenH3L, isTrueGenAntiH3L, mcparticle.pdgCode(), false, // is reconstructed diff --git a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx index b0a53668d4f..0f728f37574 100644 --- a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include "Framework/runDataProcessing.h" @@ -636,6 +638,8 @@ struct threebodyRecoTask { continue; } registry.fill(HIST("hEventCounter"), 2.5); + registry.fill(HIST("hCentFT0C"), collision.centFT0C()); + if (collision.mcCollisionId() >= 0) { isGoodCollision[collision.mcCollisionId()] = true; } diff --git a/PWGLF/TableProducer/Resonances/LFResonanceInitializer.cxx b/PWGLF/TableProducer/Resonances/LFResonanceInitializer.cxx index 0fa31113667..5f18062be42 100644 --- a/PWGLF/TableProducer/Resonances/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/Resonances/LFResonanceInitializer.cxx @@ -516,15 +516,15 @@ struct reso2initializer { v0.template posTrack_as().tpcNSigmaPi(), v0.template posTrack_as().tpcNSigmaKa(), v0.template posTrack_as().tpcNSigmaPr(), - v0.template posTrack_as().tofNSigmaPi(), - v0.template posTrack_as().tofNSigmaKa(), - v0.template posTrack_as().tofNSigmaPr(), v0.template negTrack_as().tpcNSigmaPi(), v0.template negTrack_as().tpcNSigmaKa(), v0.template negTrack_as().tpcNSigmaPr(), v0.template negTrack_as().tofNSigmaPi(), v0.template negTrack_as().tofNSigmaKa(), v0.template negTrack_as().tofNSigmaPr(), + v0.template posTrack_as().tofNSigmaPi(), + v0.template posTrack_as().tofNSigmaKa(), + v0.template posTrack_as().tofNSigmaPr(), v0.v0cosPA(), v0.dcaV0daughters(), v0.dcapostopv(), @@ -562,18 +562,18 @@ struct reso2initializer { casc.template posTrack_as().tpcNSigmaPi(), casc.template posTrack_as().tpcNSigmaKa(), casc.template posTrack_as().tpcNSigmaPr(), - casc.template posTrack_as().tofNSigmaPi(), - casc.template posTrack_as().tofNSigmaKa(), - casc.template posTrack_as().tofNSigmaPr(), casc.template negTrack_as().tpcNSigmaPi(), casc.template negTrack_as().tpcNSigmaKa(), casc.template negTrack_as().tpcNSigmaPr(), - casc.template negTrack_as().tofNSigmaPi(), - casc.template negTrack_as().tofNSigmaKa(), - casc.template negTrack_as().tofNSigmaPr(), casc.template bachelor_as().tpcNSigmaPi(), casc.template bachelor_as().tpcNSigmaKa(), casc.template bachelor_as().tpcNSigmaPr(), + casc.template posTrack_as().tofNSigmaPi(), + casc.template posTrack_as().tofNSigmaKa(), + casc.template posTrack_as().tofNSigmaPr(), + casc.template negTrack_as().tofNSigmaPi(), + casc.template negTrack_as().tofNSigmaKa(), + casc.template negTrack_as().tofNSigmaPr(), casc.template bachelor_as().tofNSigmaPi(), casc.template bachelor_as().tofNSigmaKa(), casc.template bachelor_as().tofNSigmaPr(), diff --git a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt index e75fbd9e573..582047b6b60 100644 --- a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt @@ -67,4 +67,9 @@ o2physics_add_dpl_workflow(v0coresconverter2 o2physics_add_dpl_workflow(v0mlscoresconverter SOURCES v0mlscoresconverter.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(stramccollisionconverter + SOURCES stramccollisionconverter.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/TableProducer/Strangeness/Converters/stramccollisionconverter.cxx b/PWGLF/TableProducer/Strangeness/Converters/stramccollisionconverter.cxx new file mode 100644 index 00000000000..8c7950dc4fd --- /dev/null +++ b/PWGLF/TableProducer/Strangeness/Converters/stramccollisionconverter.cxx @@ -0,0 +1,36 @@ +// 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 "PWGLF/DataModel/LFStrangenessTables.h" + +using namespace o2; +using namespace o2::framework; + +// Converts V0 version 001 to 002 +struct stramccollisionconverter { + Produces straMCCollisions_001; + + void process(aod::StraMCCollisions_000 const& straMCcoll) + { + for (auto& mccollision : straMCcoll) { + straMCCollisions_001(mccollision.posX(), mccollision.posY(), mccollision.posZ(), + mccollision.impactParameter(), 0.0f); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Strangeness/cascadeflow.cxx b/PWGLF/TableProducer/Strangeness/cascadeflow.cxx index 73cb3950016..5ae3308785d 100644 --- a/PWGLF/TableProducer/Strangeness/cascadeflow.cxx +++ b/PWGLF/TableProducer/Strangeness/cascadeflow.cxx @@ -165,7 +165,7 @@ struct cascadeFlow { Configurable> binsPtMl{"binsPtMl", std::vector{cascade_flow_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; Configurable> cutDirMl{"cutDirMl", std::vector{cascade_flow_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsMl{"cutsMl", {cascade_flow_cuts_ml::cuts[0], cascade_flow_cuts_ml::nBinsPt, cascade_flow_cuts_ml::nCutScores, cascade_flow_cuts_ml::labelsPt, cascade_flow_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; - Configurable nClassesMl{"nClassesMl", (int8_t)cascade_flow_cuts_ml::nCutScores, "Number of classes in ML model"}; + Configurable nClassesMl{"nClassesMl", static_cast(cascade_flow_cuts_ml::nCutScores), "Number of classes in ML model"}; o2::ccdb::CcdbApi ccdbApi; diff --git a/PWGLF/TableProducer/Strangeness/cascademcbuilder.cxx b/PWGLF/TableProducer/Strangeness/cascademcbuilder.cxx index 729ac3e27da..4e8e62d9db7 100644 --- a/PWGLF/TableProducer/Strangeness/cascademcbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/cascademcbuilder.cxx @@ -61,6 +61,8 @@ struct cascademcbuilder { Configurable addGeneratedOmegaMinus{"addGeneratedOmegaMinus", false, "add CascMCCore entry for generated, not-recoed OmegaMinus"}; Configurable addGeneratedOmegaPlus{"addGeneratedOmegaPlus", false, "add CascMCCore entry for generated, not-recoed OmegaPlus"}; + Configurable treatPiToMuDecays{"treatPiToMuDecays", true, "if true, will correctly capture pi -> mu and V0 label will still point to originating V0 decay in those cases. Nota bene: prong info will still be for the muon!"}; + Configurable rapidityWindow{"rapidityWindow", 0.5, "rapidity window to save non-recoed candidates"}; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -92,6 +94,36 @@ struct cascademcbuilder { mcCascinfo thisInfo; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* + // kink handling + template + int getOriginatingParticle(mcpart const& part, int& indexForPositionOfDecay) + { + int returnValue = -1; + if (part.has_mothers()) { + auto const& motherList = part.template mothers_as(); + if (motherList.size() == 1) { + for (const auto& mother : motherList) { + if (std::abs(part.pdgCode()) == 13 && treatPiToMuDecays) { + // muon decay, de-ref mother twice + if (mother.has_mothers()) { + auto grandMotherList = mother.template mothers_as(); + if (grandMotherList.size() == 1) { + for (const auto& grandMother : grandMotherList) { + returnValue = grandMother.globalIndex(); + indexForPositionOfDecay = mother.globalIndex(); // for V0 decay position: grab muon + } + } + } + } else { + returnValue = mother.globalIndex(); + indexForPositionOfDecay = part.globalIndex(); + } + } + } + } + return returnValue; + } + template void generateCascadeMCinfo(TCascadeTable cascTable, TMCParticleTable mcParticles) { @@ -147,51 +179,51 @@ struct cascademcbuilder { thisInfo.processNegative = lMCNegTrack.getProcess(); thisInfo.processBachelor = lMCBachTrack.getProcess(); - // Step 1: check if the mother is the same, go up a level - if (lMCNegTrack.has_mothers() && lMCPosTrack.has_mothers()) { - for (auto& lNegMother : lMCNegTrack.template mothers_as()) { - for (auto& lPosMother : lMCPosTrack.template mothers_as()) { - if (lNegMother == lPosMother) { - // acquire information - thisInfo.lxyz[0] = lMCPosTrack.vx(); - thisInfo.lxyz[1] = lMCPosTrack.vy(); - thisInfo.lxyz[2] = lMCPosTrack.vz(); - thisInfo.pdgCodeV0 = lNegMother.pdgCode(); + // Step 0: treat pi -> mu + antineutrino + // if present, de-reference original V0 correctly and provide label to original object + // NOTA BENE: the prong info will still correspond to a muon, treat carefully! + int negOriginating = -1, posOriginating = -1, bachOriginating = -1; + int particleForLambdaDecayPositionIdx = -1, particleForCascadeDecayPositionIdx = -1; + negOriginating = getOriginatingParticle(lMCNegTrack, particleForLambdaDecayPositionIdx); + posOriginating = getOriginatingParticle(lMCPosTrack, particleForLambdaDecayPositionIdx); + bachOriginating = getOriginatingParticle(lMCBachTrack, particleForCascadeDecayPositionIdx); + + if (negOriginating > -1 && negOriginating == posOriginating) { + auto originatingV0 = mcParticles.rawIteratorAt(negOriginating); + auto particleForLambdaDecayPosition = mcParticles.rawIteratorAt(particleForLambdaDecayPositionIdx); + + thisInfo.label = originatingV0.globalIndex(); + thisInfo.lxyz[0] = particleForLambdaDecayPosition.vx(); + thisInfo.lxyz[1] = particleForLambdaDecayPosition.vy(); + thisInfo.lxyz[2] = particleForLambdaDecayPosition.vz(); + + if (originatingV0.has_mothers()) { + for (auto& lV0Mother : originatingV0.template mothers_as()) { + if (lV0Mother.globalIndex() == bachOriginating) { // found mother particle + thisInfo.label = lV0Mother.globalIndex(); + + if (lV0Mother.has_mcCollision()) { + thisInfo.mcCollision = lV0Mother.mcCollisionId(); // save this reference, please + } - // if we got to this level, it means the mother particle exists and is the same - // now we have to go one level up and compare to the bachelor mother too - if (lNegMother.has_mothers() && lMCBachTrack.has_mothers()) { - for (auto& lV0Mother : lNegMother.template mothers_as()) { - for (auto& lBachMother : lMCBachTrack.template mothers_as()) { - if (lV0Mother == lBachMother) { - thisInfo.label = lV0Mother.globalIndex(); - - if (lV0Mother.has_mcCollision()) { - thisInfo.mcCollision = lV0Mother.mcCollisionId(); // save this reference, please - } - - thisInfo.pdgCode = lV0Mother.pdgCode(); - thisInfo.isPhysicalPrimary = lV0Mother.isPhysicalPrimary(); - thisInfo.xyz[0] = lMCBachTrack.vx(); - thisInfo.xyz[1] = lMCBachTrack.vy(); - thisInfo.xyz[2] = lMCBachTrack.vz(); - thisInfo.momentum[0] = lV0Mother.px(); - thisInfo.momentum[1] = lV0Mother.py(); - thisInfo.momentum[2] = lV0Mother.pz(); - if (lV0Mother.has_mothers()) { - for (auto& lV0GrandMother : lV0Mother.template mothers_as()) { - thisInfo.pdgCodeMother = lV0GrandMother.pdgCode(); - thisInfo.motherLabel = lV0GrandMother.globalIndex(); - } - } - } - } - } // end conditional V0-bach pair - } // end has mothers - } // end neg = pos mother conditional - } - } // end loop neg/pos mothers - } // end conditional of mothers existing + thisInfo.pdgCode = lV0Mother.pdgCode(); + thisInfo.isPhysicalPrimary = lV0Mother.isPhysicalPrimary(); + thisInfo.xyz[0] = originatingV0.vx(); + thisInfo.xyz[1] = originatingV0.vy(); + thisInfo.xyz[2] = originatingV0.vz(); + thisInfo.momentum[0] = lV0Mother.px(); + thisInfo.momentum[1] = lV0Mother.py(); + thisInfo.momentum[2] = lV0Mother.pz(); + if (lV0Mother.has_mothers()) { + for (auto& lV0GrandMother : lV0Mother.template mothers_as()) { + thisInfo.pdgCodeMother = lV0GrandMother.pdgCode(); + thisInfo.motherLabel = lV0GrandMother.globalIndex(); + } + } + } + } // end v0 mother loop + } // end has_mothers check for V0 + } // end conditional of pos/neg originating being the same } // end association check // Construct label table (note: this will be joinable with CascDatas) casclabels( diff --git a/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx b/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx index 0f8659fac38..0e14c0f491f 100644 --- a/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx +++ b/PWGLF/TableProducer/Strangeness/cascqaanalysis.cxx @@ -16,6 +16,9 @@ /// \modified by Roman Nepeivoda (roman.nepeivoda@cern.ch) /// \since June 1, 2023 +#include +#include + #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -57,6 +60,7 @@ struct cascqaanalysis { Configurable isTriggerTVX{"isTriggerTVX", 1, "TVX trigger"}; Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", 1, "TF border cut"}; Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", 1, "ITS ROF border cut"}; + Configurable isNoCollInTimeRangeNarrow{"isNoCollInTimeRangeNarrow", 1, "No collisions in +-2us window"}; // Cascade selection criteria Configurable scalefactor{"scalefactor", 1.0, "Scaling factor"}; @@ -115,9 +119,9 @@ struct cascqaanalysis { TString hCandidateCounterLabels[4] = {"All candidates", "passed topo cuts", "has associated MC particle", "associated with Xi(Omega)"}; TString hNEventsMCLabels[6] = {"All", "z vrtx", "INEL", "INEL>0", "INEL>1", "Associated with rec. collision"}; - TString hNEventsLabels[12] = {"All", "kIsTriggerTVX", "kNoTimeFrameBorder", "kNoITSROFrameBorder", "kIsVertexITSTPC", "kNoSameBunchPileup", "kIsGoodZvtxFT0vsPV", "isVertexTOFmatched", "z vrtx", "INEL", "INEL>0", "INEL>1"}; + TString hNEventsLabels[13] = {"All", "kIsTriggerTVX", "kNoTimeFrameBorder", "kNoITSROFrameBorder", "kIsVertexITSTPC", "kNoSameBunchPileup", "kIsGoodZvtxFT0vsPV", "isVertexTOFmatched", "kNoCollInTimeRangeNarrow", "z vrtx", "INEL", "INEL>0", "INEL>1"}; - registry.add("hNEvents", "hNEvents", {HistType::kTH1F, {{12, 0.f, 12.f}}}); + registry.add("hNEvents", "hNEvents", {HistType::kTH1F, {{13, 0.f, 13.f}}}); for (Int_t n = 1; n <= registry.get(HIST("hNEvents"))->GetNbinsX(); n++) { registry.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(n, hNEventsLabels[n - 1]); @@ -174,7 +178,7 @@ struct cascqaanalysis { aod::cascdata::dcaV0daughters < dcav0dau && aod::cascdata::dcacascdaughters < dcacascdau); - Partition pvContribTracksIUEta1 = (nabs(aod::track::eta) < 1.0f) && ((aod::track::flags & (uint32_t)o2::aod::track::PVContributor) == (uint32_t)o2::aod::track::PVContributor); + Partition pvContribTracksIUEta1 = (nabs(aod::track::eta) < 1.0f) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); Partition globalTracksIUEta05 = (nabs(aod::track::eta) < 0.5f) && (requireGlobalTrackInFilter()); template @@ -252,14 +256,14 @@ struct cascqaanalysis { { // 0 - INEL, 1 - INEL>0, 2 - INEL>1 int evFlag = 0; - registry.fill(HIST("hNEvents"), 9.5); // INEL + registry.fill(HIST("hNEvents"), 10.5); // INEL if (collision.isInelGt0()) { evFlag += 1; - registry.fill(HIST("hNEvents"), 10.5); // INEL>0 + registry.fill(HIST("hNEvents"), 11.5); // INEL>0 } if (collision.isInelGt1()) { evFlag += 1; - registry.fill(HIST("hNEvents"), 11.5); // INEL>1 + registry.fill(HIST("hNEvents"), 12.5); // INEL>1 } return evFlag; } @@ -326,13 +330,20 @@ struct cascqaanalysis { if (isFillEventSelectionQA) { registry.fill(HIST("hNEvents"), 7.5); } + // kNoCollInTimeRangeNarrow selection + if (isNoCollInTimeRangeNarrow && !collision.selection_bit(aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 8.5); + } // Z vertex selection if (TMath::Abs(collision.posZ()) > cutzvertex) { return false; } if (isFillEventSelectionQA) { - registry.fill(HIST("hNEvents"), 8.5); + registry.fill(HIST("hNEvents"), 9.5); registry.fill(HIST("hZCollision"), collision.posZ()); } @@ -472,15 +483,15 @@ struct cascqaanalysis { uint16_t nchFV0 = GetGenNchInFV0Aregion(mcPartSlice); int evType = 0; - registry.fill(HIST("hNEvents"), 9.5); // INEL + registry.fill(HIST("hNEvents"), 10.5); // INEL // Rec. collision associated with INEL>0 gen. one if (pwglf::isINELgtNmc(mcPartSlice, 0, pdgDB)) { - registry.fill(HIST("hNEvents"), 10.5); // INEL + registry.fill(HIST("hNEvents"), 11.5); // INEL evType++; } // Rec. collision associated with INEL>1 gen. one if (pwglf::isINELgtNmc(mcPartSlice, 1, pdgDB)) { - registry.fill(HIST("hNEvents"), 11.5); // INEL + registry.fill(HIST("hNEvents"), 12.5); // INEL evType++; } diff --git a/PWGLF/TableProducer/Strangeness/lambdakzeromcbuilder.cxx b/PWGLF/TableProducer/Strangeness/lambdakzeromcbuilder.cxx index a2324681040..1d7b1c29490 100644 --- a/PWGLF/TableProducer/Strangeness/lambdakzeromcbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/lambdakzeromcbuilder.cxx @@ -55,6 +55,8 @@ struct lambdakzeromcbuilder { Configurable addGeneratedAntiLambda{"addGeneratedAntiLambda", false, "add V0MCCore entry for generated, not-recoed AntiLambda"}; Configurable addGeneratedGamma{"addGeneratedGamma", false, "add V0MCCore entry for generated, not-recoed Gamma"}; + Configurable treatPiToMuDecays{"treatPiToMuDecays", true, "if true, will correctly capture pi -> mu and V0 label will still point to originating V0 decay in those cases. Nota bene: prong info will still be for the muon!"}; + Configurable rapidityWindow{"rapidityWindow", 0.5, "rapidity window to save non-recoed candidates"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -111,15 +113,38 @@ struct lambdakzeromcbuilder { std::array posP; std::array negP; std::array momentum; - uint64_t packedMcParticleIndices; }; mcV0info thisInfo; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - // prong index combiner - uint64_t combineProngIndices(uint32_t low, uint32_t high) + // kink handling + template + int getOriginatingParticle(mcpart const& part, int& indexForPositionOfDecay) { - return (((uint64_t)high) << 32) | ((uint64_t)low); + int returnValue = -1; + if (part.has_mothers()) { + auto const& motherList = part.template mothers_as(); + if (motherList.size() == 1) { + for (const auto& mother : motherList) { + if (std::abs(part.pdgCode()) == 13 && treatPiToMuDecays) { + // muon decay, de-ref mother twice + if (mother.has_mothers()) { + auto grandMotherList = mother.template mothers_as(); + if (grandMotherList.size() == 1) { + for (const auto& grandMother : grandMotherList) { + returnValue = grandMother.globalIndex(); + indexForPositionOfDecay = mother.globalIndex(); // for V0 decay position: grab muon + } + } + } + } else { + returnValue = mother.globalIndex(); + indexForPositionOfDecay = part.globalIndex(); + } + } + } + } + return returnValue; } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* @@ -131,7 +156,6 @@ struct lambdakzeromcbuilder { std::vector mcParticleIsReco(mcParticles.size(), false); // mc Particle not recoed by V0s for (auto& v0 : v0table) { - thisInfo.packedMcParticleIndices = 0; // not de-referenced properly yet thisInfo.label = -1; thisInfo.motherLabel = -1; thisInfo.pdgCode = 0; @@ -152,7 +176,6 @@ struct lambdakzeromcbuilder { auto lMCNegTrack = lNegTrack.mcParticle_as(); auto lMCPosTrack = lPosTrack.mcParticle_as(); - thisInfo.packedMcParticleIndices = combineProngIndices(lPosTrack.mcParticleId(), lNegTrack.mcParticleId()); thisInfo.pdgCodePositive = lMCPosTrack.pdgCode(); thisInfo.pdgCodeNegative = lMCNegTrack.pdgCode(); thisInfo.processPositive = lMCPosTrack.getProcess(); @@ -163,65 +186,71 @@ struct lambdakzeromcbuilder { thisInfo.negP[0] = lMCNegTrack.px(); thisInfo.negP[1] = lMCNegTrack.py(); thisInfo.negP[2] = lMCNegTrack.pz(); - if (lMCNegTrack.has_mothers() && lMCPosTrack.has_mothers()) { - for (auto& lNegMother : lMCNegTrack.mothers_as()) { - for (auto& lPosMother : lMCPosTrack.mothers_as()) { - if (lNegMother.globalIndex() == lPosMother.globalIndex()) { - thisInfo.label = lNegMother.globalIndex(); - thisInfo.xyz[0] = lMCPosTrack.vx(); - thisInfo.xyz[1] = lMCPosTrack.vy(); - thisInfo.xyz[2] = lMCPosTrack.vz(); - - // MC pos. and neg. daughters are the same! Looking for replacement... - if (lMCPosTrack.globalIndex() == lMCNegTrack.globalIndex()) { - auto const& daughters = lNegMother.daughters_as(); - for (auto& ldau : daughters) { - // check if the candidate originate from a decay - // if not, this is not a suitable candidate for one of the decay daughters - if (ldau.getProcess() != 4) // see TMCProcess.h - continue; - - if (lMCPosTrack.pdgCode() < 0 && ldau.pdgCode() > 0) { // the positive track needs to be changed - thisInfo.pdgCodePositive = ldau.pdgCode(); - thisInfo.processPositive = ldau.getProcess(); - thisInfo.posP[0] = ldau.px(); - thisInfo.posP[1] = ldau.py(); - thisInfo.posP[2] = ldau.pz(); - thisInfo.xyz[0] = ldau.vx(); - thisInfo.xyz[1] = ldau.vy(); - thisInfo.xyz[2] = ldau.vz(); - } - if (lMCNegTrack.pdgCode() > 0 && ldau.pdgCode() < 0) { // the negative track needs to be changed - thisInfo.pdgCodeNegative = ldau.pdgCode(); - thisInfo.processNegative = ldau.getProcess(); - thisInfo.negP[0] = ldau.px(); - thisInfo.negP[1] = ldau.py(); - thisInfo.negP[2] = ldau.pz(); - } - } - } - if (lNegMother.has_mcCollision()) { - thisInfo.mcCollision = lNegMother.mcCollisionId(); // save this reference, please - } + // check for pi -> mu + antineutrino decay + // if present, de-reference original V0 correctly and provide label to original object + // NOTA BENE: the prong info will still correspond to a muon, treat carefully! + int negOriginating = -1, posOriginating = -1, particleForDecayPositionIdx = -1; + negOriginating = getOriginatingParticle(lMCNegTrack, particleForDecayPositionIdx); + posOriginating = getOriginatingParticle(lMCPosTrack, particleForDecayPositionIdx); + + if (negOriginating > -1 && negOriginating == posOriginating) { + auto originatingV0 = mcParticles.rawIteratorAt(negOriginating); + auto particleForDecayPosition = mcParticles.rawIteratorAt(particleForDecayPositionIdx); + + thisInfo.label = originatingV0.globalIndex(); + thisInfo.xyz[0] = particleForDecayPosition.vx(); + thisInfo.xyz[1] = particleForDecayPosition.vy(); + thisInfo.xyz[2] = particleForDecayPosition.vz(); + + // MC pos. and neg. daughters are the same! Looking for replacement... + // if (lMCPosTrack.globalIndex() == lMCNegTrack.globalIndex()) { + // auto const& daughters = lNegMother.daughters_as(); + // for (auto& ldau : daughters) { + // // check if the candidate originates from a decay + // // if not, this is not a suitable candidate for one of the decay daughters + // if (ldau.getProcess() != 4) // see TMCProcess.h + // continue; + + // if (lMCPosTrack.pdgCode() < 0 && ldau.pdgCode() > 0) { // the positive track needs to be changed + // thisInfo.pdgCodePositive = ldau.pdgCode(); + // thisInfo.processPositive = ldau.getProcess(); + // thisInfo.posP[0] = ldau.px(); + // thisInfo.posP[1] = ldau.py(); + // thisInfo.posP[2] = ldau.pz(); + // thisInfo.xyz[0] = ldau.vx(); + // thisInfo.xyz[1] = ldau.vy(); + // thisInfo.xyz[2] = ldau.vz(); + // } + // if (lMCNegTrack.pdgCode() > 0 && ldau.pdgCode() < 0) { // the negative track needs to be changed + // thisInfo.pdgCodeNegative = ldau.pdgCode(); + // thisInfo.processNegative = ldau.getProcess(); + // thisInfo.negP[0] = ldau.px(); + // thisInfo.negP[1] = ldau.py(); + // thisInfo.negP[2] = ldau.pz(); + // } + // } + // } + + if (originatingV0.has_mcCollision()) { + thisInfo.mcCollision = originatingV0.mcCollisionId(); // save this reference, please + } - // acquire information - thisInfo.pdgCode = lNegMother.pdgCode(); - thisInfo.isPhysicalPrimary = lNegMother.isPhysicalPrimary(); - thisInfo.momentum[0] = lNegMother.px(); - thisInfo.momentum[1] = lNegMother.py(); - thisInfo.momentum[2] = lNegMother.pz(); - - if (lNegMother.has_mothers()) { - for (auto& lNegGrandMother : lNegMother.mothers_as()) { - thisInfo.pdgCodeMother = lNegGrandMother.pdgCode(); - thisInfo.motherLabel = lNegGrandMother.globalIndex(); - } - } - } + // acquire information + thisInfo.pdgCode = originatingV0.pdgCode(); + thisInfo.isPhysicalPrimary = originatingV0.isPhysicalPrimary(); + thisInfo.momentum[0] = originatingV0.px(); + thisInfo.momentum[1] = originatingV0.py(); + thisInfo.momentum[2] = originatingV0.pz(); + + if (originatingV0.has_mothers()) { + for (auto& lV0Mother : originatingV0.mothers_as()) { + thisInfo.pdgCodeMother = lV0Mother.pdgCode(); + thisInfo.motherLabel = lV0Mother.globalIndex(); } } } + } // end association check // Construct label table (note: this will be joinable with V0Datas!) v0labels( @@ -308,7 +337,6 @@ struct lambdakzeromcbuilder { if (populateV0MCCoresAsymmetric) { // first step: add any un-recoed v0mmcores that were requested for (auto& mcParticle : mcParticles) { - thisInfo.packedMcParticleIndices = 0; thisInfo.label = -1; thisInfo.motherLabel = -1; thisInfo.pdgCode = 0; diff --git a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx index edd4bdfa5e8..e6b7d2495a9 100644 --- a/PWGLF/TableProducer/Strangeness/sigma0builder.cxx +++ b/PWGLF/TableProducer/Strangeness/sigma0builder.cxx @@ -55,9 +55,9 @@ using namespace o2::framework; using namespace o2::framework::expressions; using std::array; using dauTracks = soa::Join; -using V0DerivedMCDatas = soa::Join; -using V0MLDerivedDatas = soa::Join; -using V0StandardDerivedDatas = soa::Join; +using V0DerivedMCDatas = soa::Join; +using V0MLDerivedDatas = soa::Join; +using V0StandardDerivedDatas = soa::Join; struct sigma0builder { SliceCache cache; @@ -106,7 +106,6 @@ struct sigma0builder { // Axis // base properties - ConfigurableAxis vertexZ{"vertexZ", {30, -15.0f, 15.0f}, ""}; 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 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, 100.0f, 110.0f}, "Centrality"}; ConfigurableAxis axisDeltaPt{"axisDeltaPt", {100, -1.0, +1.0}, "#Delta(p_{T})"}; @@ -134,7 +133,6 @@ struct sigma0builder { void init(InitContext const&) { // Event counter - histos.add("hEventVertexZ", "hEventVertexZ", kTH1F, {vertexZ}); histos.add("hEventCentrality", "hEventCentrality", kTH1F, {axisCentrality}); histos.add("hCandidateBuilderSelection", "hCandidateBuilderSelection", kTH1F, {axisCandSel}); histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(1, "No Sel"); @@ -151,45 +149,68 @@ struct sigma0builder { histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(12, "Sigma Mass Window"); histos.get(HIST("hCandidateBuilderSelection"))->GetXaxis()->SetBinLabel(13, "Sigma Y Window"); - // For efficiency calculation (and QA): - histos.add("GeneralQA/hPhotonMass", "hPhotonMass", kTH1F, {axisPhotonMass}); - histos.add("GeneralQA/hPhotonNegEta", "hPhotonNegEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hPhotonPosEta", "hPhotonPosEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hPhotonDCANegToPV", "hPhotonDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hPhotonDCAPosToPV", "hPhotonDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hPhotonDCADau", "hPhotonDCADau", kTH1F, {axisDCAdau}); - histos.add("GeneralQA/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); - histos.add("GeneralQA/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); - histos.add("GeneralQA/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); - histos.add("GeneralQA/hLambdaNegEta", "hLambdaNegEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hLambdaPosEta", "hLambdaPosEta", kTH1F, {axisRapidity}); - histos.add("GeneralQA/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); - histos.add("GeneralQA/hLambdaDCADau", "hLambdaDCADau", kTH1F, {axisDCAdau}); - histos.add("GeneralQA/hLambdaRadius", "hLambdaRadius", kTH1F, {axisRadius}); - histos.add("GeneralQA/hSigmaMass", "hSigmaMass", kTH1F, {axisSigmaMass}); - histos.add("GeneralQA/hSigmaMassWindow", "hSigmaMassWindow", kTH1F, {{1000, -0.09f, 0.11f}}); - histos.add("GeneralQA/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); - - histos.add("Efficiency/h2dPtVsCentrality_GammaAll", "h2dPtVsCentrality_GammaAll", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_LambdaAll", "h2dPtVsCentrality_LambdaAll", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_AntiLambdaAll", "h2dPtVsCentrality_AntiLambdaAll", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_GammaSigma0", "h2dPtVsCentrality_GammaSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_LambdaSigma0", "h2dPtVsCentrality_LambdaSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_Sigma0All", "h2dPtVsCentrality_Sigma0All", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_Sigma0AfterSel", "h2dPtVsCentrality_Sigma0AfterSel", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_AntiSigma0All", "h2dPtVsCentrality_AntiSigma0All", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_GammaAntiSigma0", "h2dPtVsCentrality_GammaAntiSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_LambdaAntiSigma0", "h2dPtVsCentrality_LambdaAntiSigma0", kTH2D, {axisCentrality, axisPt}); - histos.add("Efficiency/h2dPtVsCentrality_AntiSigma0AfterSel", "h2dPtVsCentrality_AntiSigma0AfterSel", kTH2D, {axisCentrality, axisPt}); - - histos.add("Efficiency/h2dSigmaPtVsLambdaPt", "h2dSigmaPtVsLambdaPt", kTH2D, {axisPt, axisPt}); - histos.add("Efficiency/h2dSigmaPtVsGammaPt", "h2dSigmaPtVsGammaPt", kTH2D, {axisPt, axisPt}); - - histos.add("Efficiency/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2D, {axisPt, axisDeltaPt}); - histos.add("Efficiency/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisPt, axisDeltaPt}); - - histos.add("h3dMassSigmasAll", "h3dMassSigmasAll", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); + // For QA: + histos.add("Selection/hPhotonMass", "hPhotonMass", kTH1F, {axisPhotonMass}); + histos.add("Selection/hPhotonNegEta", "hPhotonNegEta", kTH1F, {axisRapidity}); + histos.add("Selection/hPhotonPosEta", "hPhotonPosEta", kTH1F, {axisRapidity}); + histos.add("Selection/hPhotonDCANegToPV", "hPhotonDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add("Selection/hPhotonDCAPosToPV", "hPhotonDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add("Selection/hPhotonDCADau", "hPhotonDCADau", kTH1F, {axisDCAdau}); + histos.add("Selection/hPhotonRadius", "hPhotonRadius", kTH1F, {axisRadius}); + histos.add("Selection/hLambdaMass", "hLambdaMass", kTH1F, {axisLambdaMass}); + histos.add("Selection/hAntiLambdaMass", "hAntiLambdaMass", kTH1F, {axisLambdaMass}); + histos.add("Selection/hLambdaNegEta", "hLambdaNegEta", kTH1F, {axisRapidity}); + histos.add("Selection/hLambdaPosEta", "hLambdaPosEta", kTH1F, {axisRapidity}); + histos.add("Selection/hLambdaDCANegToPV", "hLambdaDCANegToPV", kTH1F, {axisDCAtoPV}); + histos.add("Selection/hLambdaDCAPosToPV", "hLambdaDCAPosToPV", kTH1F, {axisDCAtoPV}); + histos.add("Selection/hLambdaDCADau", "hLambdaDCADau", kTH1F, {axisDCAdau}); + histos.add("Selection/hLambdaRadius", "hLambdaRadius", kTH1F, {axisRadius}); + histos.add("Selection/hSigmaMass", "hSigmaMass", kTH1F, {axisSigmaMass}); + histos.add("Selection/hSigmaMassWindow", "hSigmaMassWindow", kTH1F, {{1000, -0.09f, 0.11f}}); + histos.add("Selection/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); + + histos.add("GeneralQA/h2dMassGammaVsK0S", "h2dMassGammaVsK0S", kTH2D, {axisPhotonMass, {200, 0.4f, 0.6f}}); + histos.add("GeneralQA/h2dMassLambdaVsK0S", "h2dMassLambdaVsK0S", kTH2D, {axisLambdaMass, {200, 0.4f, 0.6f}}); + histos.add("GeneralQA/h2dMassGammaVsLambda", "h2dMassGammaVsLambda", kTH2D, {axisPhotonMass, axisLambdaMass}); + histos.add("GeneralQA/h3dMassSigma0VsDaupTs", "h3dMassSigma0VsDaupTs", kTH3F, {axisPt, axisPt, axisSigmaMass}); + histos.add("GeneralQA/h2dMassGammaVsK0SAfterMassSel", "h2dMassGammaVsK0SAfterMassSel", kTH2D, {axisPhotonMass, {200, 0.4f, 0.6f}}); + histos.add("GeneralQA/h2dMassLambdaVsK0SAfterMassSel", "h2dMassLambdaVsK0SAfterMassSel", kTH2D, {axisLambdaMass, {200, 0.4f, 0.6f}}); + histos.add("GeneralQA/h2dMassGammaVsLambdaAfterMassSel", "h2dMassGammaVsLambdaAfterMassSel", kTH2D, {axisPhotonMass, axisLambdaMass}); + + // MC + histos.add("MC/h2dPtVsCentrality_GammaBeforeSel", "h2dPtVsCentrality_GammaBeforeSel", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_LambdaBeforeSel", "h2dPtVsCentrality_LambdaBeforeSel", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_AntiLambdaBeforeSel", "h2dPtVsCentrality_AntiLambdaBeforeSel", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_GammaSigma0", "h2dPtVsCentrality_GammaSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_LambdaSigma0", "h2dPtVsCentrality_LambdaSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_Sigma0BeforeSel", "h2dPtVsCentrality_Sigma0BeforeSel", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_Sigma0AfterSel", "h2dPtVsCentrality_Sigma0AfterSel", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_AntiSigma0BeforeSel", "h2dPtVsCentrality_AntiSigma0BeforeSel", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_GammaAntiSigma0", "h2dPtVsCentrality_GammaAntiSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_LambdaAntiSigma0", "h2dPtVsCentrality_LambdaAntiSigma0", kTH2D, {axisCentrality, axisPt}); + histos.add("MC/h2dPtVsCentrality_AntiSigma0AfterSel", "h2dPtVsCentrality_AntiSigma0AfterSel", kTH2D, {axisCentrality, axisPt}); + + // Sigma vs Daughters pT + histos.add("MC/h2dSigmaPtVsLambdaPt", "h2dSigmaPtVsLambdaPt", kTH2D, {axisPt, axisPt}); + histos.add("MC/h2dSigmaPtVsGammaPt", "h2dSigmaPtVsGammaPt", kTH2D, {axisPt, axisPt}); + + // pT Resolution: + histos.add("MC/h2dLambdaPtResolution", "h2dLambdaPtResolution", kTH2D, {axisPt, axisDeltaPt}); + histos.add("MC/h2dGammaPtResolution", "h2dGammaPtResolution", kTH2D, {axisPt, axisDeltaPt}); + + // For background decomposition + histos.add("MC/h2dPtVsMassSigma_All", "h2dPtVsMassSigma_All", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_SignalOnly", "h2dPtVsMassSigma_SignalOnly", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("MC/h2dTrueGammaFakeLambdaMatrix", "h2dTrueGammaFakeLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("MC/h2dFakeGammaTrueLambdaMatrix", "h2dFakeGammaTrueLambdaMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + histos.add("MC/h2dFakeDaughtersMatrix", "h2dFakeDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + + histos.add("h3dMassSigmasBeforeSel", "h3dMassSigmasBeforeSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); histos.add("h3dMassSigmasAfterSel", "h3dMassSigmasAfterSel", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); } @@ -200,6 +221,10 @@ struct sigma0builder { if ((lambda.v0Type() == 0) || (gamma.v0Type() == 0)) return false; + // Checking if both V0s are made of the very same tracks + if ((gamma.posTrackExtraId() == lambda.posTrackExtraId()) || (gamma.negTrackExtraId() == lambda.negTrackExtraId()) || (gamma.posTrackExtraId() == lambda.negTrackExtraId()) || (gamma.negTrackExtraId() == lambda.posTrackExtraId()) || (gamma.posTrackExtraId() == lambda.negTrackExtraId())) + return false; + if constexpr ( requires { gamma.gammaBDTScore(); } && requires { lambda.lambdaBDTScore(); } && @@ -218,49 +243,49 @@ struct sigma0builder { // Standard selection // Gamma basic selection criteria: histos.fill(HIST("hCandidateBuilderSelection"), 1.); - histos.fill(HIST("GeneralQA/hPhotonMass"), gamma.mGamma()); + histos.fill(HIST("Selection/hPhotonMass"), gamma.mGamma()); if ((gamma.mGamma() < 0) || (gamma.mGamma() > PhotonMaxMass)) return false; - histos.fill(HIST("GeneralQA/hPhotonNegEta"), gamma.negativeeta()); - histos.fill(HIST("GeneralQA/hPhotonPosEta"), gamma.positiveeta()); + histos.fill(HIST("Selection/hPhotonNegEta"), gamma.negativeeta()); + histos.fill(HIST("Selection/hPhotonPosEta"), gamma.positiveeta()); histos.fill(HIST("hCandidateBuilderSelection"), 2.); if ((TMath::Abs(gamma.negativeeta()) > PhotonMaxDauPseudoRap) || (TMath::Abs(gamma.positiveeta()) > PhotonMaxDauPseudoRap)) return false; - histos.fill(HIST("GeneralQA/hPhotonDCANegToPV"), TMath::Abs(gamma.dcanegtopv())); - histos.fill(HIST("GeneralQA/hPhotonDCAPosToPV"), TMath::Abs(gamma.dcapostopv())); + histos.fill(HIST("Selection/hPhotonDCANegToPV"), TMath::Abs(gamma.dcanegtopv())); + histos.fill(HIST("Selection/hPhotonDCAPosToPV"), TMath::Abs(gamma.dcapostopv())); histos.fill(HIST("hCandidateBuilderSelection"), 3.); if ((TMath::Abs(gamma.dcapostopv()) < PhotonMinDCAToPv) || (TMath::Abs(gamma.dcanegtopv()) < PhotonMinDCAToPv)) return false; - histos.fill(HIST("GeneralQA/hPhotonDCADau"), TMath::Abs(gamma.dcaV0daughters())); + histos.fill(HIST("Selection/hPhotonDCADau"), TMath::Abs(gamma.dcaV0daughters())); histos.fill(HIST("hCandidateBuilderSelection"), 4.); if (TMath::Abs(gamma.dcaV0daughters()) > PhotonMaxDCAV0Dau) return false; - histos.fill(HIST("GeneralQA/hPhotonRadius"), gamma.v0radius()); + histos.fill(HIST("Selection/hPhotonRadius"), gamma.v0radius()); histos.fill(HIST("hCandidateBuilderSelection"), 5.); if ((gamma.v0radius() < PhotonMinRadius) || (gamma.v0radius() > PhotonMaxRadius)) return false; histos.fill(HIST("hCandidateBuilderSelection"), 6.); - histos.fill(HIST("GeneralQA/hLambdaMass"), lambda.mLambda()); - histos.fill(HIST("GeneralQA/hAntiLambdaMass"), lambda.mAntiLambda()); + histos.fill(HIST("Selection/hLambdaMass"), lambda.mLambda()); + histos.fill(HIST("Selection/hAntiLambdaMass"), lambda.mAntiLambda()); // Lambda basic selection criteria: if ((TMath::Abs(lambda.mLambda() - 1.115683) > LambdaWindow) && (TMath::Abs(lambda.mAntiLambda() - 1.115683) > LambdaWindow)) return false; - histos.fill(HIST("GeneralQA/hLambdaNegEta"), lambda.negativeeta()); - histos.fill(HIST("GeneralQA/hLambdaPosEta"), lambda.positiveeta()); + histos.fill(HIST("Selection/hLambdaNegEta"), lambda.negativeeta()); + histos.fill(HIST("Selection/hLambdaPosEta"), lambda.positiveeta()); histos.fill(HIST("hCandidateBuilderSelection"), 7.); if ((TMath::Abs(lambda.negativeeta()) > LambdaDauPseudoRap) || (TMath::Abs(lambda.positiveeta()) > LambdaDauPseudoRap)) return false; - histos.fill(HIST("GeneralQA/hLambdaDCANegToPV"), lambda.dcanegtopv()); - histos.fill(HIST("GeneralQA/hLambdaDCAPosToPV"), lambda.dcapostopv()); + histos.fill(HIST("Selection/hLambdaDCANegToPV"), lambda.dcanegtopv()); + histos.fill(HIST("Selection/hLambdaDCAPosToPV"), lambda.dcapostopv()); histos.fill(HIST("hCandidateBuilderSelection"), 8.); if ((TMath::Abs(lambda.dcapostopv()) < LambdaMinDCAPosToPv) || (TMath::Abs(lambda.dcanegtopv()) < LambdaMinDCANegToPv)) return false; - histos.fill(HIST("GeneralQA/hLambdaRadius"), lambda.v0radius()); + histos.fill(HIST("Selection/hLambdaRadius"), lambda.v0radius()); histos.fill(HIST("hCandidateBuilderSelection"), 9.); if ((lambda.v0radius() < LambdaMinv0radius) || (lambda.v0radius() > LambdaMaxv0radius)) return false; - histos.fill(HIST("GeneralQA/hLambdaDCADau"), lambda.dcaV0daughters()); + histos.fill(HIST("Selection/hLambdaDCADau"), lambda.dcaV0daughters()); histos.fill(HIST("hCandidateBuilderSelection"), 10.); if (TMath::Abs(lambda.dcaV0daughters()) > LambdaMaxDCAV0Dau) return false; @@ -272,21 +297,57 @@ struct sigma0builder { auto arrMom = std::array{pVecPhotons, pVecLambda}; float sigmamass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); float sigmarap = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); + float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); + + histos.fill(HIST("Selection/hSigmaMass"), sigmamass); + histos.fill(HIST("Selection/hSigmaMassWindow"), sigmamass - 1.192642); + histos.fill(HIST("GeneralQA/h2dMassGammaVsK0S"), gamma.mGamma(), gamma.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0S"), lambda.mLambda(), lambda.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassGammaVsLambda"), gamma.mGamma(), lambda.mLambda()); + histos.fill(HIST("GeneralQA/h3dMassSigma0VsDaupTs"), gamma.pt(), lambda.pt(), sigmamass); + + if constexpr (requires { gamma.pdgCode(); } && requires { lambda.pdgCode(); }) { + + histos.fill(HIST("MC/h2dPtVsMassSigma_All"), SigmapT, sigmamass); + + // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! + if ((gamma.pdgCode() == 22) && ((lambda.pdgCode() == 3122) || (lambda.pdgCode() == -3122)) && (gamma.motherMCPartId() != lambda.motherMCPartId())) { + histos.fill(HIST("MC/h2dPtVsMassSigma_TrueDaughters"), SigmapT, sigmamass); + histos.fill(HIST("MC/h2dTrueDaughtersMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); + } + + // Real Gamma x fake Lambda + if ((gamma.pdgCode() == 22) && (lambda.pdgCode() != 3122) && (lambda.pdgCode() != -3122)) { + histos.fill(HIST("MC/h2dPtVsMassSigma_TrueGammaFakeLambda"), SigmapT, sigmamass); + histos.fill(HIST("MC/h2dTrueGammaFakeLambdaMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); + } + + // Fake Gamma x Real Lambda + if ((gamma.pdgCode() != 22) && ((lambda.pdgCode() == 3122) || (lambda.pdgCode() == -3122))) { + histos.fill(HIST("MC/h2dPtVsMassSigma_FakeGammaTrueLambda"), SigmapT, sigmamass); + histos.fill(HIST("MC/h2dFakeGammaTrueLambdaMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); + } - histos.fill(HIST("GeneralQA/hSigmaMass"), sigmamass); - histos.fill(HIST("GeneralQA/hSigmaMassWindow"), sigmamass - 1.192642); + // Fake Gamma x Fake Lambda + if ((gamma.pdgCode() != 22) && (lambda.pdgCode() != 3122) && (lambda.pdgCode() != -3122)) { + histos.fill(HIST("MC/h2dPtVsMassSigma_FakeDaughters"), SigmapT, sigmamass); + histos.fill(HIST("MC/h2dFakeDaughtersMatrix"), lambda.pdgCodeMother(), gamma.pdgCodeMother()); + } + } if (TMath::Abs(sigmamass - 1.192642) > Sigma0Window) return false; + histos.fill(HIST("GeneralQA/h2dMassGammaVsK0SAfterMassSel"), gamma.mGamma(), gamma.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassLambdaVsK0SAfterMassSel"), lambda.mLambda(), lambda.mK0Short()); + histos.fill(HIST("GeneralQA/h2dMassGammaVsLambdaAfterMassSel"), gamma.mGamma(), lambda.mLambda()); + histos.fill(HIST("Selection/hSigmaY"), sigmarap); histos.fill(HIST("hCandidateBuilderSelection"), 12.); - histos.fill(HIST("GeneralQA/hSigmaY"), sigmarap); if (TMath::Abs(sigmarap) > SigmaMaxRap) return false; histos.fill(HIST("hCandidateBuilderSelection"), 13.); - return true; } // Helper struct to pass v0 information @@ -294,6 +355,9 @@ struct sigma0builder { float mass; float pT; float Rapidity; + float OPAngle; + float DeltaEta; + float DeltaPhi; } sigmaCandidate; // Fill tables with reconstructed sigma0 candidate @@ -315,19 +379,6 @@ struct sigma0builder { AntiLambdaBDTScore = lambda.antiLambdaBDTScore(); } - // Sigma0 candidate properties - std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; - std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; - auto arrMom = std::array{pVecPhotons, pVecLambda}; - sigmaCandidate.mass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); - sigmaCandidate.pT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); - sigmaCandidate.Rapidity = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); - - // Sigma related - float fSigmapT = sigmaCandidate.pT; - float fSigmaMass = sigmaCandidate.mass; - float fSigmaRap = sigmaCandidate.Rapidity; - // Daughters related /// Photon auto posTrackGamma = gamma.template posTrackExtra_as(); @@ -345,6 +396,7 @@ struct sigma0builder { float fPhotonZconv = gamma.z(); float fPhotonEta = gamma.eta(); float fPhotonY = RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma); + float fPhotonPhi = RecoDecay::phi(gamma.px(), gamma.py()); float fPhotonPosTPCNSigma = posTrackGamma.tpcNSigmaEl(); float fPhotonNegTPCNSigma = negTrackGamma.tpcNSigmaEl(); uint8_t fPhotonPosTPCCrossedRows = posTrackGamma.tpcCrossedRows(); @@ -378,10 +430,17 @@ struct sigma0builder { float fLambdaDCAPosPV = lambda.dcapostopv(); float fLambdaEta = lambda.eta(); float fLambdaY = lambda.yLambda(); + float fLambdaPhi = RecoDecay::phi(lambda.px(), lambda.py()); float fLambdaPosPrTPCNSigma = posTrackLambda.tpcNSigmaPr(); float fLambdaPosPiTPCNSigma = posTrackLambda.tpcNSigmaPi(); float fLambdaNegPrTPCNSigma = negTrackLambda.tpcNSigmaPr(); float fLambdaNegPiTPCNSigma = negTrackLambda.tpcNSigmaPi(); + + float fLambdaPrTOFNSigma = lambda.tofNSigmaLaPr(); + float fLambdaPiTOFNSigma = lambda.tofNSigmaLaPi(); + float fALambdaPrTOFNSigma = lambda.tofNSigmaALaPr(); + float fALambdaPiTOFNSigma = lambda.tofNSigmaALaPi(); + uint8_t fLambdaPosTPCCrossedRows = posTrackLambda.tpcCrossedRows(); uint8_t fLambdaNegTPCCrossedRows = negTrackLambda.tpcCrossedRows(); float fLambdaPosPt = lambda.positivept(); @@ -398,12 +457,34 @@ struct sigma0builder { uint32_t fLambdaNegITSClSize = negTrackLambda.itsClusterSizes(); uint8_t fLambdaV0Type = lambda.v0Type(); + // Sigma0 candidate properties + std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; + std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; + TVector3 v1(gamma.px(), gamma.py(), gamma.pz()); + TVector3 v2(lambda.px(), lambda.py(), lambda.pz()); + + sigmaCandidate.mass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + sigmaCandidate.pT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); + sigmaCandidate.Rapidity = RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0); + sigmaCandidate.OPAngle = v1.Angle(v2); + sigmaCandidate.DeltaEta = fLambdaEta - fPhotonEta; + sigmaCandidate.DeltaPhi = fLambdaPhi - fPhotonPhi; + + // Sigma related + float fSigmapT = sigmaCandidate.pT; + float fSigmaMass = sigmaCandidate.mass; + float fSigmaRap = sigmaCandidate.Rapidity; + float fSigmaOPAngle = sigmaCandidate.OPAngle; + float fSigmaDeltaEta = sigmaCandidate.DeltaEta; + float fSigmaDeltaPhi = sigmaCandidate.DeltaPhi; + // Filling TTree for ML analysis - sigma0cores(fSigmapT, fSigmaMass, fSigmaRap); + sigma0cores(fSigmapT, fSigmaMass, fSigmaRap, fSigmaOPAngle, fSigmaDeltaEta, fSigmaDeltaPhi); sigmaPhotonExtras(fPhotonPt, fPhotonMass, fPhotonQt, fPhotonAlpha, fPhotonRadius, fPhotonCosPA, fPhotonDCADau, fPhotonDCANegPV, fPhotonDCAPosPV, fPhotonZconv, - fPhotonEta, fPhotonY, fPhotonPosTPCNSigma, fPhotonNegTPCNSigma, fPhotonPosTPCCrossedRows, + fPhotonEta, fPhotonY, fPhotonPhi, fPhotonPosTPCNSigma, fPhotonNegTPCNSigma, fPhotonPosTPCCrossedRows, fPhotonNegTPCCrossedRows, fPhotonPosPt, fPhotonNegPt, fPhotonPosEta, fPhotonNegEta, fPhotonPosY, fPhotonNegY, fPhotonPsiPair, fPhotonPosITSCls, fPhotonNegITSCls, fPhotonPosITSClSize, fPhotonNegITSClSize, @@ -411,9 +492,10 @@ struct sigma0builder { sigmaLambdaExtras(fLambdaPt, fLambdaMass, fAntiLambdaMass, fLambdaQt, fLambdaAlpha, fLambdaRadius, fLambdaCosPA, fLambdaDCADau, fLambdaDCANegPV, - fLambdaDCAPosPV, fLambdaEta, fLambdaY, fLambdaPosPrTPCNSigma, - fLambdaPosPiTPCNSigma, fLambdaNegPrTPCNSigma, fLambdaNegPiTPCNSigma, fLambdaPosTPCCrossedRows, - fLambdaNegTPCCrossedRows, fLambdaPosPt, fLambdaNegPt, fLambdaPosEta, + fLambdaDCAPosPV, fLambdaEta, fLambdaY, fLambdaPhi, fLambdaPosPrTPCNSigma, + fLambdaPosPiTPCNSigma, fLambdaNegPrTPCNSigma, fLambdaNegPiTPCNSigma, + fLambdaPrTOFNSigma, fLambdaPiTOFNSigma, fALambdaPrTOFNSigma, fALambdaPiTOFNSigma, + fLambdaPosTPCCrossedRows, fLambdaNegTPCCrossedRows, fLambdaPosPt, fLambdaNegPt, fLambdaPosEta, fLambdaNegEta, fLambdaPosPrY, fLambdaPosPiY, fLambdaNegPrY, fLambdaNegPiY, fLambdaPosITSCls, fLambdaNegITSCls, fLambdaPosITSClSize, fLambdaNegITSClSize, fLambdaV0Type, LambdaBDTScore, AntiLambdaBDTScore); @@ -427,8 +509,7 @@ struct sigma0builder { auto V0Table_thisCollision = V0s.sliceBy(perCollisionMCDerived, collIdx); // V0 table sliced - for (auto& gamma : V0Table_thisCollision) { // selecting photons from Sigma0 - + for (auto& gamma : V0Table_thisCollision) { // selecting photons from Sigma0 float centrality = coll.centFT0C(); // Auxiliary histograms: @@ -436,39 +517,38 @@ struct sigma0builder { float GammaY = TMath::Abs(RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassGamma)); if (GammaY < 0.5) { // rapidity selection - histos.fill(HIST("Efficiency/h2dPtVsCentrality_GammaAll"), centrality, gamma.pt()); // isgamma - histos.fill(HIST("Efficiency/h2dGammaPtResolution"), gamma.pt(), gamma.pt() - RecoDecay::pt(array{gamma.pxMC(), gamma.pyMC()})); // pT resolution + histos.fill(HIST("MC/h2dPtVsCentrality_GammaBeforeSel"), centrality, gamma.pt()); // isgamma + histos.fill(HIST("MC/h2dGammaPtResolution"), gamma.pt(), gamma.pt() - RecoDecay::pt(array{gamma.pxMC(), gamma.pyMC()})); // pT resolution if (gamma.pdgCodeMother() == 3212) { - histos.fill(HIST("Efficiency/h2dPtVsCentrality_GammaSigma0"), centrality, gamma.pt()); // isgamma from sigma + histos.fill(HIST("MC/h2dPtVsCentrality_GammaSigma0"), centrality, gamma.pt()); // isgamma from sigma } if (gamma.pdgCodeMother() == -3212) { - histos.fill(HIST("Efficiency/h2dPtVsCentrality_GammaAntiSigma0"), centrality, gamma.pt()); // isgamma from sigma + histos.fill(HIST("MC/h2dPtVsCentrality_GammaAntiSigma0"), centrality, gamma.pt()); // isgamma from sigma } } } if (gamma.pdgCode() == 3122) { // Is Lambda float LambdaY = TMath::Abs(RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassLambda)); if (LambdaY < 0.5) { // rapidity selection - histos.fill(HIST("Efficiency/h2dPtVsCentrality_LambdaAll"), centrality, gamma.pt()); - histos.fill(HIST("Efficiency/h2dLambdaPtResolution"), gamma.pt(), gamma.pt() - RecoDecay::pt(array{gamma.pxMC(), gamma.pyMC()})); // pT resolution + histos.fill(HIST("MC/h2dPtVsCentrality_LambdaBeforeSel"), centrality, gamma.pt()); + histos.fill(HIST("MC/h2dLambdaPtResolution"), gamma.pt(), gamma.pt() - RecoDecay::pt(array{gamma.pxMC(), gamma.pyMC()})); // pT resolution if (gamma.pdgCodeMother() == 3212) { - histos.fill(HIST("Efficiency/h2dPtVsCentrality_LambdaSigma0"), centrality, gamma.pt()); + histos.fill(HIST("MC/h2dPtVsCentrality_LambdaSigma0"), centrality, gamma.pt()); } } } if (gamma.pdgCode() == -3122) { // Is AntiLambda float AntiLambdaY = TMath::Abs(RecoDecay::y(std::array{gamma.px(), gamma.py(), gamma.pz()}, o2::constants::physics::MassLambda)); if (AntiLambdaY < 0.5) { // rapidity selection - histos.fill(HIST("Efficiency/h2dPtVsCentrality_AntiLambdaAll"), centrality, gamma.pt()); + histos.fill(HIST("MC/h2dPtVsCentrality_AntiLambdaBeforeSel"), centrality, gamma.pt()); if (gamma.pdgCodeMother() == -3212) { - histos.fill(HIST("Efficiency/h2dPtVsCentrality_LambdaAntiSigma0"), centrality, gamma.pt()); // isantilambda from antisigma + histos.fill(HIST("MC/h2dPtVsCentrality_LambdaAntiSigma0"), centrality, gamma.pt()); // isantilambda from antisigma } } } for (auto& lambda : V0Table_thisCollision) { // selecting lambdas from Sigma0 - // Sigma0 candidate properties std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; @@ -477,31 +557,43 @@ struct sigma0builder { float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); float SigmaY = TMath::Abs(RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0)); - histos.fill(HIST("h3dMassSigmasAll"), centrality, SigmapT, SigmaMass); - if ((gamma.pdgCode() == 22) && (gamma.pdgCodeMother() == 3212) && (lambda.pdgCode() == 3122) && (lambda.pdgCodeMother() == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId()) && (SigmaY < 0.5)) { - histos.fill(HIST("Efficiency/h2dPtVsCentrality_Sigma0All"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); - histos.fill(HIST("Efficiency/h2dSigmaPtVsLambdaPt"), SigmapT, lambda.pt()); - histos.fill(HIST("Efficiency/h2dSigmaPtVsGammaPt"), SigmapT, gamma.pt()); + histos.fill(HIST("MC/h2dPtVsCentrality_Sigma0BeforeSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); + histos.fill(HIST("MC/h2dSigmaPtVsLambdaPt"), SigmapT, lambda.pt()); + histos.fill(HIST("MC/h2dSigmaPtVsGammaPt"), SigmapT, gamma.pt()); } if ((gamma.pdgCode() == 22) && (gamma.pdgCodeMother() == -3212) && (lambda.pdgCode() == -3122) && (lambda.pdgCodeMother() == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId()) && (SigmaY < 0.5)) - histos.fill(HIST("Efficiency/h2dPtVsCentrality_AntiSigma0All"), centrality, SigmapT); + histos.fill(HIST("MC/h2dPtVsCentrality_AntiSigma0BeforeSel"), centrality, SigmapT); if (!processSigmaCandidate(lambda, gamma)) // basic selection continue; bool fIsSigma = false; bool fIsAntiSigma = false; - histos.fill(HIST("h3dMassSigmasAfterSel"), centrality, SigmapT, SigmaMass); + bool fIsPhotonPrimary = gamma.isPhysicalPrimary(); + int PhotonCandPDGCode = gamma.pdgCode(); + int PhotonCandPDGCodeMother = gamma.pdgCodeMother(); + bool fIsLambdaPrimary = lambda.isPhysicalPrimary(); + int LambdaCandPDGCode = lambda.pdgCode(); + int LambdaCandPDGCodeMother = lambda.pdgCodeMother(); + if ((gamma.pdgCode() == 22) && (gamma.pdgCodeMother() == 3212) && (lambda.pdgCode() == 3122) && (lambda.pdgCodeMother() == 3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) { fIsSigma = true; - histos.fill(HIST("Efficiency/h2dPtVsCentrality_Sigma0AfterSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); + histos.fill(HIST("MC/h2dPtVsCentrality_Sigma0AfterSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); } if ((gamma.pdgCode() == 22) && (gamma.pdgCodeMother() == -3212) && (lambda.pdgCode() == -3122) && (lambda.pdgCodeMother() == -3212) && (gamma.motherMCPartId() == lambda.motherMCPartId())) { fIsAntiSigma = true; - histos.fill(HIST("Efficiency/h2dPtVsCentrality_AntiSigma0AfterSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); + histos.fill(HIST("MC/h2dPtVsCentrality_AntiSigma0AfterSel"), centrality, RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()})); + // TH3D Mass histogram } - sigma0mccores(fIsSigma, fIsAntiSigma); + sigma0mccores(fIsSigma, fIsAntiSigma, + PhotonCandPDGCode, PhotonCandPDGCodeMother, fIsPhotonPrimary, + LambdaCandPDGCode, LambdaCandPDGCodeMother, fIsLambdaPrimary); + + // QA histograms + // Signal only (sigma0+antisigma0) + if (fIsSigma || fIsAntiSigma) + histos.fill(HIST("MC/h2dPtVsMassSigma_SignalOnly"), SigmapT, SigmaMass); } } } @@ -514,23 +606,32 @@ struct sigma0builder { const uint64_t collIdx = coll.globalIndex(); auto V0Table_thisCollision = V0s.sliceBy(perCollisionSTDDerived, collIdx); - histos.fill(HIST("hEventVertexZ"), coll.posZ()); histos.fill(HIST("hEventCentrality"), coll.centFT0C()); sigma0Coll(coll.posX(), coll.posY(), coll.posZ(), coll.centFT0M(), coll.centFT0A(), coll.centFT0C(), coll.centFV0A()); // V0 table sliced for (auto& gamma : V0Table_thisCollision) { // selecting photons from Sigma0 for (auto& lambda : V0Table_thisCollision) { // selecting lambdas from Sigma0 + std::array pVecPhotons{gamma.px(), gamma.py(), gamma.pz()}; + std::array pVecLambda{lambda.px(), lambda.py(), lambda.pz()}; + auto arrMom = std::array{pVecPhotons, pVecLambda}; + float SigmaMass = RecoDecay::m(arrMom, std::array{o2::constants::physics::MassPhoton, o2::constants::physics::MassLambda0}); + float SigmapT = RecoDecay::pt(array{gamma.px() + lambda.px(), gamma.py() + lambda.py()}); + float SigmaY = TMath::Abs(RecoDecay::y(std::array{gamma.px() + lambda.px(), gamma.py() + lambda.py(), gamma.pz() + lambda.pz()}, o2::constants::physics::MassSigma0)); + histos.fill(HIST("h3dMassSigmasBeforeSel"), coll.centFT0C(), SigmapT, SigmaMass); + if (!processSigmaCandidate(lambda, gamma)) // applying selection for reconstruction continue; + histos.fill(HIST("h3dMassSigmasAfterSel"), coll.centFT0C(), SigmapT, SigmaMass); + + sigma0CollRefs(collIdx); + fillTables(lambda, gamma); // filling tables with accepted candidates + nSigmaCandidates++; if (nSigmaCandidates % 5000 == 0) { LOG(info) << "Sigma0 Candidates built: " << nSigmaCandidates; } - - sigma0CollRefs(collIdx); - fillTables(lambda, gamma); // filling tables with accepted candidates } } } @@ -543,7 +644,7 @@ struct sigma0builder { const uint64_t collIdx = coll.globalIndex(); auto V0Table_thisCollision = V0s.sliceBy(perCollisionMLDerived, collIdx); - histos.fill(HIST("hEventVertexZ"), coll.posZ()); + histos.fill(HIST("hEventCentrality"), coll.centFT0C()); sigma0Coll(coll.posX(), coll.posY(), coll.posZ(), coll.centFT0M(), coll.centFT0A(), coll.centFT0C(), coll.centFV0A()); // V0 table sliced diff --git a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx index 177786c6d5c..ee8db63d0a6 100644 --- a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" @@ -112,6 +114,7 @@ struct strangederivedbuilder { Produces StraFV0AQVs; // FV0A Q-vector Produces StraTPCQVs; // TPC Q-vector Produces StraFT0CQVsEv; // events used to compute FT0C Q-vector (LF) + Produces StraZDCSP; // ZDC Sums and Products //__________________________________________________ // Generated binned data @@ -414,7 +417,8 @@ struct strangederivedbuilder { // ______________________________________________ // fill all MC collisions, correlate via index later on for (const auto& mccollision : mcCollisions) { - strangeMCColl(mccollision.posX(), mccollision.posY(), mccollision.posZ(), mccollision.impactParameter()); + strangeMCColl(mccollision.posX(), mccollision.posY(), mccollision.posZ(), + mccollision.impactParameter(), mccollision.eventPlaneAngle()); strangeMCMults(mccollision.multMCFT0A(), mccollision.multMCFT0C(), mccollision.multMCNParticlesEta05(), mccollision.multMCNParticlesEta08(), @@ -800,6 +804,10 @@ struct strangederivedbuilder { StraFT0CQVs(collision.qFT0C() * std::cos(2 * collision.psiFT0C()), collision.qFT0C() * std::sin(2 * collision.psiFT0C()), collision.qFT0C()); StraFT0CQVsEv(collision.triggereventep()); } + void processZDCSP(soa::Join::iterator const& collision) + { + StraZDCSP(collision.triggereventsp(), collision.psiZDCA(), collision.psiZDCC()); + } void processFT0MQVectors(soa::Join::iterator const& collision) { StraFT0MQVs(collision.qvecFT0MRe(), collision.qvecFT0MIm(), collision.sumAmplFT0M()); @@ -905,6 +913,7 @@ struct strangederivedbuilder { PROCESS_SWITCH(strangederivedbuilder, processFV0AQVectors, "Produce FV0A Q-vectors table", false); PROCESS_SWITCH(strangederivedbuilder, processTPCQVectors, "Produce TPC Q-vectors table", false); PROCESS_SWITCH(strangederivedbuilder, processTPCQVectorsLF, "Produce TPC Q-vectors table using LF temporary calibration", false); + PROCESS_SWITCH(strangederivedbuilder, processZDCSP, "Produce ZDC SP table", false); // dedicated findable functionality PROCESS_SWITCH(strangederivedbuilder, processV0FoundTags, "Produce FoundV0Tags for findable exercise", false); diff --git a/PWGLF/Tasks/Nuspex/AngularCorrelationsInJets.cxx b/PWGLF/Tasks/Nuspex/AngularCorrelationsInJets.cxx index 51a48b3902e..6d751cde7c1 100644 --- a/PWGLF/Tasks/Nuspex/AngularCorrelationsInJets.cxx +++ b/PWGLF/Tasks/Nuspex/AngularCorrelationsInJets.cxx @@ -12,6 +12,8 @@ // author: Lars Jörgensen #include +#include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -29,9 +31,6 @@ #include "fastjet/AreaDefinition.hh" #include "fastjet/ClusterSequenceArea.hh" #include "fastjet/GhostedAreaSpec.hh" -// #include "fastjet/Selector.hh" -// #include "fastjet/tools/Subtractor.hh" -// #include "fastjet/tools/JetMedianBackgroundEstimator.hh" #include "PWGJE/Core/JetBkgSubUtils.h" #include "TVector2.h" #include "TVector3.h" @@ -43,8 +42,8 @@ using namespace o2::framework::expressions; struct AxisSpecs { AxisSpec ptAxisPos = {1000, 0, 100, "#it{p}_{T} [GeV/#it{c}]"}; AxisSpec ptAxisFull = {2000, -100, 100, "#it{p}_{T} [GeV/#it{c}]"}; - AxisSpec nsigmapTAxis = {1000, -50, 50, "#it{p}_{T} [GeV/#it{c}]"}; - AxisSpec nsigmaAxis = {1000, -15, 15, "n#sigma"}; + AxisSpec nsigmapTAxis = {500, 0, 50, "#it{p}_{T} [GeV/#it{c}]"}; + AxisSpec nsigmaAxis = {300, -15, 15, "n#sigma"}; AxisSpec dcazAxis = {1000, -1, 1, "DCA_{z} [cm]"}; AxisSpec dcaxyAxis = {1000, -0.5, 0.5, "DCA_{xy} [cm]"}; AxisSpec angDistPhiAxis = {1000, -2, 5, "#Delta#varphi"}; @@ -67,8 +66,6 @@ struct AngularCorrelationsInJets { Configurable fJetR{"jetR", 0.4, "jet resolution parameter"}; Configurable fMinJetPt{"minJetPt", 5.0, "minimum total pT to accept jet"}; Configurable fMinJetParticlePt{"minJetParticlePt", 0.0, "minimum pT to accept jet particle"}; - // Configurable fMinLeadingPt{"minLeadingPt", 5.0, "minimum pT for leading track"}; - // float fMinLeadingPt = 5.0; // Proton Cuts Configurable fProtonDCAxyYield{"protonDCAxyYield", 0.05, "[proton] DCAxy cut for yield"}; @@ -182,7 +179,7 @@ struct AngularCorrelationsInJets { registryData.add("hPtJetAntiproton", "p_{T} of antiprotons", HistType::kTH1D, {axisSpecs.ptAxisPos}); registryData.add("hPtJetNuclei", "p_{T} of nuclei", HistType::kTH1D, {axisSpecs.ptAxisPos}); registryData.add("hPtJetAntinuclei", "p_{T} of antinuclei", HistType::kTH1D, {axisSpecs.ptAxisPos}); - registryData.add("hPtTotalJet", "p_{T} of entire jet;#it{p}_{T} [GeV/#it{c}]", HistType::kTH1F, {{2000, 0, 500}}); + registryData.add("hPtTotalJet", "p_{T} of entire jet;#it{p}_{T} [GeV/#it{c}]", HistType::kTH1F, {{1000, 0, 500}}); registryQA.add("hPtJetProton_15", "Proton p_{T} for jet p_{T} < 15 GeV", HistType::kTH1D, {axisSpecs.ptAxisPos}); registryQA.add("hPtJetProton_20", "Proton p_{T} for jet p_{T} < 20 GeV", HistType::kTH1D, {axisSpecs.ptAxisPos}); registryQA.add("hPtJetProton_30", "Proton p_{T} for jet p_{T} < 30 GeV", HistType::kTH1D, {axisSpecs.ptAxisPos}); @@ -201,16 +198,24 @@ struct AngularCorrelationsInJets { registryQA.add("hPtJetAntinuclei_50", "Antinuclei p_{T} for jet p_{T} < 50 GeV", HistType::kTH1D, {axisSpecs.ptAxisPos}); // nSigma - registryData.add("hTPCsignal", "TPC signal", HistType::kTH2F, {{1000, 0, 100, "#it{p} [GeV/#it{c}]"}, {5000, 0, 5000, "d#it{E}/d#it{X} (a.u.)"}}); - registryData.add("hTOFsignal", "TOF signal", HistType::kTH2F, {{1000, 0, 100, "#it{p} [GeV/#it{c}]"}, {550, 0, 1.1, "#beta (TOF)"}}); - registryData.add("hTPCsignalProton", "TPC n#sigma for (anti)proton without cuts", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTOFsignalProton", "TOF n#sigma for (anti)proton without cuts", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTPCsignalNuclei", "TPC n#sigma for (anti)nuclei without cuts", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTOFsignalNuclei", "TOF n#sigma for (anti)nuclei without cuts", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTPCnsigmaProton", "TPC n#sigma for (anti)proton", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTOFnsigmaProton", "TOF n#sigma for (anti)proton", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTPCnsigmaNuclei", "TPC n#sigma for (anti)nuclei", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); - registryData.add("hTOFnsigmaNuclei", "TOF n#sigma for (anti)nuclei", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCsignal", "TPC signal", HistType::kTH2F, {{1000, -100, 100, "#it{p} [GeV/#it{c}]"}, {5000, 0, 5000, "d#it{E}/d#it{X} (a.u.)"}}); + registryData.add("hTOFsignal", "TOF signal", HistType::kTH2F, {{1000, -100, 100, "#it{p} [GeV/#it{c}]"}, {550, 0, 1.1, "#beta (TOF)"}}); + registryData.add("hTPCnsigmaProton", "TPC n#sigma for proton", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaProton", "TOF n#sigma for proton", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaAntiproton", "TPC n#sigma for antiproton", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaAntiproton", "TOF n#sigma for antiproton", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaNuclei", "TPC n#sigma for nuclei", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaNuclei", "TOF n#sigma for nuclei", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaAntinuclei", "TPC n#sigma for antinuclei", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaAntinuclei", "TOF n#sigma for antinuclei", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaProtonCF", "TPC n#sigma for proton CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaProtonCF", "TOF n#sigma for proton CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaAntiprotonCF", "TPC n#sigma for antiproton CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaAntiprotonCF", "TOF n#sigma for antiproton CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaNucleiCF", "TPC n#sigma for nuclei CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaNucleiCF", "TOF n#sigma for nuclei CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTPCnsigmaAntinucleiCF", "TPC n#sigma for antinuclei CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); + registryData.add("hTOFnsigmaAntinucleiCF", "TOF n#sigma for antinuclei CF", HistType::kTH2F, {axisSpecs.nsigmapTAxis, axisSpecs.nsigmaAxis}); // DCA registryData.add("hDCAxyFullJet", "DCA_{xy} of full jet", HistType::kTH2F, {axisSpecs.ptAxisFull, axisSpecs.dcaxyAxis}); @@ -265,7 +270,7 @@ struct AngularCorrelationsInJets { registryQA.add("hRhoMEstimateArea", "Background #rho_{m} (area)", HistType::kTH2F, {{axisSpecs.ptAxisPos}, {200, 0, 20}}); registryQA.add("hJetBkgDeltaPt", "#Delta p_{T} Clustered Cone - Pure Jet", HistType::kTH1F, {{200, 0, 10}}); - registryQA.add("hTOFmass", "TOF mass", HistType::kTH2F, {axisSpecs.ptAxisPos, {1000, 0, 5, "#it{m} [GeV/#it{c}^{2}]"}}); + registryQA.add("hTOFmass", "TOF mass vs p_{T}", HistType::kTH2F, {axisSpecs.ptAxisPos, {1000, 0, 5, "#it{m} [GeV/#it{c}^{2}]"}}); registryQA.get(HIST("hTOFmass"))->Sumw2(); registryQA.add("hPtFullEvent", "p_{T} after basic cuts", HistType::kTH1F, {axisSpecs.ptAxisPos}); registryQA.add("hCrossedRowsTPC", "Crossed rows TPC", HistType::kTH2I, {axisSpecs.ptAxisPos, {135, 65, 200}}); @@ -335,37 +340,49 @@ struct AngularCorrelationsInJets { return false; if (tightCuts) { // for correlation function + // DCA + if (TMath::Abs(track.dcaXY()) > fProtonDCAxyCF) + return false; + if (TMath::Abs(track.dcaZ()) > fProtonDCAzCF) + return false; + + registryData.fill(HIST("hTPCnsigmaProtonCF"), track.pt(), track.tpcNSigmaPr()); + // TPC if (track.pt() < fProtonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fProtonTPCnsigLowCF) return false; if (track.pt() > fProtonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fProtonTPCnsigHighCF) return false; + registryData.fill(HIST("hTOFnsigmaProtonCF"), track.pt(), track.tofNSigmaPr()); + + // TOF + if (track.hasTOF()) { + if (track.pt() > fProtonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fProtonTOFnsigCF) + return false; + } + } else { // for yields // DCA - if (TMath::Abs(track.dcaXY()) > fProtonDCAxyCF) + if (TMath::Abs(track.dcaXY()) > fProtonDCAxyYield) return false; - if (TMath::Abs(track.dcaZ()) > fProtonDCAzCF) + if (TMath::Abs(track.dcaZ()) > fProtonDCAzYield) return false; - // TOF - if (track.pt() > fProtonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fProtonTOFnsigCF) - return false; - } else { // for yields + registryData.fill(HIST("hTPCnsigmaProton"), track.pt(), track.tpcNSigmaPr()); + // TPC if (track.pt() < fProtonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fProtonTPCnsigLowYield) return false; if (track.pt() > fProtonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fProtonTPCnsigHighYield) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fProtonDCAxyYield) - return false; - if (TMath::Abs(track.dcaZ()) > fProtonDCAzYield) - return false; + registryData.fill(HIST("hTOFnsigmaProton"), track.pt(), track.tofNSigmaPr()); // TOF - if (track.pt() > fProtonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fProtonTOFnsigYield) - return false; + if (track.hasTOF()) { + if (track.pt() > fProtonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fProtonTOFnsigYield) + return false; + } } return true; @@ -378,37 +395,49 @@ struct AngularCorrelationsInJets { return false; if (tightCuts) { // for correlation function + // DCA + if (TMath::Abs(track.dcaXY()) > fAntiprotonDCAxyCF) + return false; + if (TMath::Abs(track.dcaZ()) > fAntiprotonDCAzCF) + return false; + + registryData.fill(HIST("hTPCnsigmaAntiprotonCF"), track.pt(), track.tpcNSigmaPr()); + // TPC if (track.pt() < fAntiprotonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fAntiprotonTPCnsigLowCF) return false; if (track.pt() > fAntiprotonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fAntiprotonTPCnsigHighCF) return false; + registryData.fill(HIST("hTOFnsigmaAntiprotonCF"), track.pt(), track.tofNSigmaPr()); + + // TOF + if (track.hasTOF()) { + if (track.pt() > fAntiprotonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fAntiprotonTOFnsigCF) + return false; + } + } else { // for yields // DCA - if (TMath::Abs(track.dcaXY()) > fAntiprotonDCAxyCF) + if (TMath::Abs(track.dcaXY()) > fAntiprotonDCAxyYield) return false; - if (TMath::Abs(track.dcaZ()) > fAntiprotonDCAzCF) + if (TMath::Abs(track.dcaZ()) > fAntiprotonDCAzYield) return false; - // TOF - if (track.pt() > fAntiprotonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fAntiprotonTOFnsigCF) - return false; - } else { // for yields + registryData.fill(HIST("hTPCnsigmaAntiproton"), track.pt(), track.tpcNSigmaPr()); + // TPC if (track.pt() < fAntiprotonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fAntiprotonTPCnsigLowYield) return false; if (track.pt() > fAntiprotonTPCTOFpT && TMath::Abs(track.tpcNSigmaPr()) > fAntiprotonTPCnsigHighYield) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fAntiprotonDCAxyYield) - return false; - if (TMath::Abs(track.dcaZ()) > fAntiprotonDCAzYield) - return false; + registryData.fill(HIST("hTOFnsigmaAntiproton"), track.pt(), track.tofNSigmaPr()); // TOF - if (track.pt() > fAntiprotonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fAntiprotonTOFnsigYield) - return false; + if (track.hasTOF()) { + if (track.pt() > fAntiprotonTPCTOFpT && TMath::Abs(track.tofNSigmaPr()) > fAntiprotonTOFnsigYield) + return false; + } } return true; @@ -421,71 +450,95 @@ struct AngularCorrelationsInJets { return false; if (fDeuteronAnalysis) { if (tightCuts) { // for correlation function + // DCA + if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyCF) + return false; + if (TMath::Abs(track.dcaZ()) > fNucleiDCAzCF) + return false; + + registryData.fill(HIST("hTPCnsigmaNucleiCF"), track.pt(), track.tpcNSigmaDe()); + // TPC if (track.pt() < fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fNucleiTPCnsigLowCF) return false; if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fNucleiTPCnsigHighCF) return false; + registryData.fill(HIST("hTOFnsigmaNucleiCF"), track.pt(), track.tofNSigmaDe()); + + // TOF + if (track.hasTOF()) { + if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaDe()) > fNucleiTOFnsigCF) + return false; + } + } else { // for yields // DCA - if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyCF) + if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyYield) return false; - if (TMath::Abs(track.dcaZ()) > fNucleiDCAzCF) + if (TMath::Abs(track.dcaZ()) > fNucleiDCAzYield) return false; - // TOF - if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaDe()) > fNucleiTOFnsigCF) - return false; - } else { // for yields + registryData.fill(HIST("hTPCnsigmaNuclei"), track.pt(), track.tpcNSigmaDe()); + // TPC if (track.pt() < fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fNucleiTPCnsigLowYield) return false; if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fNucleiTPCnsigHighYield) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyYield) - return false; - if (TMath::Abs(track.dcaZ()) > fNucleiDCAzYield) - return false; + registryData.fill(HIST("hTOFnsigmaNuclei"), track.pt(), track.tofNSigmaDe()); // TOF - if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaDe()) > fNucleiTOFnsigYield) - return false; + if (track.hasTOF()) { + if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaDe()) > fNucleiTOFnsigYield) + return false; + } } } else { if (tightCuts) { // for correlation function - including for helium just in case, but realistically, angular correlations won't be a thing here + // DCA + if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyCF) + return false; + if (TMath::Abs(track.dcaZ()) > fNucleiDCAzCF) + return false; + + registryData.fill(HIST("hTPCnsigmaNucleiCF"), track.pt(), track.tpcNSigmaHe()); + // TPC if (track.pt() < fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fNucleiTPCnsigLowCF) return false; if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fNucleiTPCnsigHighCF) return false; + registryData.fill(HIST("hTOFnsigmaNucleiCF"), track.pt(), track.tofNSigmaHe()); + + // TOF + if (track.hasTOF()) { + if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaHe()) > fNucleiTOFnsigCF) + return false; + } + } else { // for yields // DCA - if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyCF) + if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyYield) return false; - if (TMath::Abs(track.dcaZ()) > fNucleiDCAzCF) + if (TMath::Abs(track.dcaZ()) > fNucleiDCAzYield) return false; - // TOF - if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaHe()) > fNucleiTOFnsigCF) - return false; - } else { // for yields + registryData.fill(HIST("hTPCnsigmaNuclei"), track.pt(), track.tpcNSigmaHe()); + // TPC if (track.pt() < fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fNucleiTPCnsigLowYield) return false; if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fNucleiTPCnsigHighYield) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fNucleiDCAxyYield) - return false; - if (TMath::Abs(track.dcaZ()) > fNucleiDCAzYield) - return false; + registryData.fill(HIST("hTOFnsigmaNuclei"), track.pt(), track.tofNSigmaHe()); // TOF - if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaHe()) > fNucleiTOFnsigYield) - return false; + if (track.hasTOF()) { + if (track.pt() > fNucleiTPCTOFpT && TMath::Abs(track.tofNSigmaHe()) > fNucleiTOFnsigYield) + return false; + } } } @@ -500,33 +553,41 @@ struct AngularCorrelationsInJets { if (fDeuteronAnalysis) { if (tightCuts) { // for correlation function + // DCA + if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyCF) + return false; + if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzCF) + return false; + + registryData.fill(HIST("hTPCnsigmaAntinucleiCF"), track.pt(), track.tpcNSigmaDe()); + // TPC if (track.pt() < fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fAntinucleiTPCnsigLowCF) return false; if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fAntinucleiTPCnsigHighCF) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyCF) - return false; - if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzCF) - return false; + registryData.fill(HIST("hTOFnsigmaAntinucleiCF"), track.pt(), track.tofNSigmaDe()); // TOF if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tofNSigmaDe()) > fAntinucleiTOFnsigCF) return false; } else { // for yields + // DCA + if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyYield) + return false; + if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzYield) + return false; + + registryData.fill(HIST("hTPCnsigmaAntinuclei"), track.pt(), track.tpcNSigmaDe()); + // TPC if (track.pt() < fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fAntinucleiTPCnsigLowYield) return false; if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaDe()) > fAntinucleiTPCnsigHighYield) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyYield) - return false; - if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzYield) - return false; + registryData.fill(HIST("hTOFnsigmaAntinuclei"), track.pt(), track.tofNSigmaDe()); // TOF if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tofNSigmaDe()) > fAntinucleiTOFnsigYield) @@ -534,33 +595,41 @@ struct AngularCorrelationsInJets { } } else { if (tightCuts) { // for correlation function - including for antihelium just in case, but realistically, angular correlations won't be a thing here + // DCA + if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyCF) + return false; + if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzCF) + return false; + + registryData.fill(HIST("hTPCnsigmaAntinucleiCF"), track.pt(), track.tpcNSigmaHe()); + // TPC if (track.pt() < fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fAntinucleiTPCnsigLowCF) return false; if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fAntinucleiTPCnsigHighCF) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyCF) - return false; - if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzCF) - return false; + registryData.fill(HIST("hTOFnsigmaAntinucleiCF"), track.pt(), track.tofNSigmaHe()); // TOF if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tofNSigmaHe()) > fAntinucleiTOFnsigCF) return false; } else { // for yields + // DCA + if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyYield) + return false; + if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzYield) + return false; + + registryData.fill(HIST("hTPCnsigmaAntinuclei"), track.pt(), track.tpcNSigmaHe()); + // TPC if (track.pt() < fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fAntinucleiTPCnsigLowYield) return false; if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tpcNSigmaHe()) > fAntinucleiTPCnsigHighYield) return false; - // DCA - if (TMath::Abs(track.dcaXY()) > fAntinucleiDCAxyYield) - return false; - if (TMath::Abs(track.dcaZ()) > fAntinucleiDCAzYield) - return false; + registryData.fill(HIST("hTOFnsigmaAntinuclei"), track.pt(), track.tofNSigmaHe()); // TOF if (track.pt() > fAntinucleiTPCTOFpT && TMath::Abs(track.tofNSigmaHe()) > fAntinucleiTOFnsigYield) @@ -901,17 +970,6 @@ struct AngularCorrelationsInJets { registryData.fill(HIST("hTPCsignal"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcSignal()); if (jetParticle.hasTOF()) { registryData.fill(HIST("hTOFsignal"), jetParticle.pt() * jetParticle.sign(), jetParticle.beta()); - registryData.fill(HIST("hTOFsignalProton"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaPr()); - } - registryData.fill(HIST("hTPCsignalProton"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaPr()); - if (fDeuteronAnalysis) { - registryData.fill(HIST("hTPCsignalNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaDe()); - if (jetParticle.hasTOF()) - registryData.fill(HIST("hTOFsignalNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaDe()); - } else { - registryData.fill(HIST("hTPCsignalNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaHe()); - if (jetParticle.hasTOF()) - registryData.fill(HIST("hTOFsignalNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaHe()); } double ptDiff = pseudoParticle.pt() - jetParticle.pt(); registryQA.fill(HIST("hPtDiff"), ptDiff); @@ -929,9 +987,8 @@ struct AngularCorrelationsInJets { } else if (subtractedJetPerp.pt() < 50) { registryQA.fill(HIST("hPtJetProton_50"), jetParticle.pt()); } - registryData.fill(HIST("hTPCnsigmaProton"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaPr()); if (jetParticle.hasTOF()) - registryData.fill(HIST("hTOFnsigmaProton"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaPr()); + registryData.fill(HIST("hTOFnsigmaProton"), jetParticle.pt(), jetParticle.tofNSigmaPr()); registryData.fill(HIST("hTrackProtocol"), 4); // # protons if (isProton(jetParticle, true)) { registryData.fill(HIST("hTrackProtocol"), 5); // # high purity protons @@ -949,9 +1006,9 @@ struct AngularCorrelationsInJets { } else if (subtractedJetPerp.pt() < 50) { registryQA.fill(HIST("hPtJetAntiproton_50"), jetParticle.pt()); } - registryData.fill(HIST("hTPCnsigmaProton"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaPr()); + registryData.fill(HIST("hTPCnsigmaAntiproton"), jetParticle.pt(), jetParticle.tpcNSigmaPr()); if (jetParticle.hasTOF()) - registryData.fill(HIST("hTOFnsigmaProton"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaPr()); + registryData.fill(HIST("hTOFnsigmaAntiproton"), jetParticle.pt(), jetParticle.tofNSigmaPr()); registryData.fill(HIST("hTrackProtocol"), 6); // # antiprotons if (isAntiproton(jetParticle, true)) { registryData.fill(HIST("hTrackProtocol"), 7); // # high purity antiprotons @@ -970,15 +1027,15 @@ struct AngularCorrelationsInJets { registryQA.fill(HIST("hPtJetNuclei_50"), jetParticle.pt()); } if (fDeuteronAnalysis) { - registryData.fill(HIST("hTPCnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaDe()); + registryData.fill(HIST("hTPCnsigmaNuclei"), jetParticle.pt(), jetParticle.tpcNSigmaDe()); } else { - registryData.fill(HIST("hTPCnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaHe()); + registryData.fill(HIST("hTPCnsigmaNuclei"), jetParticle.pt(), jetParticle.tpcNSigmaHe()); } if (jetParticle.hasTOF()) { if (fDeuteronAnalysis) { - registryData.fill(HIST("hTOFnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaDe()); + registryData.fill(HIST("hTOFnsigmaNuclei"), jetParticle.pt(), jetParticle.tofNSigmaDe()); } else { - registryData.fill(HIST("hTOFnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaHe()); + registryData.fill(HIST("hTOFnsigmaNuclei"), jetParticle.pt(), jetParticle.tofNSigmaHe()); } } registryData.fill(HIST("hTrackProtocol"), 8); // # nuclei @@ -999,15 +1056,15 @@ struct AngularCorrelationsInJets { registryQA.fill(HIST("hPtJetAntinuclei_50"), jetParticle.pt()); } if (fDeuteronAnalysis) { - registryData.fill(HIST("hTPCnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaDe()); + registryData.fill(HIST("hTPCnsigmaAntinuclei"), jetParticle.pt(), jetParticle.tpcNSigmaDe()); } else { - registryData.fill(HIST("hTPCnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tpcNSigmaHe()); + registryData.fill(HIST("hTPCnsigmaAntinuclei"), jetParticle.pt(), jetParticle.tpcNSigmaHe()); } if (jetParticle.hasTOF()) { if (fDeuteronAnalysis) { - registryData.fill(HIST("hTOFnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaDe()); + registryData.fill(HIST("hTOFnsigmaAntinuclei"), jetParticle.pt(), jetParticle.tofNSigmaDe()); } else { - registryData.fill(HIST("hTOFnsigmaNuclei"), jetParticle.pt() * jetParticle.sign(), jetParticle.tofNSigmaHe()); + registryData.fill(HIST("hTOFnsigmaAntinuclei"), jetParticle.pt(), jetParticle.tofNSigmaHe()); } } registryData.fill(HIST("hTrackProtocol"), 10); // # antinuclei diff --git a/PWGLF/Tasks/Nuspex/NucleiHistTask.cxx b/PWGLF/Tasks/Nuspex/NucleiHistTask.cxx index e3bfc1be9ae..37ad72ef487 100644 --- a/PWGLF/Tasks/Nuspex/NucleiHistTask.cxx +++ b/PWGLF/Tasks/Nuspex/NucleiHistTask.cxx @@ -58,7 +58,9 @@ struct NucleiHistTask { // MC HistogramRegistry MC_recon_reg{"MC_particles_reco", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - OutputObj histPDG{TH1F("PDG", "PDG;PDG code", 20, 0.0, 20.0)}; + OutputObj histPDG{TH1I("PDG", "PDG;PDG code", 20, 0.0, 20.0)}; + OutputObj histTrackcuts_data{TH1I("histTrackcuts_data", "Entires;Track cut", 15, 0, 15)}; + OutputObj histTrackcuts_MC{TH1I("histTrackcuts_MC", "Entires;Track cut", 15, 0, 15)}; void init(o2::framework::InitContext&) { @@ -67,6 +69,36 @@ struct NucleiHistTask { LOG(fatal) << "Can't enable processData and processDataCent in the same time, pick one!"; } + // +++++++++++++++++++++ Data ++++++++++++++++++++++++ + histTrackcuts_data->GetXaxis()->SetBinLabel(1, "Events read"); + histTrackcuts_data->GetXaxis()->SetBinLabel(2, "Ev. sel. passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(3, "Rap. cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(4, "DCA cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(5, "TPCnCls cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(6, "TPCCrossedRowsOverFindable cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(7, "Chi2 cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(8, "Passed TPC refit cut"); + histTrackcuts_data->GetXaxis()->SetBinLabel(9, "Passed ITS refit cut"); + histTrackcuts_data->GetXaxis()->SetBinLabel(10, "ITSnCls cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(11, "Momentum cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(12, "hasITS & hasTPC cut passed"); + histTrackcuts_data->GetXaxis()->SetBinLabel(13, "GoldenChi2 cut passed"); + + // +++++++++++++++++++++ MC ++++++++++++++++++++++++ + histTrackcuts_MC->GetXaxis()->SetBinLabel(1, "Events read"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(2, "Prim. particle. sel. passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(3, "Rap. cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(4, "DCA cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(5, "TPCnCls cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(6, "TPCCrossedRowsOverFindable cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(7, "Chi2 cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(8, "Passed TPC refit cut"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(9, "Passed ITS refit cut"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(10, "ITSnCls cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(11, "Momentum cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(12, "hasITS & hasTPC cut passed"); + histTrackcuts_MC->GetXaxis()->SetBinLabel(13, "GoldenChi2 cut passed"); + 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 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}; std::vector PDGBinning = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0}; @@ -386,6 +418,7 @@ struct NucleiHistTask { // Configurables Configurable use_momentum_getter{"use_momentum_getter", 0, "0: track.p(), 1: track.pt(), 2: track.tpcInnerParam()"}; + Configurable momentum_He3{"momentum_He3", 0, "0: momentum * 1.0, 1: momentum * 2.0"}; Configurable yMin{"yMin", -0.5, "Maximum rapidity"}; Configurable yMax{"yMax", 0.5, "Minimum rapidity"}; Configurable p_min{"p_min", 0.1f, "min momentum"}; @@ -399,16 +432,23 @@ struct NucleiHistTask { Configurable enable_Centrality_cut_global{"enable_Centrality_cut_global", true, "use Centrality cut"}; // Replacement for globalTrack filter + Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; + Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; + Configurable passedITSRefit{"passedITSRefit", true, "Additional cut on the ITS refit requirement"}; + Configurable passedTPCRefit{"passedTPCRefit", true, "Additional cut on the TPC refit requirement"}; Configurable minReqClusterITS{"minReqClusterITS", 1.0, "min number of clusters required in ITS"}; Configurable minReqClusterITSib{"minReqClusterITSib", 1.0, "min number of clusters required in ITS inner barrel"}; Configurable minTPCnClsFound{"minTPCnClsFound", 0.0f, "min number of crossed rows TPC"}; Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.0f, "min number of crossed rows TPC"}; Configurable minRatioCrossedRowsTPC{"minRatioCrossedRowsTPC", 0.8f, "min ratio of crossed rows over findable clusters TPC"}; Configurable maxRatioCrossedRowsTPC{"maxRatioCrossedRowsTPC", 2.0f, "max ratio of crossed rows over findable clusters TPC"}; - Configurable maxChi2ITS{"maxChi2ITS", 36.0f, "max chi2 per cluster ITS"}; - Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; + Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 4.f, "Cut on the maximum value of the chi2 per cluster in the TPC"}; + Configurable minChi2PerClusterTPC{"minChi2PerClusterTPC", 0.5f, "Cut on the minimum value of the chi2 per cluster in the TPC"}; + Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Cut on the maximum value of the chi2 per cluster in the ITS"}; Configurable maxDCA_XY{"maxDCA_XY", 0.5f, "max DCA to vertex xy"}; Configurable maxDCA_Z{"maxDCA_Z", 2.0f, "max DCA to vertex z"}; + Configurable lastRequiredTrdCluster{"lastRequiredTrdCluster", -1, "Last cluster to required in TRD for track selection. -1 does not require any TRD cluster"}; + Configurable requireGoldenChi2{"requireGoldenChi2", false, "Enable the requirement of GoldenChi2"}; Configurable event_selection_sel8{"event_selection_sel8", true, "Enable sel8 event selection"}; Configurable event_selection_MC_sel8{"event_selection_MC_sel8", true, "Enable sel8 event selection in MC processing"}; @@ -425,26 +465,63 @@ struct NucleiHistTask { for (auto track : tracks) { + histTrackcuts_data->AddBinContent(1); if (event_selection_sel8 && !event.sel8()) continue; + histTrackcuts_data->AddBinContent(2); double momentum = 0.0; + double momentum_Z_equal_2 = 0.0; int momentum_getter = 0; + int momentum_getter_Z_equal_2 = 0; switch (use_momentum_getter) { case 0: momentum = track.p(); + switch (momentum_He3) { + case 0: + momentum_Z_equal_2 = track.p(); + break; + case 1: + momentum_Z_equal_2 = track.p() * 2.0; + break; + default: + momentum_getter_Z_equal_2 = -1; + break; + } break; case 1: momentum = track.pt(); + switch (momentum_He3) { + case 0: + momentum_Z_equal_2 = track.pt(); + break; + case 1: + momentum_Z_equal_2 = track.pt() * 2.0; + break; + default: + momentum_getter_Z_equal_2 = -1; + break; + } break; case 2: momentum = track.tpcInnerParam(); + switch (momentum_He3) { + case 0: + momentum_Z_equal_2 = track.tpcInnerParam(); + break; + case 1: + momentum_Z_equal_2 = track.tpcInnerParam() * 2.0; + break; + default: + momentum_getter_Z_equal_2 = -1; + break; + } break; default: momentum_getter = -1; break; } - if (momentum_getter == -1) + if (momentum_getter == -1 || momentum_getter_Z_equal_2 == -1) break; float TPCnumberClsFound = track.tpcNClsFound(); @@ -483,6 +560,7 @@ struct NucleiHistTask { lorentzVector_He3.Rapidity() < yMin || lorentzVector_He3.Rapidity() > yMax || lorentzVector_He4.Rapidity() < yMin || lorentzVector_He4.Rapidity() > yMax) continue; + histTrackcuts_data->AddBinContent(3); float nSigmaPion = track.tpcNSigmaPi(); float nSigmaProton = track.tpcNSigmaPr(); @@ -497,8 +575,36 @@ struct NucleiHistTask { spectra_reg.fill(HIST("histChi2TPC"), track.pt(), track.tpcChi2NCl()); spectra_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); - if (TMath::Abs(track.dcaXY()) > maxDCA_XY || TMath::Abs(track.dcaZ()) > maxDCA_Z || 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 || track.pt() < p_min || track.pt() > p_max) + if (TMath::Abs(track.dcaXY()) > maxDCA_XY || TMath::Abs(track.dcaZ()) > maxDCA_Z) + continue; + histTrackcuts_data->AddBinContent(4); + if (TPCnumberClsFound < minTPCnClsFound || TPC_nCls_Crossed_Rows < minNCrossedRowsTPC) + continue; + histTrackcuts_data->AddBinContent(5); + if (RatioCrossedRowsOverFindableTPC < minRatioCrossedRowsTPC || RatioCrossedRowsOverFindableTPC > maxRatioCrossedRowsTPC) + continue; + histTrackcuts_data->AddBinContent(6); + if (Chi2perClusterTPC > maxChi2PerClusterTPC || Chi2perClusterTPC < minChi2PerClusterTPC || Chi2perClusterITS > maxChi2PerClusterITS) + continue; + histTrackcuts_data->AddBinContent(7); + if (!(track.passedTPCRefit())) + continue; + histTrackcuts_data->AddBinContent(8); + if (!(track.passedITSRefit())) continue; + histTrackcuts_data->AddBinContent(9); + if ((track.itsNClsInnerBarrel()) < minReqClusterITSib || (track.itsNCls()) < minReqClusterITS) + continue; + histTrackcuts_data->AddBinContent(10); + if (track.pt() < p_min || track.pt() > p_max) + continue; + histTrackcuts_data->AddBinContent(11); + if ((requireITS && !(track.hasITS())) || (requireTPC && !(track.hasTPC()))) + continue; + histTrackcuts_data->AddBinContent(12); + if (requireGoldenChi2 && !(track.passedGoldenChi2())) + continue; + histTrackcuts_data->AddBinContent(13); spectra_reg.fill(HIST("histTpcSignalData"), momentum * track.sign(), track.tpcSignal()); @@ -507,10 +613,21 @@ struct NucleiHistTask { proton_reg.fill(HIST("histTpcNsigmaData"), momentum, nSigmaProton); deuteron_reg.fill(HIST("histTpcNsigmaData"), momentum, nSigmaDeut); triton_reg.fill(HIST("histTpcNsigmaData"), momentum, nSigmaTriton); - Helium3_reg.fill(HIST("histTpcNsigmaData"), momentum * 2.0, nSigmaHe3); - Helium4_reg.fill(HIST("histTpcNsigmaData"), momentum * 2.0, nSigmaHe4); + Helium3_reg.fill(HIST("histTpcNsigmaData"), momentum_Z_equal_2, nSigmaHe3); + Helium4_reg.fill(HIST("histTpcNsigmaData"), momentum_Z_equal_2, nSigmaHe4); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); spectra_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); } @@ -521,10 +638,21 @@ struct NucleiHistTask { aproton_reg.fill(HIST("histTpcNsigmaData"), momentum, nSigmaProton); adeuteron_reg.fill(HIST("histTpcNsigmaData"), momentum, nSigmaDeut); atriton_reg.fill(HIST("histTpcNsigmaData"), momentum, nSigmaTriton); - aHelium3_reg.fill(HIST("histTpcNsigmaData"), momentum * 2.0, nSigmaHe3); - aHelium4_reg.fill(HIST("histTpcNsigmaData"), momentum * 2.0, nSigmaHe4); + aHelium3_reg.fill(HIST("histTpcNsigmaData"), momentum_Z_equal_2, nSigmaHe3); + aHelium4_reg.fill(HIST("histTpcNsigmaData"), momentum_Z_equal_2, nSigmaHe4); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); spectra_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); } @@ -545,6 +673,17 @@ struct NucleiHistTask { pion_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); pion_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -564,6 +703,17 @@ struct NucleiHistTask { apion_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); apion_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -573,6 +723,17 @@ struct NucleiHistTask { } 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; + } spectra_reg.fill(HIST("histTofSignalData"), momentum * track.sign(), track.beta()); } } @@ -592,6 +753,17 @@ struct NucleiHistTask { proton_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); proton_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -611,6 +783,17 @@ struct NucleiHistTask { aproton_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); aproton_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -620,6 +803,17 @@ struct NucleiHistTask { } 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; + } spectra_reg.fill(HIST("histTofSignalData"), momentum * track.sign(), track.beta()); } } @@ -639,6 +833,17 @@ struct NucleiHistTask { deuteron_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); deuteron_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -658,6 +863,17 @@ struct NucleiHistTask { adeuteron_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); adeuteron_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -667,6 +883,17 @@ struct NucleiHistTask { } 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; + } spectra_reg.fill(HIST("histTofSignalData"), momentum * track.sign(), track.beta()); } } @@ -686,6 +913,17 @@ struct NucleiHistTask { triton_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); triton_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -705,6 +943,17 @@ struct NucleiHistTask { atriton_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); atriton_reg.fill(HIST("histTOFm2"), momentum, TOFmass2); @@ -714,6 +963,17 @@ struct NucleiHistTask { } 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; + } spectra_reg.fill(HIST("histTofSignalData"), momentum * track.sign(), track.beta()); } } @@ -725,7 +985,7 @@ struct NucleiHistTask { if (track.sign() > 0) { 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"), momentum * 2.0, track.tpcSignal()); + Helium3_reg.fill(HIST("histTpcSignalData"), momentum_Z_equal_2, 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()); @@ -733,18 +993,29 @@ struct NucleiHistTask { Helium3_reg.fill(HIST("histChi2ITS"), track.pt() * 2.0, track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); - Helium3_reg.fill(HIST("histTOFm2"), momentum * 2.0, TOFmass2); - Helium3_reg.fill(HIST("histTofSignalData"), momentum * 2.0, beta); - Helium3_reg.fill(HIST("histTofNsigmaData"), momentum * 2.0, track.tofNSigmaHe()); + Helium3_reg.fill(HIST("histTOFm2"), momentum_Z_equal_2, TOFmass2); + Helium3_reg.fill(HIST("histTofSignalData"), momentum_Z_equal_2, beta); + Helium3_reg.fill(HIST("histTofNsigmaData"), momentum_Z_equal_2, track.tofNSigmaHe()); } } if (track.sign() < 0) { 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"), momentum * 2.0, track.tpcSignal()); + aHelium3_reg.fill(HIST("histTpcSignalData"), momentum_Z_equal_2, 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()); @@ -752,16 +1023,38 @@ struct NucleiHistTask { aHelium3_reg.fill(HIST("histChi2ITS"), track.pt() * 2.0, track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); - aHelium3_reg.fill(HIST("histTOFm2"), momentum * 2.0, TOFmass2); - aHelium3_reg.fill(HIST("histTofSignalData"), momentum * 2.0, beta); - aHelium3_reg.fill(HIST("histTofNsigmaData"), momentum * 2.0, track.tofNSigmaHe()); + aHelium3_reg.fill(HIST("histTOFm2"), momentum_Z_equal_2, TOFmass2); + aHelium3_reg.fill(HIST("histTofSignalData"), momentum_Z_equal_2, beta); + aHelium3_reg.fill(HIST("histTofNsigmaData"), momentum_Z_equal_2, track.tofNSigmaHe()); } } if (track.hasTOF()) { - spectra_reg.fill(HIST("histTofSignalData"), momentum * 2.0 * track.sign(), track.beta()); + 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; + } + spectra_reg.fill(HIST("histTofSignalData"), momentum_Z_equal_2 * track.sign(), track.beta()); } } @@ -772,7 +1065,7 @@ struct NucleiHistTask { if (track.sign() > 0) { 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"), momentum * 2.0, track.tpcSignal()); + Helium4_reg.fill(HIST("histTpcSignalData"), momentum_Z_equal_2, 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()); @@ -780,18 +1073,29 @@ struct NucleiHistTask { Helium4_reg.fill(HIST("histChi2ITS"), track.pt() * 2.0, track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); - Helium4_reg.fill(HIST("histTOFm2"), momentum * 2.0, TOFmass2); - Helium4_reg.fill(HIST("histTofSignalData"), momentum * 2.0, beta); - Helium4_reg.fill(HIST("histTofNsigmaData"), momentum * 2.0, track.tofNSigmaAl()); + Helium4_reg.fill(HIST("histTOFm2"), momentum_Z_equal_2, TOFmass2); + Helium4_reg.fill(HIST("histTofSignalData"), momentum_Z_equal_2, beta); + Helium4_reg.fill(HIST("histTofNsigmaData"), momentum_Z_equal_2, track.tofNSigmaAl()); } } if (track.sign() < 0) { 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"), momentum * 2.0, track.tpcSignal()); + aHelium4_reg.fill(HIST("histTpcSignalData"), momentum_Z_equal_2, 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()); @@ -799,16 +1103,38 @@ struct NucleiHistTask { aHelium4_reg.fill(HIST("histChi2ITS"), track.pt() * 2.0, track.itsChi2NCl()); 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; + } Float_t TOFmass2 = ((track.mass()) * (track.mass())); Float_t beta = track.beta(); - aHelium4_reg.fill(HIST("histTOFm2"), momentum * 2.0, TOFmass2); - aHelium4_reg.fill(HIST("histTofSignalData"), momentum * 2.0, beta); - aHelium4_reg.fill(HIST("histTofNsigmaData"), momentum * 2.0, track.tofNSigmaAl()); + aHelium4_reg.fill(HIST("histTOFm2"), momentum_Z_equal_2, TOFmass2); + aHelium4_reg.fill(HIST("histTofSignalData"), momentum_Z_equal_2, beta); + aHelium4_reg.fill(HIST("histTofNsigmaData"), momentum_Z_equal_2, track.tofNSigmaAl()); } } if (track.hasTOF()) { - spectra_reg.fill(HIST("histTofSignalData"), momentum * 2.0 * track.sign(), track.beta()); + 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; + } + spectra_reg.fill(HIST("histTofSignalData"), momentum_Z_equal_2 * track.sign(), track.beta()); } } } @@ -862,7 +1188,25 @@ struct NucleiHistTask { float Chi2perClusterTPC = track.tpcChi2NCl(); float Chi2perClusterITS = track.itsChi2NCl(); - 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) + if (TMath::Abs(track.dcaXY()) > maxDCA_XY || TMath::Abs(track.dcaZ()) > maxDCA_Z) + continue; + if (TPCnumberClsFound < minTPCnClsFound || TPC_nCls_Crossed_Rows < minNCrossedRowsTPC) + continue; + if (RatioCrossedRowsOverFindableTPC < minRatioCrossedRowsTPC || RatioCrossedRowsOverFindableTPC > maxRatioCrossedRowsTPC) + continue; + if (Chi2perClusterTPC > maxChi2PerClusterTPC || Chi2perClusterTPC < minChi2PerClusterTPC || Chi2perClusterITS > maxChi2PerClusterITS) + continue; + if (!(track.passedTPCRefit())) + continue; + if (!(track.passedITSRefit())) + continue; + if ((track.itsNClsInnerBarrel()) < minReqClusterITSib || (track.itsNCls()) < minReqClusterITS) + continue; + if (track.pt() < p_min || track.pt() > p_max) + continue; + if ((requireITS && !(track.hasITS())) || (requireTPC && !(track.hasTPC()))) + continue; + if (requireGoldenChi2 && !(track.passedGoldenChi2())) continue; TLorentzVector lorentzVector_pion{}; @@ -906,6 +1250,17 @@ struct NucleiHistTask { } 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; + } pion_reg.fill(HIST("histTofNsigmaData_cent"), momentum, track.tofNSigmaPi(), event.centFT0C()); proton_reg.fill(HIST("histTofNsigmaData_cent"), momentum, track.tofNSigmaPr(), event.centFT0C()); deuteron_reg.fill(HIST("histTofNsigmaData_cent"), momentum, track.tofNSigmaDe(), event.centFT0C()); @@ -956,6 +1311,17 @@ struct NucleiHistTask { } 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; + } apion_reg.fill(HIST("histTofNsigmaData_cent"), momentum, track.tofNSigmaPi(), event.centFT0C()); aproton_reg.fill(HIST("histTofNsigmaData_cent"), momentum, track.tofNSigmaPr(), event.centFT0C()); adeuteron_reg.fill(HIST("histTofNsigmaData_cent"), momentum, track.tofNSigmaDe(), event.centFT0C()); @@ -1023,9 +1389,11 @@ struct NucleiHistTask { MC_recon_reg.fill(HIST("histCentrality"), collisions.centFT0C()); for (auto& track : tracks) { + histTrackcuts_MC->AddBinContent(1); const auto particle = track.mcParticle(); if (!particle.isPhysicalPrimary()) continue; + histTrackcuts_MC->AddBinContent(2); int pdgbin = 0; switch (particle.pdgCode()) { @@ -1133,6 +1501,7 @@ struct NucleiHistTask { lorentzVector_He3.Rapidity() < yMin || lorentzVector_He3.Rapidity() > yMax || lorentzVector_He4.Rapidity() < yMin || lorentzVector_He4.Rapidity() > yMax) continue; + histTrackcuts_MC->AddBinContent(3); MC_recon_reg.fill(HIST("histEta"), track.eta(), pdgbin); @@ -1168,8 +1537,37 @@ struct NucleiHistTask { float Chi2perClusterTPC = track.tpcChi2NCl(); float Chi2perClusterITS = track.itsChi2NCl(); - 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 || TMath::Abs(track.dcaXY()) > maxDCA_XY || TMath::Abs(track.dcaZ()) > maxDCA_Z) + if (TMath::Abs(track.dcaXY()) > maxDCA_XY || TMath::Abs(track.dcaZ()) > maxDCA_Z) + continue; + histTrackcuts_MC->AddBinContent(4); + if (TPCnumberClsFound < minTPCnClsFound || TPC_nCls_Crossed_Rows < minNCrossedRowsTPC) + continue; + histTrackcuts_MC->AddBinContent(5); + if (RatioCrossedRowsOverFindableTPC < minRatioCrossedRowsTPC || RatioCrossedRowsOverFindableTPC > maxRatioCrossedRowsTPC) + continue; + histTrackcuts_MC->AddBinContent(6); + if (Chi2perClusterTPC > maxChi2PerClusterTPC || Chi2perClusterTPC < minChi2PerClusterTPC || Chi2perClusterITS > maxChi2PerClusterITS) + continue; + histTrackcuts_MC->AddBinContent(7); + if (!(track.passedTPCRefit())) + continue; + histTrackcuts_MC->AddBinContent(8); + if (!(track.passedITSRefit())) + continue; + histTrackcuts_MC->AddBinContent(9); + if ((track.itsNClsInnerBarrel()) < minReqClusterITSib || (track.itsNCls()) < minReqClusterITS) + continue; + histTrackcuts_MC->AddBinContent(10); + if (track.pt() < p_min || track.pt() > p_max) + continue; + histTrackcuts_MC->AddBinContent(11); + + if ((requireITS && !(track.hasITS())) || (requireTPC && !(track.hasTPC()))) + continue; + histTrackcuts_MC->AddBinContent(12); + if (requireGoldenChi2 && !(track.passedGoldenChi2())) continue; + histTrackcuts_MC->AddBinContent(13); float nSigmaPion = track.tpcNSigmaPi(); float nSigmaProton = track.tpcNSigmaPr(); diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx index 1fe1a563137..7d54bd86d48 100644 --- a/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx +++ b/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include "CommonDataFormat/InteractionRecord.h" @@ -267,7 +270,7 @@ struct hypertriton3bodyTrackMcinfo { Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; - o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; + o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; o2::pid::tof::TOFResoParamsV2 mRespParamsV2; void initCCDB(aod::BCsWithTimestamps::iterator const& bc) diff --git a/PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx b/PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx index a90b4677b61..7d3659419de 100644 --- a/PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx @@ -264,9 +264,9 @@ struct nuclei_in_jets { // standard selection if (!setDCAselectionPtDep) { - if (TMath::Abs(track.dcaXY()) > 0.1) + if (TMath::Abs(track.dcaXY()) > max_dcaxy) return false; - if (TMath::Abs(track.dcaZ()) > 0.1) + if (TMath::Abs(track.dcaZ()) > max_dcaz) return false; } @@ -378,7 +378,7 @@ struct nuclei_in_jets { double c = pz * pz * pz * pz - py * py * py * py - px * px * py * py; double delta = b * b - 4.0 * a * c; - // Protection agains delta<0 + // Protection against delta<0 if (delta < 0) { return; } @@ -1127,9 +1127,9 @@ struct nuclei_in_jets { continue; } if (!setDCAselectionPtDep) { - if (dcaxy > 0.1) + if (dcaxy > max_dcaxy) continue; - if (dcaz > 0.1) + if (dcaz > max_dcaz) continue; } @@ -1228,9 +1228,9 @@ struct nuclei_in_jets { continue; } if (!setDCAselectionPtDep) { - if (dcaxy > 0.1) + if (dcaxy > max_dcaxy) continue; - if (dcaz > 0.1) + if (dcaz > max_dcaz) continue; } diff --git a/PWGLF/Tasks/Nuspex/spectraTOF.cxx b/PWGLF/Tasks/Nuspex/spectraTOF.cxx index 942175867b7..a16e466f884 100644 --- a/PWGLF/Tasks/Nuspex/spectraTOF.cxx +++ b/PWGLF/Tasks/Nuspex/spectraTOF.cxx @@ -52,16 +52,21 @@ std::array, NpCharge> hDcaXYZMat; std::array, NpCharge> hDcaXYWrongCollisionPrm; std::array, NpCharge> hDcaXYWrongCollisionStr; std::array, NpCharge> hDcaXYWrongCollisionMat; -std::array, NpCharge> hDcaXYMC; // DCA xy in the MC -std::array, NpCharge> hDcaZMC; // DCA z in the MC -std::array, NpCharge> hDcaXYMCD0; // DCA xy in the MC for particles from D0 -std::array, NpCharge> hDcaZMCD0; // DCA z in the MC for particles from D0 -std::array, NpCharge> hDcaXYMCCharm; // DCA xy in the MC for particles from charm -std::array, NpCharge> hdcaZMCCharm; // DCA z in the MC for particles from charm -std::array, NpCharge> hDcaXYMCBeauty; // DCA xy in the MC for particles from beauty -std::array, NpCharge> hDcaZMCBeauty; // DCA z in the MC for particles from beauty -std::array, NpCharge> hDcaXYMCNotHF; // DCA xy in the MC for particles from not a HF -std::array, NpCharge> hDcaZMCNotHF; // DCA z in the MC for particles from not a HF +std::array, NpCharge> hDcaXYMC; // DCA xy in the MC +std::array, NpCharge> hDcaZMC; // DCA z in the MC +std::array, NpCharge> hDcaXYMCD0; // DCA xy in the MC for particles from D0 +std::array, NpCharge> hDcaZMCD0; // DCA z in the MC for particles from D0 +std::array, NpCharge> hDcaXYMCCharm; // DCA xy in the MC for particles from charm +std::array, NpCharge> hdcaZMCCharm; // DCA z in the MC for particles from charm +std::array, NpCharge> hDcaXYMCBeauty; // DCA xy in the MC for particles from beauty +std::array, NpCharge> hDcaZMCBeauty; // DCA z in the MC for particles from beauty +std::array, NpCharge> hDcaXYMCNotHF; // DCA xy in the MC for particles from not a HF +std::array, NpCharge> hDcaZMCNotHF; // DCA z in the MC for particles from not a HF +std::array, NpCharge> hDecayLengthStr; // Decay Length for particles from Strange +std::array, NpCharge> hDecayLengthMCD0; // Decay Length in the MC for particles from D0 +std::array, NpCharge> hDecayLengthMCCharm; // Decay Length in the MC for particles from charm +std::array, NpCharge> hDecayLengthMCBeauty; // Decay Length in the MC for particles from charm +std::array, NpCharge> hDecayLengthMCNotHF; // Decay Length in the MC for particles from not a HF // Spectra task struct tofSpectra { @@ -335,6 +340,7 @@ struct tofSpectra { const AxisSpec phiAxis{200, 0, 7, "#it{#varphi} (rad)"}; const AxisSpec dcaZAxis{binsOptions.binsDca, "DCA_{z} (cm)"}; const AxisSpec lengthAxis{100, 0, 600, "Track length (cm)"}; + const AxisSpec decayLengthAxis{100, 0, 0.1, "Decay Length (cm)"}; if (enableTrackCutHistograms) { const AxisSpec chargeAxis{2, -2.f, 2.f, "Charge"}; @@ -653,6 +659,7 @@ struct tofSpectra { histos.add(hdcazstr[i].data(), pTCharge[i], kTH2D, {ptAxis, dcaZAxis}); histos.add(hdcaxymat[i].data(), pTCharge[i], kTH2D, {ptAxis, dcaXyAxis}); histos.add(hdcazmat[i].data(), pTCharge[i], kTH2D, {ptAxis, dcaZAxis}); + hDecayLengthStr[i] = histos.add("decaylengthstr" + cpName, pTCharge[i], kTH2D, {ptAxis, decayLengthAxis}); if (enableDcaGoodEvents) { histos.add(hdcaxyprmgoodevs[i].data(), pTCharge[i], kTH2D, {ptAxis, dcaXyAxis}); histos.add(hdcazprmgoodevs[i].data(), pTCharge[i], kTH2D, {ptAxis, dcaZAxis}); @@ -668,6 +675,10 @@ struct tofSpectra { hdcaZMCCharm[i] = histos.add("dcazcharm" + cpName, pTCharge[i], kTH2D, {ptAxis, dcaZAxis}); hDcaXYMCBeauty[i] = histos.add("dcaxybeauty" + cpName, pTCharge[i], kTH2D, {ptAxis, dcaXyAxis}); hDcaZMCBeauty[i] = histos.add("dcazbeauty" + cpName, pTCharge[i], kTH2D, {ptAxis, dcaZAxis}); + hDecayLengthMCD0[i] = histos.add("decaylengthD0" + cpName, pTCharge[i], kTH2D, {ptAxis, decayLengthAxis}); + hDecayLengthMCCharm[i] = histos.add("decaylengthcharm" + cpName, pTCharge[i], kTH2D, {ptAxis, decayLengthAxis}); + hDecayLengthMCBeauty[i] = histos.add("decaylengthbeauty" + cpName, pTCharge[i], kTH2D, {ptAxis, decayLengthAxis}); + hDecayLengthMCNotHF[i] = histos.add("decaylengthnothf" + cpName, pTCharge[i], kTH2D, {ptAxis, decayLengthAxis}); } } @@ -1630,6 +1641,13 @@ struct tofSpectra { histos.fill(HIST(hdcaxystr[i]), track.pt(), track.dcaXY()); histos.fill(HIST(hdcazstr[i]), track.pt(), track.dcaZ()); } + if (mcParticle.has_daughters()) { + auto daughter0 = mcParticle.template daughters_as().begin(); + double vertexDau[3] = {daughter0.vx(), daughter0.vy(), daughter0.vz()}; + double vertexPrimary[3] = {mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()}; + auto decayLength = RecoDecay::distance(vertexPrimary, vertexDau) / 10000; + hDecayLengthStr[i]->Fill(track.pt(), decayLength); + } } else { if (enableDCAxyzHistograms) { hDcaXYZMat[i]->Fill(track.pt(), track.dcaXY(), track.dcaZ()); @@ -1658,23 +1676,23 @@ struct tofSpectra { bool IsD0Mother = false; bool IsCharmMother = false; bool IsBeautyMother = false; + bool IsNotHFMother = false; if (mcParticle.has_mothers()) { const int charmOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, mcParticle, false); for (const auto& mother : mcParticle.template mothers_as()) { - const int motherPdgCode = mother.pdgCode(); + const int motherPdgCode = std::abs(mother.pdgCode()); if (motherPdgCode == 421) { IsD0Mother = true; } - if (charmOrigin == RecoDecay::OriginType::NonPrompt) { - if ((motherPdgCode) / 1000 == 5 || (motherPdgCode) / 100 == 5) { - IsBeautyMother = true; - } + if (charmOrigin == RecoDecay::OriginType::NonPrompt && ((motherPdgCode) / 1000 == 5 || (motherPdgCode) / 100 == 5)) { + IsBeautyMother = true; + } + if (charmOrigin == RecoDecay::OriginType::Prompt && ((motherPdgCode) / 1000 == 4 || (motherPdgCode) / 100 == 4)) { + IsCharmMother = true; } - if (charmOrigin == RecoDecay::OriginType::Prompt) { - if ((motherPdgCode) / 1000 == 4 || (motherPdgCode) / 100 == 4) { - IsCharmMother = true; - } + if (!(motherPdgCode / 1000 == 4 || motherPdgCode / 100 == 4) && !(motherPdgCode / 1000 == 5 || motherPdgCode / 100 == 5)) { + IsNotHFMother = true; } } } @@ -1690,10 +1708,30 @@ struct tofSpectra { hDcaXYMCBeauty[i]->Fill(track.pt(), track.dcaXY()); hDcaZMCBeauty[i]->Fill(track.pt(), track.dcaZ()); } - if (!IsCharmMother && !IsBeautyMother) { + if (IsNotHFMother) { hDcaXYMCNotHF[i]->Fill(track.pt(), track.dcaXY()); hDcaZMCNotHF[i]->Fill(track.pt(), track.dcaZ()); } + + if (mcParticle.has_daughters()) { + auto daughter0 = mcParticle.template daughters_as().begin(); + double vertexDau[3] = {daughter0.vx(), daughter0.vy(), daughter0.vz()}; + double vertexPrimary[3] = {mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()}; + auto decayLength = RecoDecay::distance(vertexPrimary, vertexDau) / 10000; + + if (IsD0Mother) { + hDecayLengthMCD0[i]->Fill(track.pt(), decayLength); + } + if (IsCharmMother) { + hDecayLengthMCCharm[i]->Fill(track.pt(), decayLength); + } + if (IsBeautyMother) { + hDecayLengthMCBeauty[i]->Fill(track.pt(), decayLength); + } + if (IsNotHFMother) { + hDecayLengthMCNotHF[i]->Fill(track.pt(), decayLength); + } + } } } diff --git a/PWGLF/Tasks/QC/CMakeLists.txt b/PWGLF/Tasks/QC/CMakeLists.txt index 20377eb08cb..5fba2292100 100644 --- a/PWGLF/Tasks/QC/CMakeLists.txt +++ b/PWGLF/Tasks/QC/CMakeLists.txt @@ -72,7 +72,7 @@ o2physics_add_dpl_workflow(tpc-dedx-qa o2physics_add_dpl_workflow(vertexqa SOURCES vertexQA.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(efficiencyqa diff --git a/PWGLF/Tasks/QC/vertexQA.cxx b/PWGLF/Tasks/QC/vertexQA.cxx index 5e9060d51ce..66ae298813d 100644 --- a/PWGLF/Tasks/QC/vertexQA.cxx +++ b/PWGLF/Tasks/QC/vertexQA.cxx @@ -9,14 +9,18 @@ // 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 "CCDB/BasicCCDBManager.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" using namespace o2; using namespace o2::framework; @@ -34,7 +38,7 @@ double deltaTimeColl(BCcoll const bccoll1, BCcoll const bccoll2) auto coll2 = std::get(bccoll2); auto bc1 = std::get(bccoll1); auto bc2 = std::get(bccoll2); - int64_t tmpDT = int64_t(bc1.globalBC()) - int64_t(bc2.globalBC()); + int64_t tmpDT = static_cast(bc1.globalBC()) - static_cast(bc2.globalBC()); double deltaT = tmpDT * LHCBunchSpacingNS + coll1.collisionTime() - coll2.collisionTime(); return deltaT; } @@ -57,6 +61,9 @@ DECLARE_SOA_TABLE(VtxQAtable, "AOD", "VTXQATABLE", } // namespace o2::aod struct vertexQA { + Service ccdb; + ctpRateFetcher mRateFetcher; + Produces vtxQAtable; Configurable storeTree{"storeTree", 1000, "Store in tree collisions from BC's with more than 'storeTree' vertices, for in-depth analysis"}; @@ -87,10 +94,15 @@ struct vertexQA { ConfigurableAxis nContribAxis{"nContribBins", {1000, 0, 5000}, "Binning for number of contributors to PV"}; ConfigurableAxis nContribDiffAxis{"nContribDiffBins", {1000, -5000, 5000}, "Binning for the difference in number of contributors to PV"}; + ConfigurableAxis irBinning{"IRbinning", {500, 0, 100}, "Binning for the interaction rate (kHz)"}; + Configurable irSource{"irSource", "ZNC hadronic", "Source of the interaction rate"}; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; std::deque colls; + int64_t mFirstBCid = -1; + void init(InitContext const&) { histos.add("nVtxHistogram", ";#it{N}_{vtx}^{rec};Entries", HistType::kTH1F, {nVtxAxis}); @@ -121,6 +133,11 @@ struct vertexQA { histos.add("nContribITSRofTimeSeriesHistogram", ";#it{N}_{contrib}^{1};#it{N}_{contrib}^{2}", HistType::kTH2F, {nContribAxis, nContribAxis}); histos.add("tDiffDuplicateTimeSeriesHistogram", ";#Delta#it{t}_{vtx} (ns);Entries", HistType::kTH1F, {tDiffVtxAxisExtend}); + histos.add("tIRvsCollisionRateHistogram", Form(";IR from %s (kHz);IR from reconstructed vertices (kHz)", irSource.value.data()), HistType::kTH2D, {irBinning, irBinning}); + + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); } void process(aod::BC const& bc, aod::Collisions const& collisions) @@ -231,6 +248,48 @@ struct vertexQA { } } } + PROCESS_SWITCH(vertexQA, process, "Standard vertex QA", true); + + void processIR(aod::BCsWithTimestamps const& bcs, aod::Collisions const& collisions) + { + if (collisions.size() <= 2) { + return; + } + + std::vector jumps{0ll}; + int64_t lastBC = bcs.rawIteratorAt(0).globalBC(); + for (auto bc : bcs) { + if (bc.globalBC() - lastBC > 3564 * 32) { // 32 orbits + jumps.push_back(bc.globalIndex()); + lastBC = bc.globalBC(); + } + } + uint64_t jumpsSentinel{1}; + std::vector collisionsIndices{0ll}; + for (auto col : collisions) { + if (jumpsSentinel == jumps.size()) { + break; + } + if (col.bcId() > jumps[jumpsSentinel]) { + collisionsIndices.push_back(col.globalIndex()); + jumpsSentinel++; + } + } + jumps.push_back(bcs.size()); + collisionsIndices.push_back(collisions.size()); + + for (size_t i{0}; i < jumps.size() - 1; ++i) { + auto startBC = bcs.rawIteratorAt(jumps[i]); + auto endBC = bcs.rawIteratorAt(jumps[i + 1] - 1); + double startIR = mRateFetcher.fetch(ccdb.service, startBC.timestamp(), startBC.runNumber(), irSource.value); + double endIR = mRateFetcher.fetch(ccdb.service, endBC.timestamp(), endBC.runNumber(), irSource.value); + double deltaT = (endBC.globalBC() - startBC.globalBC()) * LHCBunchSpacingNS * 1.e-9; + double collisionRate = (collisionsIndices[i + 1] - collisionsIndices[i]) / deltaT; /// -1 to remove the bias of the collisions at extremities? + double ir = (startIR + endIR) * 0.5; + histos.fill(HIST("tIRvsCollisionRateHistogram"), ir * 1.e-3, collisionRate * 1.e-3); + } + } + PROCESS_SWITCH(vertexQA, processIR, "Checks on interaction rate", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Resonances/kstarpbpb.cxx b/PWGLF/Tasks/Resonances/kstarpbpb.cxx index 9f5e61b2503..712b2d411a3 100644 --- a/PWGLF/Tasks/Resonances/kstarpbpb.cxx +++ b/PWGLF/Tasks/Resonances/kstarpbpb.cxx @@ -102,9 +102,12 @@ struct kstarpbpb { Configurable additionalEvsel{"additionalEvsel", false, "Additional event selcection"}; Configurable timFrameEvsel{"timFrameEvsel", false, "TPC Time frame boundary cut"}; Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; + Configurable OnlyTOF{"OnlyTOF", true, "OnlyTOF"}; Configurable strategyPID{"strategyPID", 2, "PID strategy"}; Configurable isGI{"isGI", false, "pT dependent PID"}; + Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.0, "cut TOF beta"}; Configurable additionalQAplots{"additionalQAplots", true, "Additional QA plots"}; + Configurable additionalQAplots1{"additionalQAplots1", true, "Additional QA plots"}; Configurable confMinRot{"confMinRot", 5.0 * TMath::Pi() / 6.0, "Minimum of rotation"}; Configurable confMaxRot{"confMaxRot", 7.0 * TMath::Pi() / 6.0, "Maximum of rotation"}; Configurable nBkgRotations{"nBkgRotations", 9, "Number of rotated copies (background) per each original candidate"}; @@ -148,13 +151,6 @@ struct kstarpbpb { AxisSpec occupancyAxis = {occupancyBinning, "Occupancy"}; histos.add("hpTvsRapidity", "pT vs Rapidity", kTH2F, {{100, 0.0f, 10.0f}, {300, -1.5f, 1.5f}}); - histos.add("hFTOCvsTPCSelected", "Mult correlation FT0C vs. TPC after selection", kTH2F, {{80, 0.0f, 80.0f}, {100, -0.5f, 5999.5f}}); - histos.add("hCentrality", "Centrality distribution", kTH1F, {{200, 0.0, 200.0}}); - histos.add("hOccupancy", "Occupancy distribution", kTH1F, {occupancyAxis}); - histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); - histos.add("hPsiFT0C", "PsiFT0C", kTH2F, {centAxis, phiAxis}); - histos.add("hPsiFT0A", "PsiFT0A", kTH2F, {centAxis, phiAxis}); - histos.add("hPsiTPC", "PsiTPC", kTH2F, {centAxis, phiAxis}); histos.add("TPC_Nsigma_pi", "TPC_Nsigma_pi", kTH2F, {{60, 0.0f, 6.0f}, {500, -5, 5}}); histos.add("TPC_Nsigma_ka", "TPC_Nsigma_ka", kTH2F, {{60, 0.0f, 6.0f}, {500, -5, 5}}); histos.add("TOF_Nsigma_pi", "TOF_Nsigma_pi", kTH2F, {{60, 0.0f, 6.0f}, {500, -5, 5}}); @@ -164,11 +160,18 @@ struct kstarpbpb { histos.add("hSparseV2SAlikeEventPP_V2", "hSparseV2SAlikeEventPP_V2", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisV2, thnAxisCentrality}); histos.add("hSparseV2SAMixedEvent_V2", "hSparseV2SAMixedEvent_V2", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisV2, thnAxisCentrality}); histos.add("hSparseV2SASameEventRotational_V2", "hSparseV2SASameEventRotational_V2", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisV2, thnAxisCentrality}); - - // histogram for resolution - histos.add("ResFT0CTPC", "ResFT0CTPC", kTH2F, {centAxis, resAxis}); - histos.add("ResFT0CFT0A", "ResFT0CFT0A", kTH2F, {centAxis, resAxis}); - histos.add("ResFT0ATPC", "ResFT0ATPC", kTH2F, {centAxis, resAxis}); + if (additionalQAplots1) { + histos.add("hFTOCvsTPCSelected", "Mult correlation FT0C vs. TPC after selection", kTH2F, {{80, 0.0f, 80.0f}, {100, -0.5f, 5999.5f}}); + histos.add("hCentrality", "Centrality distribution", kTH1F, {{200, 0.0, 200.0}}); + histos.add("hOccupancy", "Occupancy distribution", kTH1F, {occupancyAxis}); + histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); + histos.add("hPsiFT0C", "PsiFT0C", kTH2F, {centAxis, phiAxis}); + histos.add("hPsiFT0A", "PsiFT0A", kTH2F, {centAxis, phiAxis}); + histos.add("hPsiTPC", "PsiTPC", kTH2F, {centAxis, phiAxis}); + histos.add("ResFT0CTPC", "ResFT0CTPC", kTH2F, {centAxis, resAxis}); + histos.add("ResFT0CFT0A", "ResFT0CFT0A", kTH2F, {centAxis, resAxis}); + histos.add("ResFT0ATPC", "ResFT0ATPC", kTH2F, {centAxis, resAxis}); + } if (additionalQAplots) { // DCA QA histos.add("QAbefore/trkDCAxyka", "DCAxy distribution of kaon track candidates", HistType::kTH1F, {{150, 0.0f, 1.0f}}); @@ -256,17 +259,17 @@ struct kstarpbpb { bool selectionPIDNew(const T& candidate, int PID) { if (PID == 0) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && candidate.hasTOF() && ((candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) + (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa())) < (nsigmaCutCombined * nsigmaCutCombined)) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } } else if (PID == 1) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { + if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && candidate.hasTOF() && ((candidate.tofNSigmaPi() * candidate.tofNSigmaPi()) + (candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi())) < (nsigmaCutCombined * nsigmaCutCombined)) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { return true; } } @@ -277,11 +280,23 @@ struct kstarpbpb { bool selectionPID(const T& candidate, int PID) { if (PID == 0) { - if (candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { + if (!OnlyTOF && !candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + return true; + } + if (!OnlyTOF && candidate.hasTOF() && ((candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) + (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa())) < (nsigmaCutCombined * nsigmaCutCombined)) { + return true; + } + if (OnlyTOF && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } } else if (PID == 1) { - if (candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { + if (!OnlyTOF && !candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaPi()) < nsigmaCutTPC) { + return true; + } + if (!OnlyTOF && candidate.hasTOF() && ((candidate.tofNSigmaPi() * candidate.tofNSigmaPi()) + (candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi())) < (nsigmaCutCombined * nsigmaCutCombined)) { + return true; + } + if (OnlyTOF && candidate.hasTOF() && TMath::Abs(candidate.tofNSigmaPi()) < nsigmaCutTOF) { return true; } } @@ -393,16 +408,18 @@ struct kstarpbpb { if (additionalEvsel && !eventSelected(collision, centrality)) { return; } - histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); - histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); - histos.fill(HIST("hPsiFT0A"), centrality, psiFT0A); - histos.fill(HIST("hPsiTPC"), centrality, psiTPC); - histos.fill(HIST("ResFT0CTPC"), centrality, TMath::Cos(2.0 * (psiFT0C - psiTPC))); - histos.fill(HIST("ResFT0CFT0A"), centrality, TMath::Cos(2.0 * (psiFT0C - psiFT0A))); - histos.fill(HIST("ResFT0ATPC"), centrality, TMath::Cos(2.0 * (psiTPC - psiFT0A))); - histos.fill(HIST("hCentrality"), centrality); - histos.fill(HIST("hOccupancy"), occupancy); - histos.fill(HIST("hVtxZ"), collision.posZ()); + if (additionalQAplots1) { + histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); + histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); + histos.fill(HIST("hPsiFT0A"), centrality, psiFT0A); + histos.fill(HIST("hPsiTPC"), centrality, psiTPC); + histos.fill(HIST("ResFT0CTPC"), centrality, TMath::Cos(2.0 * (psiFT0C - psiTPC))); + histos.fill(HIST("ResFT0CFT0A"), centrality, TMath::Cos(2.0 * (psiFT0C - psiFT0A))); + histos.fill(HIST("ResFT0ATPC"), centrality, TMath::Cos(2.0 * (psiTPC - psiFT0A))); + histos.fill(HIST("hCentrality"), centrality); + histos.fill(HIST("hOccupancy"), occupancy); + histos.fill(HIST("hVtxZ"), collision.posZ()); + } for (auto track1 : tracks) { if (!selectionTrack(track1)) { continue; @@ -514,17 +531,18 @@ struct kstarpbpb { if (additionalEvsel && !eventSelected(collision, centrality)) { return; } - histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); - histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); - histos.fill(HIST("hPsiFT0A"), centrality, psiFT0A); - histos.fill(HIST("hPsiTPC"), centrality, psiTPC); - histos.fill(HIST("ResFT0CTPC"), centrality, TMath::Cos(2.0 * (psiFT0C - psiTPC))); - histos.fill(HIST("ResFT0CFT0A"), centrality, TMath::Cos(2.0 * (psiFT0C - psiFT0A))); - histos.fill(HIST("ResFT0ATPC"), centrality, TMath::Cos(2.0 * (psiTPC - psiFT0A))); - histos.fill(HIST("hCentrality"), centrality); - histos.fill(HIST("hOccupancy"), occupancy); - histos.fill(HIST("hVtxZ"), collision.posZ()); - + if (additionalQAplots1) { + histos.fill(HIST("hFTOCvsTPCSelected"), centrality, multTPC); + histos.fill(HIST("hPsiFT0C"), centrality, psiFT0C); + histos.fill(HIST("hPsiFT0A"), centrality, psiFT0A); + histos.fill(HIST("hPsiTPC"), centrality, psiTPC); + histos.fill(HIST("ResFT0CTPC"), centrality, TMath::Cos(2.0 * (psiFT0C - psiTPC))); + histos.fill(HIST("ResFT0CFT0A"), centrality, TMath::Cos(2.0 * (psiFT0C - psiFT0A))); + histos.fill(HIST("ResFT0ATPC"), centrality, TMath::Cos(2.0 * (psiTPC - psiFT0A))); + histos.fill(HIST("hCentrality"), centrality); + histos.fill(HIST("hOccupancy"), occupancy); + histos.fill(HIST("hVtxZ"), collision.posZ()); + } for (auto track1 : posThisColl) { if (!selectionTrack(track1)) { continue; diff --git a/PWGLF/Tasks/Resonances/lambda1520analysis.cxx b/PWGLF/Tasks/Resonances/lambda1520analysis.cxx index 5884c7b067a..97cec72b2c2 100644 --- a/PWGLF/Tasks/Resonances/lambda1520analysis.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520analysis.cxx @@ -15,6 +15,7 @@ #include "TLorentzVector.h" #include "TF1.h" +#include "TRandom3.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "PWGLF/DataModel/LFResonanceTables.h" @@ -39,14 +40,12 @@ struct lambda1520analysis { // switches Configurable cEtaAssym{"cEtaAssym", false, "Turn on/off EtaAssym calculation"}; Configurable isFilladditionalQA{"isFilladditionalQA", false, "Turn on/off additional QA plots"}; - Configurable cAddlTrackcut{"cAddlTrackcut", false, "Switch to turn on/off Additional track cut"}; Configurable cOldPIDcut{"cOldPIDcut", false, "Switch to turn on/off old PID cut to apply pt dependent cut"}; Configurable FixedPIDcut{"FixedPIDcut", false, "Switch to turn on/off FIXED PID cut to apply pt dependent cut"}; Configurable cRejectPion{"cRejectPion", false, "Switch to turn on/off pion contamination"}; Configurable cDCAr7SigCut{"cDCAr7SigCut", false, "Track DCAr 7 Sigma cut to PV Maximum"}; Configurable cKinCuts{"cKinCuts", false, "Kinematic Cuts for p-K pair opening angle"}; Configurable cTPCNClsFound{"cTPCNClsFound", false, "Switch to turn on/off TPCNClsFound cut"}; - Configurable additionalEvsel{"additionalEvsel", true, "Additional event selcection"}; Configurable additionalQAeventPlots{"additionalQAeventPlots", false, "Additional QA event plots"}; Configurable additionalMEPlots{"additionalMEPlots", false, "Additional Mixed event plots"}; @@ -73,6 +72,8 @@ struct lambda1520analysis { Configurable cfgHasITS{"cfgHasITS", false, "Require ITS"}; Configurable cfgHasTPC{"cfgHasTPC", false, "Require TPC"}; Configurable cfgHasTOF{"cfgHasTOF", false, "Require TOF"}; + Configurable cfgUseTPCRefit{"cfgUseTPCRefit", false, "Require TPC Refit"}; + Configurable cfgUseITSRefit{"cfgUseITSRefit", false, "Require ITS Refit"}; /// PID Selections Configurable cRejNsigmaTpc{"cRejNsigmaTpc", 3.0, "Reject tracks to improve purity of TPC PID"}; // Reject missidentified particles when tpc bands merge @@ -121,6 +122,11 @@ struct lambda1520analysis { Configurable cfgCutsOnMother{"cfgCutsOnMother", false, "Enamble additional cuts on mother"}; Configurable cMaxPtMotherCut{"cMaxPtMotherCut", 10.0, "Maximum pt of mother cut"}; Configurable cMaxMinvMotherCut{"cMaxMinvMotherCut", 3.0, "Maximum Minv of mother cut"}; + Configurable cfgCutsOnDaughters{"cfgCutsOnDaughters", false, "Enamble additional cuts on daughters"}; + Configurable cetaphiBins{"cetaphiBins", 400, "number of eta and phi bins"}; + Configurable cMaxDeltaEtaCut{"cMaxDeltaEtaCut", 0.7, "Maximum deltaEta between daughters"}; + Configurable cMaxDeltaPhiCut{"cMaxDeltaPhiCut", 1.5, "Maximum deltaPhi between daughters"}; + TRandom* rn = new TRandom(); /// Figures ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 7.0, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9.0, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 11.0, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12.0, 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14.0, 14.1, 14.2, 14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15.0}, "Binning of the pT axis"}; @@ -132,13 +138,14 @@ struct lambda1520analysis { ConfigurableAxis binsTPCXrows{"binsTPCXrows", {200, 0, 200}, ""}; ConfigurableAxis binsnSigma{"binsnSigma", {130, -6.5, 6.5}, ""}; ConfigurableAxis binsnTPCSignal{"binsnTPCSignal", {1000, 0, 1000}, ""}; + ConfigurableAxis occupancy_bins{"occupancy_bins", {VARIABLE_WIDTH, 0.0, 100, 500, 600, 1000, 1100, 1500, 1600, 2000, 2100, 2500, 2600, 3000, 3100, 3500, 3600, 4000, 4100, 4500, 4600, 5000, 5100, 9999}, "Binning of the occupancy axis"}; + Configurable applyOccupancyCut{"applyOccupancyCut", false, "Apply occupancy cut"}; + Configurable OccupancyCut{"OccupancyCut", 1000, "Mimimum Occupancy cut"}; - // Event selection cuts - (Temporary, need to fix!) - TF1* fMultPVCutLow = nullptr; - TF1* fMultPVCutHigh = nullptr; - TF1* fMultCutLow = nullptr; - TF1* fMultCutHigh = nullptr; - TF1* fMultMultPVCut = nullptr; + // Rotational background + Configurable IsCalcRotBkg{"IsCalcRotBkg", true, "Calculate rotational background"}; + Configurable rotational_cut{"rotational_cut", 10, "Cut value (Rotation angle pi - pi/cut and pi + pi/cut)"}; + Configurable c_nof_rotations{"c_nof_rotations", 3, "Number of random rotations in the rotational background"}; void init(o2::framework::InitContext&) { @@ -153,6 +160,7 @@ struct lambda1520analysis { AxisSpec pidQAAxis = {binsnSigma, "#sigma"}; AxisSpec axisTPCSignal = {binsnTPCSignal, ""}; AxisSpec mcLabelAxis = {5, -0.5, 4.5, "MC Label"}; + AxisSpec occupancy_axis = {occupancy_bins, "Occupancy [-40,100]"}; if (additionalQAeventPlots) { // Test on Mixed event @@ -198,16 +206,10 @@ struct lambda1520analysis { histos.add("TPCncluster/TPCnclusterPhika", "TPC ncluster vs phi", kTH2F, {{160, 0, 160, "TPC nCluster"}, {63, 0, 6.28, "#phi"}}); // Multiplicity correlation calibrations - histos.add("MultCalib/centglopr_before", "Centrality vs Global-Tracks", kTH2F, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}}); - histos.add("MultCalib/centgloka_before", "Centrality vs Global-Tracks", kTH2F, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}}); - histos.add("MultCalib/GloPVpr_before", "Global tracks vs PV tracks", kTH2F, {{500, 0, 5000, "Global tracks"}, {500, 0, 5000, "PV tracks"}}); - histos.add("MultCalib/GloPVka_before", "Global tracks vs PV tracks", kTH2F, {{500, 0, 5000, "Global tracks"}, {500, 0, 5000, "PV tracks"}}); - - // Multiplicity correlation calibrations - histos.add("MultCalib/centglopr_after", "Centrality vs Global-Tracks", kTH2F, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}}); - histos.add("MultCalib/centgloka_after", "Centrality vs Global-Tracks", kTH2F, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}}); - histos.add("MultCalib/GloPVpr_after", "Global tracks vs PV tracks", kTH2F, {{500, 0, 5000, "Global tracks"}, {500, 0, 5000, "PV tracks"}}); - histos.add("MultCalib/GloPVka_after", "Global tracks vs PV tracks", kTH2F, {{500, 0, 5000, "Global tracks"}, {500, 0, 5000, "PV tracks"}}); + histos.add("MultCalib/centglopr", "Centrality vs Global-Tracks", kTH2F, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}}); + histos.add("MultCalib/centgloka", "Centrality vs Global-Tracks", kTH2F, {{110, 0, 110, "Centrality"}, {500, 0, 5000, "Global Tracks"}}); + histos.add("MultCalib/GloPVpr", "Global tracks vs PV tracks", kTH2F, {{500, 0, 5000, "Global tracks"}, {500, 0, 5000, "PV tracks"}}); + histos.add("MultCalib/GloPVka", "Global tracks vs PV tracks", kTH2F, {{500, 0, 5000, "Global tracks"}, {500, 0, 5000, "PV tracks"}}); } // PID QA after cuts @@ -241,6 +243,26 @@ struct lambda1520analysis { histos.add("Result/Data/lambda1520invmassLSPP", "Invariant mass of #Lambda(1520) Like Sign Method K^{#plus}p^{#plus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K+ + Pr histos.add("Result/Data/lambda1520invmassLSMM", "Invariant mass of #Lambda(1520) Like Sign Method K^{#minus}p^{#minus}; Invariant Mass (GeV/#it{c}^2); Counts;", {HistType::kTH1F, {axisMassLambda1520}}); // K- + anti-Pr + // eta phi QA + if (cfgCutsOnDaughters) { + histos.add("QAbefore/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 3.15}}); + histos.add("QAbefore/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 3.15}}); + + histos.add("QAafter/deltaEta", "deltaEta of kaon and proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 3.15}}); + histos.add("QAafter/deltaPhi", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 3.15}}); + + histos.add("QAafter/deltaEtaafter", "deltaEta of kaon and proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 3.15}}); + histos.add("QAafter/deltaPhiafter", "deltaPhi of kaon and proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 3.15}}); + histos.add("QAafter/EtaPrafter", "Eta of proton candidates", HistType::kTH1F, {{cetaphiBins, -1.6, 1.6}}); + histos.add("QAafter/PhiPrafter", "Phi of proton candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 6.30}}); + histos.add("QAafter/EtaKaafter", "Eta of kaon candidates", HistType::kTH1F, {{cetaphiBins, -1.6, 1.6}}); + histos.add("QAafter/PhiKaafter", "Phi of kaon candidates", HistType::kTH1F, {{cetaphiBins, 0.0, 6.30}}); + } + + if (IsCalcRotBkg) { + histos.add("Result/Data/h3lambda1520InvMassRotation", "Invariant mass of #Lambda(1520) rotation", kTHnSparseF, {axisMult, axisPt, axisMassLambda1520, occupancy_axis}); + } + // 3d histogram histos.add("Result/Data/h3lambda1520invmass", "Invariant mass of #Lambda(1520) K^{#pm}p^{#mp}", HistType::kTH3F, {axisMult, axisPt, axisMassLambda1520}); histos.add("Result/Data/h3antilambda1520invmass", "Invariant mass of #Lambda(1520) K^{#mp}p^{#pm}", HistType::kTH3F, {axisMult, axisPt, axisMassLambda1520}); @@ -301,45 +323,11 @@ struct lambda1520analysis { histos.add("Result/MC/hantilambda1520Recoinvmass", "Inv mass distribution of Reconstructed MC Anti-#Lambda(1520)", kTH1F, {axisMassLambda1520}); } - if (additionalEvsel) { - 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); - } // Print output histograms statistics LOG(info) << "Size of the histograms in spectraTOF"; histos.print(); } - template - bool eventSelected(TCollision collision, const float& centrality) - { - // if (collision.alias_bit(kTVXinTRD)) { - // // TRD triggered - // // return 0; - // } - auto multNTracksPV = collision.multNTracksPV(); - 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; - } - double massKa = MassKaonCharged; double massPr = MassProton; @@ -358,22 +346,22 @@ struct lambda1520analysis { } if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut) return false; - if (track.tpcNClsCrossedRows() < cMinTPCncr) + if (track.itsNCls() < cfgITScluster) return false; - if (cAddlTrackcut) { - if (!track.passedITSRefit() || !track.passedTPCRefit()) - return false; - if (track.tpcCrossedRowsOverFindableCls() < cfgRatioTPCRowsOverFindableCls) - return false; - if (track.itsChi2NCl() > cMaxChi2ITScut) - return false; - if (track.tpcChi2NCl() > cMaxChi2TPCcut) - return false; - if (track.itsNCls() < cfgITScluster) - return false; - } if (cTPCNClsFound && (track.tpcNClsFound() < cMinTPCNClsFound)) return false; + if (track.tpcCrossedRowsOverFindableCls() < cfgRatioTPCRowsOverFindableCls) + return false; + if (track.itsChi2NCl() > cMaxChi2ITScut) + return false; + if (track.tpcChi2NCl() > cMaxChi2TPCcut) + return false; + if (cfgHasITS && !track.hasITS()) + return false; + if (cfgHasTPC && !track.hasTPC()) + return false; + if (cfgHasTOF && !track.hasTOF()) + return false; if (cfgPrimaryTrack && !track.isPrimaryTrack()) return false; if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) @@ -382,11 +370,11 @@ struct lambda1520analysis { return false; if (cfgGlobalTrack && !track.isGlobalTrack()) return false; - if (cfgHasITS && !track.hasITS()) + if (cfgUseITSRefit && !track.passedITSRefit()) return false; - if (cfgHasTPC && !track.hasTPC()) + if (cfgUseTPCRefit && !track.passedTPCRefit()) return false; - if (cfgHasTOF && !track.hasTOF()) + if (track.tpcNClsCrossedRows() < cMinTPCncr) return false; return true; @@ -679,25 +667,20 @@ struct lambda1520analysis { { auto multiplicity = collision.cent(); - // Multiplicity correlation calibration plots - if (isFilladditionalQA) { - if constexpr (IsData) { - histos.fill(HIST("MultCalib/centglopr_before"), multiplicity, dTracks1.size()); - histos.fill(HIST("MultCalib/centgloka_before"), multiplicity, dTracks2.size()); - histos.fill(HIST("MultCalib/GloPVpr_before"), dTracks1.size(), collision.multNTracksPV()); - histos.fill(HIST("MultCalib/GloPVka_before"), dTracks2.size(), collision.multNTracksPV()); - } - } + // LOG(info) << "Before pass, Collision index:" << collision.index() << "multiplicity: " << collision.cent() << std::endl; - if (additionalEvsel && !eventSelected(collision, multiplicity)) { + auto occupancy_no = collision.trackOccupancyInTimeRange(); + if (applyOccupancyCut && occupancy_no < OccupancyCut) { return; } + + // Multiplicity correlation calibration plots if (isFilladditionalQA) { if constexpr (IsData) { - histos.fill(HIST("MultCalib/centglopr_after"), multiplicity, dTracks1.size()); - histos.fill(HIST("MultCalib/centgloka_after"), multiplicity, dTracks2.size()); - histos.fill(HIST("MultCalib/GloPVpr_after"), dTracks1.size(), collision.multNTracksPV()); - histos.fill(HIST("MultCalib/GloPVka_after"), dTracks2.size(), collision.multNTracksPV()); + histos.fill(HIST("MultCalib/centglopr"), multiplicity, dTracks1.size()); + histos.fill(HIST("MultCalib/centgloka"), multiplicity, dTracks2.size()); + histos.fill(HIST("MultCalib/GloPVpr"), dTracks1.size(), collision.multNTracksPV()); + histos.fill(HIST("MultCalib/GloPVka"), dTracks2.size(), collision.multNTracksPV()); } } @@ -714,8 +697,8 @@ struct lambda1520analysis { histos.fill(HIST("TestME/hnTrksMixedE"), dTracks1.size()); } } - - TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance; + // LOG(info) << "After pass, Collision index:" << collision.index() << "multiplicity: " << collision.cent() << std::endl; + TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance, ldaughter_rot, lresonance_rot; for (auto& [trk1, trk2] : combinations(CombinationsFullIndexPolicy(dTracks1, dTracks2))) { // Full index policy is needed to consider all possible combinations @@ -746,6 +729,10 @@ struct lambda1520analysis { auto trk2NSigmaKaTPC = trk2.tpcNSigmaKa(); auto trk2NSigmaKaTOF = (isTrk2hasTOF) ? trk2.tofNSigmaKa() : -999.; + auto deltaEta = TMath::Abs(trk1.eta() - trk2.eta()); + auto deltaPhi = TMath::Abs(trk1.phi() - trk2.phi()); + deltaPhi = (deltaPhi > TMath::Pi()) ? (2 * TMath::Pi() - deltaPhi) : deltaPhi; + //// QA plots before the selection // --- Track QA all if constexpr (IsData) { @@ -771,6 +758,10 @@ struct lambda1520analysis { histos.fill(HIST("QA/QAbefore/Track/TPC_CR"), trk1ptPr, trk1.tpcNClsCrossedRows()); histos.fill(HIST("QA/QAbefore/Track/pT"), trk1ptPr); histos.fill(HIST("QA/QAbefore/Track/eta"), trk1.eta()); + if (cfgCutsOnDaughters) { + histos.fill(HIST("QAbefore/deltaEta"), deltaEta); + histos.fill(HIST("QAbefore/deltaPhi"), deltaPhi); + } } //// Apply the pid selection @@ -823,7 +814,10 @@ struct lambda1520analysis { histos.fill(HIST("QA/QAafter/Kaon/TPC_CR"), trk2ptKa, trk2.tpcNClsCrossedRows()); histos.fill(HIST("QA/QAafter/Kaon/pT"), trk2ptKa); histos.fill(HIST("QA/QAafter/Kaon/eta"), trk2.eta()); - + if (cfgCutsOnDaughters) { + histos.fill(HIST("QAafter/deltaEta"), deltaEta); + histos.fill(HIST("QAafter/deltaPhi"), deltaPhi); + } if (isFilladditionalQA) { // TPCncluster distributions histos.fill(HIST("TPCncluster/TPCnclusterpr"), trk1.tpcNClsFound()); @@ -843,8 +837,8 @@ struct lambda1520analysis { } //// Resonance reconstruction - lDecayDaughter1.SetXYZM(trk1.px(), trk1.py(), trk1.pz(), massPr); - lDecayDaughter2.SetXYZM(trk2.px(), trk2.py(), trk2.pz(), massKa); + lDecayDaughter1.SetPtEtaPhiM(trk1.pt(), trk1.eta(), trk1.phi(), massPr); + lDecayDaughter2.SetPtEtaPhiM(trk2.pt(), trk2.eta(), trk2.phi(), massKa); lResonance = lDecayDaughter1 + lDecayDaughter2; // Rapidity cut if (abs(lResonance.Rapidity()) > 0.5) @@ -857,13 +851,38 @@ struct lambda1520analysis { continue; } + if (cfgCutsOnDaughters) { + if (deltaEta >= cMaxDeltaEtaCut) + continue; + if (deltaPhi >= cMaxDeltaPhiCut) + continue; + + if constexpr (!IsMix) { + histos.fill(HIST("QAafter/EtaPrafter"), trk1.eta()); + histos.fill(HIST("QAafter/PhiPrafter"), trk1.phi()); + histos.fill(HIST("QAafter/EtaKaafter"), trk2.eta()); + histos.fill(HIST("QAafter/PhiKaafter"), trk2.phi()); + histos.fill(HIST("QAafter/deltaEtaafter"), deltaEta); + histos.fill(HIST("QAafter/deltaPhiafter"), deltaPhi); + } + } + //// Un-like sign pair only if (trk1.sign() * trk2.sign() < 0) { if constexpr (IsData) { + if (IsCalcRotBkg) { + for (int i = 0; i < c_nof_rotations; i++) { + float theta2 = rn->Uniform(TMath::Pi() - TMath::Pi() / rotational_cut, TMath::Pi() + TMath::Pi() / rotational_cut); + ldaughter_rot.SetPtEtaPhiM(trk2.pt(), trk2.eta(), trk2.phi() + theta2, massKa); // for rotated background + lresonance_rot = lDecayDaughter1 + ldaughter_rot; + histos.fill(HIST("Result/Data/h3lambda1520InvMassRotation"), multiplicity, lresonance_rot.Pt(), lresonance_rot.M(), occupancy_no); + } + } + if (trk1.sign() < 0) { histos.fill(HIST("Result/Data/lambda1520invmass"), lResonance.M()); histos.fill(HIST("Result/Data/h3lambda1520invmass"), multiplicity, lResonance.Pt(), lResonance.M()); - } else { + } else if (trk1.sign() > 0) { histos.fill(HIST("Result/Data/antilambda1520invmass"), lResonance.M()); histos.fill(HIST("Result/Data/h3antilambda1520invmass"), multiplicity, lResonance.Pt(), lResonance.M()); } @@ -981,16 +1000,12 @@ struct lambda1520analysis { continue; if (abs(part.y()) > 0.5) // rapidity cut continue; - bool pass1 = false; - bool pass2 = false; - if (abs(part.daughterPDG1()) == 321 || abs(part.daughterPDG2()) == 321) { // At least one decay to Kaon - pass2 = true; - } - if (abs(part.daughterPDG1()) == 2212 || abs(part.daughterPDG2()) == 2212) { // At least one decay to Proton - pass1 = true; - } + bool pass1 = abs(part.daughterPDG1()) == 321 || abs(part.daughterPDG2()) == 321; // At least one decay to Kaon + bool pass2 = abs(part.daughterPDG1()) == 2212 || abs(part.daughterPDG2()) == 2212; // At least one decay to Proton + if (!pass1 || !pass2) // If we have both decay products continue; + if (collision.isVtxIn10()) // INEL10 { if (part.pdgCode() > 0) diff --git a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx index 9537b986a04..9d41ffb6eaa 100644 --- a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include "TRandom3.h" #include "Math/Vector3D.h" @@ -73,18 +74,18 @@ struct phianalysisrun3_PbPb { Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"}; Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; Configurable nsigmaCutTPC{"nsigmacutTPC", 2.0, "Value of the TPC Nsigma cut"}; + Configurable nsigmaCutTOF{"nsigmacutTOF", 2.0, "Value of the TOF Nsigma cut"}; Configurable nsigmaCutCombined{"nsigmaCutCombined", 3.0, "Value of the TOF Nsigma cut"}; Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, "Number of mixed events per event"}; Configurable fillOccupancy{"fillOccupancy", true, "fill Occupancy"}; Configurable cfgOccupancyCut{"cfgOccupancyCut", 2500, "Occupancy cut"}; + Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.0, "cut TOF beta"}; Configurable isNoTOF{"isNoTOF", false, "isNoTOF"}; - Configurable isEtaAssym{"isEtaAssym", false, "isEtaAssym"}; Configurable additionalEvSel2{"additionalEvSel2", true, "Additional evsel2"}; Configurable additionalEvSel3{"additionalEvSel3", true, "Additional evsel3"}; Configurable cfgMultFT0{"cfgMultFT0", true, "cfgMultFT0"}; Configurable iscustomDCAcut{"iscustomDCAcut", false, "iscustomDCAcut"}; Configurable ismanualDCAcut{"ismanualDCAcut", true, "ismanualDCAcut"}; - Configurable isITSOnlycut{"isITSOnlycut", true, "isITSOnlycut"}; Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; Configurable confRapidity{"confRapidity", 0.5, "Rapidity cut"}; @@ -106,24 +107,13 @@ struct phianalysisrun3_PbPb { histos.add("hOccupancy", "Occupancy distribution", kTH1F, {occupancyAxis}); if (!isMC) { histos.add("h3PhiInvMassUnlikeSign", "Invariant mass of Phi meson Unlike Sign", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassLikeSignPP", "Invariant mass of Phi meson Like Sign positive", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassLikeSignMM", "Invariant mass of Phi meson Like Sign negative", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); histos.add("h3PhiInvMassMixed", "Invariant mass of Phi meson Mixed", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassRotation", "Invariant mass of Phi meson Rotation", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - if (isEtaAssym) { - histos.add("h3PhiInvMassUnlikeSignAside", "Invariant mass of Phi meson Unlike Sign A side", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassLikeSignAside", "Invariant mass of Phi meson Like Sign A side", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassMixedAside", "Invariant mass of Phi meson Mixed A side", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassUnlikeSignCside", "Invariant mass of Phi meson Unlike Sign C side", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassLikeSignCside", "Invariant mass of Phi meson Like Sign C side", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - histos.add("h3PhiInvMassMixedCside", "Invariant mass of Phi meson Mixed C side", kTH3F, {{200, 0.0, 200.0}, {200, 0.0f, 20.0f}, {200, 0.9, 1.1}}); - } } else if (isMC) { histos.add("hMC", "MC Event statistics", kTH1F, {{10, 0.0f, 10.0f}}); histos.add("h1PhiGen", "Phi meson Gen", kTH1F, {{200, 0.0f, 20.0f}}); - histos.add("h1PhiGen1", "Phi meson Gen", kTH1F, {{200, 0.0f, 20.0f}}); histos.add("h1PhiRecsplit", "Phi meson Rec split", kTH1F, {{200, 0.0f, 20.0f}}); histos.add("Centrec", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); + histos.add("Centgen", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); histos.add("h2PhiRec2", "Phi meson Rec", kTH2F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}}); histos.add("h3PhiRec3", "Phi meson Rec", kTH3F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}, {200, 0.9, 1.1}}); histos.add("h2PhiGen2", "Phi meson gen", kTH2F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}}); @@ -166,9 +156,6 @@ struct phianalysisrun3_PbPb { if (ismanualDCAcut && !(candidate.isGlobalTrackWoDCA() && candidate.isPVContributor() && std::abs(candidate.dcaXY()) < cfgCutDCAxy && std::abs(candidate.dcaZ()) < cfgCutDCAz && candidate.itsNCls() > cfgITScluster)) { return false; } - if (isITSOnlycut && !(candidate.isPVContributor() && std::abs(candidate.dcaXY()) < cfgCutDCAxy && std::abs(candidate.dcaZ()) < cfgCutDCAz && candidate.itsNCls() > cfgITScluster)) { - return false; - } return true; } @@ -189,10 +176,10 @@ struct phianalysisrun3_PbPb { template bool selectionPIDpTdependent(const T& candidate) { - if (candidate.pt() < 0.5 && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { return true; } - if (candidate.pt() >= 0.5 && candidate.hasTOF() && ((candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) + (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa())) < (nsigmaCutCombined * nsigmaCutCombined)) { + if (candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { return true; } return false; @@ -215,79 +202,43 @@ struct phianalysisrun3_PbPb { 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) + void FillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, float massd1, float massd2) { pvec0 = array{candidate1.px(), candidate1.py(), candidate1.pz()}; pvec1 = array{candidate2.px(), candidate2.py(), candidate2.pz()}; - pvec1rotation = array{-candidate2.px(), -candidate2.py(), candidate2.pz()}; auto arrMom = array{pvec0, pvec1}; - auto arrMomrotation = array{pvec0, pvec1rotation}; int track1Sign = candidate1.sign(); int track2Sign = candidate2.sign(); mass = RecoDecay::m(arrMom, array{massd1, massd2}); - massrotation = RecoDecay::m(arrMomrotation, array{massd1, massd2}); pT = RecoDecay::pt(array{candidate1.px() + candidate2.px(), candidate1.py() + candidate2.py()}); rapidity = RecoDecay::y(array{candidate1.px() + candidate2.px(), candidate1.py() + candidate2.py(), candidate1.pz() + candidate2.pz()}, mass); - if (isEtaAssym && unlike && track1Sign * track2Sign < 0) { - if (candidate1.eta() > 0.2 && candidate1.eta() < 0.8 && candidate2.eta() > 0.2 && candidate2.eta() < 0.8) { - histos.fill(HIST("h3PhiInvMassUnlikeSignAside"), multiplicity, pT, mass); - } else if (candidate1.eta() > -0.6 && candidate1.eta() < 0.0 && candidate2.eta() > -0.6 && candidate2.eta() < 0.0) { - histos.fill(HIST("h3PhiInvMassUnlikeSignCside"), multiplicity, pT, mass); - } - } - if (isEtaAssym && mix && track1Sign * track2Sign < 0) { - if (candidate1.eta() > 0.2 && candidate1.eta() < 0.8 && candidate2.eta() > 0.2 && candidate2.eta() < 0.8) { - histos.fill(HIST("h3PhiInvMassMixedAside"), multiplicity, pT, mass); - } else if (candidate1.eta() > -0.6 && candidate1.eta() < 0.0 && candidate2.eta() > -0.6 && candidate2.eta() < 0.0) { - histos.fill(HIST("h3PhiInvMassMixedCside"), multiplicity, pT, mass); - } - } - if (isEtaAssym && likesign && track1Sign * track2Sign > 0) { - if (candidate1.eta() > 0.2 && candidate1.eta() < 0.8 && candidate2.eta() > 0.2 && candidate2.eta() < 0.8) { - histos.fill(HIST("h3PhiInvMassLikeSignAside"), multiplicity, pT, mass); - } else if (candidate1.eta() > -0.6 && candidate1.eta() < 0.0 && candidate2.eta() > -0.6 && candidate2.eta() < 0.0) { - histos.fill(HIST("h3PhiInvMassLikeSignCside"), multiplicity, pT, mass); - } - } // default filling - if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign < 0) { + if (std::abs(rapidity) < 0.5 && track1Sign * track2Sign < 0) { if (unlike) { histos.fill(HIST("h3PhiInvMassUnlikeSign"), multiplicity, pT, mass); } if (mix) { histos.fill(HIST("h3PhiInvMassMixed"), multiplicity, pT, mass); } - if (rotation) { - histos.fill(HIST("h3PhiInvMassRotation"), multiplicity, pT, massrotation); - } - } - if (std::abs(rapidity) < 0.5 && !isEtaAssym && track1Sign * track2Sign > 0 && likesign) { - if (track1Sign > 0 && track2Sign > 0) { - histos.fill(HIST("h3PhiInvMassLikeSignPP"), multiplicity, pT, mass); - } else { - histos.fill(HIST("h3PhiInvMassLikeSignMM"), multiplicity, pT, mass); - } } } - Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using EventCandidates = soa::Filtered>; - using TrackCandidates = soa::Filtered>; + using TrackCandidates = soa::Filtered>; // using EventCandidatesMC = soa::Join; using EventCandidatesMC = soa::Join; using TrackCandidatesMC = soa::Filtered>; using CollisionMCTrueTable = aod::McCollisions; using TrackMCTrueTable = aod::McParticles; using CollisionMCRecTableCentFT0C = soa::SmallGroups>; - using TrackMCRecTable = soa::Join; + using TrackMCRecTable = soa::Join; using FilTrackMCRecTable = soa::Filtered; ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; @@ -298,15 +249,7 @@ struct phianalysisrun3_PbPb { SliceCache cache; - // using BinningType = BinningPolicy>; - // BinningType binningOnPositions{{axisVertex, axisMultiplicityClass}, true}; - - // using BinningTypeTPCMultiplicity = ColumnBinningPolicy; using BinningTypeVertexContributor = ColumnBinningPolicy; - // using BinningTypeCentrality = ColumnBinningPolicy; - - // using BinningType = ColumnBinningPolicy; - // BinningType binningOnPositions{{axisVertex, axisMultiplicity}, true}; ROOT::Math::PxPyPzMVector PhiMesonMother, KaonPlus, KaonMinus; void processSameEvent(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) { @@ -320,7 +263,7 @@ struct phianalysisrun3_PbPb { return; } int occupancy = collision.trackOccupancyInTimeRange(); - if (fillOccupancy && occupancy < cfgOccupancyCut) // occupancy info is available for this collision (*) + if (fillOccupancy && occupancy > cfgOccupancyCut) // occupancy info is available for this collision (*) { return; } @@ -354,31 +297,21 @@ struct phianalysisrun3_PbPb { } bool unlike = true; bool mix = false; - bool likesign = true; - bool rotation = true; - if (isITSOnlycut) { - histos.fill(HIST("QAafter/TPC_Nsigma_all"), track1.pt(), track1.tpcNSigmaKa()); - histos.fill(HIST("QAafter/TOF_Nsigma_all"), track1.pt(), track1.tofNSigmaKa()); - histos.fill(HIST("QAafter/trkDCAxy"), track1.dcaXY()); - histos.fill(HIST("QAafter/trkDCAz"), track1.dcaZ()); - histos.fill(HIST("QAafter/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); - FillinvMass(track1, track2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); - } - if (!isITSOnlycut && !ispTdepPID && selectionPID(track1) && selectionPID(track2)) { + if (!ispTdepPID && selectionPID(track1) && selectionPID(track2)) { histos.fill(HIST("QAafter/TPC_Nsigma_all"), track1.pt(), track1.tpcNSigmaKa()); histos.fill(HIST("QAafter/TOF_Nsigma_all"), track1.pt(), track1.tofNSigmaKa()); histos.fill(HIST("QAafter/trkDCAxy"), track1.dcaXY()); histos.fill(HIST("QAafter/trkDCAz"), track1.dcaZ()); histos.fill(HIST("QAafter/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); - FillinvMass(track1, track2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); + FillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); } - if (!isITSOnlycut && ispTdepPID && selectionPIDpTdependent(track1) && selectionPIDpTdependent(track2)) { + if (ispTdepPID && selectionPIDpTdependent(track1) && selectionPIDpTdependent(track2)) { histos.fill(HIST("QAafter/TPC_Nsigma_all"), track1.pt(), track1.tpcNSigmaKa()); histos.fill(HIST("QAafter/TOF_Nsigma_all"), track1.pt(), track1.tofNSigmaKa()); histos.fill(HIST("QAafter/trkDCAxy"), track1.dcaXY()); histos.fill(HIST("QAafter/trkDCAz"), track1.dcaZ()); histos.fill(HIST("QAafter/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); - FillinvMass(track1, track2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); + FillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -412,7 +345,7 @@ struct phianalysisrun3_PbPb { } int occupancy1 = c1.trackOccupancyInTimeRange(); int occupancy2 = c2.trackOccupancyInTimeRange(); - if (fillOccupancy && occupancy1 < cfgOccupancyCut && occupancy2 < cfgOccupancyCut) // occupancy info is available for this collision (*) + if (fillOccupancy && occupancy1 > cfgOccupancyCut && occupancy2 > cfgOccupancyCut) // occupancy info is available for this collision (*) { return; } @@ -425,8 +358,6 @@ struct phianalysisrun3_PbPb { for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; bool mix = true; - bool likesign = false; - bool rotation = false; if (!selectionTrack(t1)) { continue; } @@ -436,14 +367,11 @@ struct phianalysisrun3_PbPb { if (!selectionPair(t1, t2)) { continue; } - if (isITSOnlycut) { - FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); + if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { + FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } - if (!isITSOnlycut && !ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); - } - if (!isITSOnlycut && ispTdepPID && selectionPIDpTdependent(t1) && selectionPIDpTdependent(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); + if (ispTdepPID && selectionPIDpTdependent(t1) && selectionPIDpTdependent(t2)) { + FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -472,6 +400,11 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("hMC"), 5); continue; } + int occupancy = RecCollision.trackOccupancyInTimeRange(); + if (fillOccupancy && occupancy > cfgOccupancyCut) // occupancy info is available for this collision (*) + { + return; + } if (TMath::Abs(RecCollision.posZ()) > cfgCutVertex) { histos.fill(HIST("hMC"), 6); continue; @@ -625,6 +558,169 @@ struct phianalysisrun3_PbPb { } // process MC PROCESS_SWITCH(phianalysisrun3_PbPb, processMC, "Process Reconstructed", false); + 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"), 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; + } + } + } + if (Nchinel > 0 && std::abs(mcCollision.posZ()) < cfgCutVertex) + histos.fill(HIST("hMC"), 2.5); + std::vector SelectedEvents(collisions.size()); + int nevts = 0; + auto multiplicity = 0; + for (const auto& collision : collisions) { + if (!collision.sel8() || std::abs(collision.mcCollision().posZ()) > cfgCutVertex) { + continue; + } + multiplicity = collision.centFT0C(); + histos.fill(HIST("Centgen"), multiplicity); + SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + } + SelectedEvents.resize(nevts); + const auto evtReconstructedAndSelected = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcCollision.globalIndex()) != SelectedEvents.end(); + histos.fill(HIST("hMC"), 3.5); + if (!evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + return; + } + histos.fill(HIST("hMC"), 4.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; + } + if (kCurrentDaughter.pdgCode() == +321) { + daughtp = true; + } else if (kCurrentDaughter.pdgCode() == -321) { + daughtm = true; + } + } + if (daughtp && daughtm) { + histos.fill(HIST("h1PhiGen"), mcParticle.pt()); + histos.fill(HIST("h2PhiGen2"), mcParticle.pt(), multiplicity); + } + } + } + PROCESS_SWITCH(phianalysisrun3_PbPb, processGen, "Process Generated", false); + void processRec(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const& /*mcParticles*/, aod::McCollisions const& /*mcCollisions*/) + { + if (!collision.has_mcCollision()) { + return; + } + if (std::abs(collision.mcCollision().posZ()) > cfgCutVertex || !collision.sel8()) { + return; + } + auto multiplicity = collision.centFT0C(); + histos.fill(HIST("Centrec"), multiplicity); + histos.fill(HIST("hMC"), 5.5); + auto oldindex = -999; + for (auto track1 : tracks) { + if (!selectionTrack(track1)) { + continue; + } + if (!track1.has_mcParticle()) { + continue; + } + auto track1ID = track1.index(); + for (auto track2 : tracks) { + if (!track2.has_mcParticle()) { + continue; + } + if (!selectionTrack(track2)) { + continue; + } + auto track2ID = track2.index(); + if (track2ID <= track1ID) { + continue; + } + if (!selectionPair(track1, track2)) { + continue; + } + if (track1.sign() * track2.sign() > 0) { + continue; + } + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); + if (!mctrack1.isPhysicalPrimary()) { + continue; + } + if (!mctrack2.isPhysicalPrimary()) { + continue; + } + if (!(track1PDG == 321 && track2PDG == 321)) { + continue; + } + for (auto& mothertrack1 : mctrack1.mothers_as()) { + for (auto& mothertrack2 : mctrack2.mothers_as()) { + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { + continue; + } + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { + continue; + } + if (!mothertrack1.producedByGenerator()) { + continue; + } + if (std::abs(mothertrack1.y()) >= 0.5) { + continue; + } + if (std::abs(mothertrack1.pdgCode()) != 333) { + continue; + } + if (!ispTdepPID && (!selectionPID(track1) || !selectionPID(track2))) { + continue; + } + if (ispTdepPID && (!selectionPIDpTdependent(track1) || !selectionPIDpTdependent(track2))) { + continue; + } + if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + histos.fill(HIST("h1PhiRecsplit"), mothertrack1.pt()); + continue; + } + oldindex = mothertrack1.globalIndex(); + pvec0 = array{track1.px(), track1.py(), track1.pz()}; + pvec1 = array{track2.px(), track2.py(), track2.pz()}; + auto arrMomrec = array{pvec0, pvec1}; + auto motherP = mothertrack1.p(); + auto motherE = mothertrack1.e(); + genMass = std::sqrt(motherE * motherE - motherP * motherP); + recMass = RecoDecay::m(arrMomrec, array{massKa, massKa}); + auto recpt = TMath::Sqrt((track1.px() + track2.px()) * (track1.px() + track2.px()) + (track1.py() + track2.py()) * (track1.py() + track2.py())); + histos.fill(HIST("h1PhiRec1"), mothertrack1.pt()); + histos.fill(HIST("h2PhiRec2"), mothertrack1.pt(), multiplicity); + histos.fill(HIST("h1Phimassgen"), genMass); + histos.fill(HIST("h1Phimassrec"), recMass); + histos.fill(HIST("h1Phipt"), recpt); + } + } + } + } + } + + PROCESS_SWITCH(phianalysisrun3_PbPb, processRec, "Process Reconstructed", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGLF/Tasks/Resonances/phipbpb.cxx b/PWGLF/Tasks/Resonances/phipbpb.cxx index 9930f231c25..8d837d8314f 100644 --- a/PWGLF/Tasks/Resonances/phipbpb.cxx +++ b/PWGLF/Tasks/Resonances/phipbpb.cxx @@ -152,6 +152,7 @@ struct phipbpb { const AxisSpec thnAxisV2{configThnAxisV2, "V2"}; const AxisSpec thnAxisRapidity{configThnAxisRapidity, "Rapidity"}; const AxisSpec thnAxisSA{configThnAxisSA, "SA"}; + AxisSpec cumulantAxis = {200, -1, 1, "phi"}; AxisSpec phiAxis = {500, -6.28, 6.28, "phi"}; AxisSpec resAxis = {2000, -10, 10, "Res"}; AxisSpec centAxis = {8, 0, 80, "V0M (%)"}; @@ -175,6 +176,11 @@ struct phipbpb { histos.add("hPsiTPCR", "PsiTPCR", kTH3F, {centAxis, occupancyAxis, phiAxis}); histos.add("hPsiTPCL", "PsiTPCL", kTH3F, {centAxis, occupancyAxis, phiAxis}); + histos.add("hSparseV2SameEventCosPhi", "hSparseV2SameEventCosPhi", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, cumulantAxis, thnAxisCentrality}); + histos.add("hSparseV2SameEventSinPhi", "hSparseV2SameEventSinPhi", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, cumulantAxis, thnAxisCentrality}); + histos.add("hSparseV2SameEventCosPsi", "hSparseV2SameEventCosPsi", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, cumulantAxis, thnAxisCentrality}); + histos.add("hSparseV2SameEventSinPsi", "hSparseV2SameEventSinPsi", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, cumulantAxis, thnAxisCentrality}); + histos.add("hSparseV2SameEventCosDeltaPhi", "hSparseV2SameEventCosDeltaPhi", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisV2, thnAxisCentrality}); histos.add("hSparseV2MixedEventCosDeltaPhi", "hSparseV2MixedEventCosDeltaPhi", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisV2, thnAxisCentrality}); @@ -455,10 +461,16 @@ struct phipbpb { auto phiminuspsi = GetPhiInRange(PhiMesonMother.Phi() - psiFT0C); auto v2 = TMath::Cos(2.0 * phiminuspsi); auto v2sin = TMath::Sin(2.0 * phiminuspsi); + auto phimother = PhiMesonMother.Phi(); histos.fill(HIST("hpTvsRapidity"), PhiMesonMother.Pt(), PhiMesonMother.Rapidity()); if (TMath::Abs(PhiMesonMother.Rapidity()) < confRapidity) { histos.fill(HIST("hSparseV2SameEventCosDeltaPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2 * QFT0C, centrality); histos.fill(HIST("hSparseV2SameEventSinDeltaPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2sin * QFT0C, centrality); + + histos.fill(HIST("hSparseV2SameEventCosPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), TMath::Cos(2.0 * phimother), centrality); + histos.fill(HIST("hSparseV2SameEventSinPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), TMath::Sin(2.0 * phimother), centrality); + histos.fill(HIST("hSparseV2SameEventCosPsi"), PhiMesonMother.M(), PhiMesonMother.Pt(), TMath::Cos(2.0 * psiFT0C), centrality); + histos.fill(HIST("hSparseV2SameEventSinPsi"), PhiMesonMother.M(), PhiMesonMother.Pt(), TMath::Sin(2.0 * psiFT0C), centrality); } ROOT::Math::Boost boost{PhiMesonMother.BoostToCM()}; fourVecDauCM = boost(KaonMinus); diff --git a/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx index 3bbff7b117a..d92e48733b5 100644 --- a/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx +++ b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx @@ -216,8 +216,8 @@ struct cascpostprocessing { registry.add("hPtCascPlusTrueRec", "hPtCascPlusTrueRec", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); registry.add("hPtCascMinusTrueRec", "hPtCascMinusTrueRec", {HistType::kTH3F, {ptAxis, rapidityAxis, centFT0MAxis}}); - registry.add("hCascMinusMassvsPtTrueRec", "hCascMinusMassvsPtTrueRec", {HistType::kTH2F, {ptAxis, massAxis}}); - registry.add("hCascPlusMassvsPtTrueRec", "hCascPlusMassvsPtTrueRec", {HistType::kTH2F, {ptAxis, massAxis}}); + registry.add("hCascMinusMassvsPtTrueRec", "hCascMinusMassvsPtTrueRec", {HistType::kTH3F, {ptAxis, massAxis, centFT0MAxis}}); + registry.add("hCascPlusMassvsPtTrueRec", "hCascPlusMassvsPtTrueRec", {HistType::kTH3F, {ptAxis, massAxis, centFT0MAxis}}); registry.add("hCascMinusMassvsPtBG", "hCascMinusMassvsPtBG", {HistType::kTH2F, {ptAxis, massAxis}}); registry.add("hCascPlusMassvsPtBG", "hCascPlusMassvsPtBG", {HistType::kTH2F, {ptAxis, massAxis}}); if (isMC) { @@ -489,7 +489,7 @@ struct cascpostprocessing { if (candidate.sign() < 0) { if (isCorrectlyRec) { registry.fill(HIST("hPtCascMinusTrueRec"), candidate.pt(), rapidity, candidate.centFT0M()); // 3rd axis is from MC calibration - registry.fill(HIST("hCascMinusMassvsPtTrueRec"), candidate.pt(), invmass); + registry.fill(HIST("hCascMinusMassvsPtTrueRec"), candidate.pt(), invmass, candidate.centFT0M()); } else { registry.fill(HIST("hCascMinusMassvsPtBG"), candidate.pt(), invmass); } @@ -500,7 +500,7 @@ struct cascpostprocessing { if (candidate.sign() > 0) { if (isCorrectlyRec) { registry.fill(HIST("hPtCascPlusTrueRec"), candidate.pt(), rapidity, candidate.centFT0M()); // 3rd axis is from MC calibration - registry.fill(HIST("hCascPlusMassvsPtTrueRec"), candidate.pt(), invmass); + registry.fill(HIST("hCascPlusMassvsPtTrueRec"), candidate.pt(), invmass, candidate.centFT0M()); } else { registry.fill(HIST("hCascPlusMassvsPtBG"), candidate.pt(), invmass); } diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx index d287bd0f7aa..c40b0e6adb3 100644 --- a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx @@ -80,6 +80,7 @@ struct derivedlambdakzeroanalysis { Configurable calculateFeeddownMatrix{"calculateFeeddownMatrix", true, "fill feeddown matrix if MC"}; Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; + Configurable requireTriggerTVX{"requireTriggerTVX", true, "require FT0 vertex (acceptable FT0C-FT0A time difference) at trigger level"}; Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; @@ -94,6 +95,8 @@ struct derivedlambdakzeroanalysis { Configurable requireNoCollInROFStd{"requireNoCollInROFStd", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF with mult. above a certain threshold"}; Configurable requireNoCollInROFStrict{"requireNoCollInROFStrict", false, "reject collisions corrupted by the cannibalism, with other collisions within the same ITS ROF"}; + Configurable maxZVtxPosition{"maxZVtxPosition", 10., "max Z vtx position"}; + Configurable useFT0CbasedOccupancy{"useFT0CbasedOccupancy", false, "Use sum of FT0-C amplitudes for estimating occupancy? (if not, use track-based definition)"}; // fast check on occupancy Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; @@ -148,6 +151,7 @@ struct derivedlambdakzeroanalysis { // for MC Configurable doMCAssociation{"doMCAssociation", true, "if MC, do MC association"}; + Configurable doTreatPiToMuon{"doTreatPiToMuon", false, "Take pi decay into muon into account in MC"}; Configurable doCollisionAssociationQA{"doCollisionAssociationQA", true, "check collision association"}; // Machine learning evaluation for pre-selection and corresponding information generation @@ -389,22 +393,23 @@ struct derivedlambdakzeroanalysis { histos.add("hEventSelection", "hEventSelection", kTH1F, {{20, -0.5f, +19.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.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "kIsTriggerTVX"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "kIsVertexITSTPC"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsGoodZvtxFT0vsPV"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsVertexTOFmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTRDmatched"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kNoSameBunchPileup"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoCollInTimeRangeStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStrict"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeNarrow"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeVzDep"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInRofStd"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStrict"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "Below min occup."); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Above max occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(6, "posZ cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(7, "kIsVertexITSTPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(8, "kIsGoodZvtxFT0vsPV"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(9, "kIsVertexTOFmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(10, "kIsVertexTRDmatched"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(11, "kNoSameBunchPileup"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(12, "kNoCollInTimeRangeStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "kNoCollInTimeRangeStrict"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "kNoCollInTimeRangeNarrow"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "kNoCollInTimeRangeVzDep"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "kNoCollInRofStd"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(17, "kNoCollInRofStrict"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(18, "Below min occup."); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(19, "Above max occup."); histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); histos.add("hCentralityVsNch", "hCentralityVsNch", kTH2F, {axisCentrality, axisNch}); @@ -685,7 +690,8 @@ struct derivedlambdakzeroanalysis { histos.print(); } - void initCCDB(soa::Join::iterator const& collision) + template + void initCCDB(TCollision collision) { if (mRunNumber == collision.runNumber()) { return; @@ -816,19 +822,22 @@ struct derivedlambdakzeroanalysis { // precalculate this information so that a check is one mask operation, not many { uint64_t bitMap = 0; - // check for specific particle species + bool isPositiveProton = v0.pdgCodePositive() == 2212; + bool isPositivePion = v0.pdgCodePositive() == 211 || (doTreatPiToMuon && v0.pdgCodePositive() == -13); + bool isNegativeProton = v0.pdgCodeNegative() == -2212; + bool isNegativePion = v0.pdgCodeNegative() == -211 || (doTreatPiToMuon && v0.pdgCodeNegative() == 13); - if (v0.pdgCode() == 310 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -211) { + if (v0.pdgCode() == 310 && isPositivePion && isNegativePion) { bitset(bitMap, selConsiderK0Short); if (v0.isPhysicalPrimary()) bitset(bitMap, selPhysPrimK0Short); } - if (v0.pdgCode() == 3122 && v0.pdgCodePositive() == 2212 && v0.pdgCodeNegative() == -211) { + if (v0.pdgCode() == 3122 && isPositiveProton && isNegativePion) { bitset(bitMap, selConsiderLambda); if (v0.isPhysicalPrimary()) bitset(bitMap, selPhysPrimLambda); } - if (v0.pdgCode() == -3122 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -2212) { + if (v0.pdgCode() == -3122 && isPositivePion && isNegativeProton) { bitset(bitMap, selConsiderAntiLambda); if (v0.isPhysicalPrimary()) bitset(bitMap, selPhysPrimAntiLambda); @@ -1335,108 +1344,214 @@ struct derivedlambdakzeroanalysis { } } - // ______________________________________________________ - // Real data processing - no MC subscription - void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) + template + bool IsEventAccepted(TCollision collision, bool fillHists) + // check whether the collision passes our collision selections { - // Fire up CCDB - if ((mlConfigurations.useK0ShortScores && mlConfigurations.calculateK0ShortScores) || - (mlConfigurations.useLambdaScores && mlConfigurations.calculateLambdaScores) || - (mlConfigurations.useAntiLambdaScores && mlConfigurations.calculateAntiLambdaScores)) { - initCCDB(collision); - } + if (fillHists) + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); - histos.fill(HIST("hEventSelection"), 0. /* all collisions */); if (requireSel8 && !collision.sel8()) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); - if (std::abs(collision.posZ()) > 10.f) { - return; + if (requireTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + return false; } - histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 2 /* FT0 vertex (acceptable FT0C-FT0A time difference) collisions */); if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return; + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + + if (std::abs(collision.posZ()) > maxZVtxPosition) { + return false; } - histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 5 /* vertex-Z selected */); if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 5 /* Contains at least one ITS-TPC track */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 6 /* Contains at least one ITS-TPC track */); if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 6 /* PV position consistency check */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 7 /* PV position consistency check */); if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 7 /* PV with at least one contributor matched with TOF */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TOF */); if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TRD */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 9 /* PV with at least one contributor matched with TRD */); if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 9 /* Not at same bunch pile-up */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 10 /* Not at same bunch pile-up */); if (requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 10 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); + if (fillHists) + histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); if (requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 10 microseconds */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 10 microseconds */); if (requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 2 microseconds */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 13 /* No other collision within +/- 2 microseconds */); if (requireNoCollInTimeRangeVzDep && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeVzDependent)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 13 /* No other collision with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 14 /* No other collision with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ */); if (requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF with mult. above a certain threshold */); if (requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 16 /* No other collision within the same ITS ROF */); float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); if (minOccupancy > 0 && collisionOccupancy < minOccupancy) { - return; + return false; } - histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); + if (fillHists) + histos.fill(HIST("hEventSelection"), 17 /* Below min occupancy */); + if (maxOccupancy > 0 && collisionOccupancy > maxOccupancy) { + return false; + } + if (fillHists) + histos.fill(HIST("hEventSelection"), 18 /* Above max occupancy */); + + return true; + } + + // ______________________________________________________ + // Simulated processing + // Return the list of indices to the recoed collision associated to a given MC collision. + std::vector getListOfRecoCollIndices(soa::Join const& mcCollisions, soa::Join const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + // Find the collision with the biggest nbr of PV contributors + // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 + int biggestNContribs = -1; + int bestCollisionIndex = -1; + for (auto const& collision : groupedCollisions) { + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + bestCollisionIndex = collision.globalIndex(); + } + } + listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; + } + return listBestCollisionIdx; + } + + // ______________________________________________________ + // Simulated processing + // Fill generated event information (for event loss/splitting estimation) + void fillGeneratedEventProperties(soa::Join const& mcCollisions, soa::Join const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + histos.fill(HIST("hGenEvents"), mcCollision.multMCNParticlesEta05(), 0 /* all gen. events*/); + + auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); + // Check if there is at least one of the reconstructed collisions associated to this MC collision + // If so, we consider it + bool atLeastOne = false; + int biggestNContribs = -1; + float centrality = 100.5f; + int nCollisions = 0; + for (auto const& collision : groupedCollisions) { + + if (!IsEventAccepted(collision, false)) { + continue; + } + + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + centrality = collision.centFT0C(); + } + nCollisions++; + + atLeastOne = true; + } + + histos.fill(HIST("hCentralityVsNcoll_beforeEvSel"), centrality, groupedCollisions.size()); + histos.fill(HIST("hCentralityVsNcoll_afterEvSel"), centrality, nCollisions); + + histos.fill(HIST("hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); + + if (atLeastOne) { + histos.fill(HIST("hGenEvents"), mcCollision.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); + + histos.fill(HIST("hGenEventCentrality"), centrality); + } + } + return; + } + + // ______________________________________________________ + // Real data processing - no MC subscription + void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) + { + // Fire up CCDB + if ((mlConfigurations.useK0ShortScores && mlConfigurations.calculateK0ShortScores) || + (mlConfigurations.useLambdaScores && mlConfigurations.calculateLambdaScores) || + (mlConfigurations.useAntiLambdaScores && mlConfigurations.calculateAntiLambdaScores)) { + initCCDB(collision); + } + + if (!IsEventAccepted(collision, true)) { return; } - histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); float centrality = collision.centFT0C(); if (qaCentrality) { auto hRawCentrality = histos.get(HIST("hRawCentrality")); centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); } + float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); // gap side int gapSide = collision.gapSide(); @@ -1495,99 +1610,25 @@ struct derivedlambdakzeroanalysis { // ______________________________________________________ // Simulated processing (subscribes to MC information too) - void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&) + void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join const& /*mccollisions*/, soa::Join const&) { - histos.fill(HIST("hEventSelection"), 0. /* all collisions */); - if (requireSel8 && !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 */); - - if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - return; - } - histos.fill(HIST("hEventSelection"), 3 /* Not at ITS ROF border */); - - if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - return; - } - histos.fill(HIST("hEventSelection"), 4 /* Not at TF border */); - - if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { - return; - } - histos.fill(HIST("hEventSelection"), 5 /* Contains at least one ITS-TPC track */); - - if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - return; - } - histos.fill(HIST("hEventSelection"), 6 /* PV position consistency check */); - - if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { - return; - } - histos.fill(HIST("hEventSelection"), 7 /* PV with at least one contributor matched with TOF */); - - if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { - return; - } - histos.fill(HIST("hEventSelection"), 8 /* PV with at least one contributor matched with TRD */); - - if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - return; - } - histos.fill(HIST("hEventSelection"), 9 /* Not at same bunch pile-up */); - - if (requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - return; - } - histos.fill(HIST("hEventSelection"), 10 /* No other collision within +/- 2 microseconds or mult above a certain threshold in -4 - -2 microseconds*/); - - if (requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { - return; - } - histos.fill(HIST("hEventSelection"), 11 /* No other collision within +/- 10 microseconds */); - - if (requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { - return; - } - histos.fill(HIST("hEventSelection"), 12 /* No other collision within +/- 2 microseconds */); - - if (requireNoCollInTimeRangeVzDep && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeVzDependent)) { - return; - } - histos.fill(HIST("hEventSelection"), 13 /* No other collision with pvZ of drifting TPC tracks from past/future collisions within 2.5 cm the current pvZ */); - - if (requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - return; - } - histos.fill(HIST("hEventSelection"), 14 /* No other collision within the same ITS ROF with mult. above a certain threshold */); - - if (requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { - return; + // Fire up CCDB + if ((mlConfigurations.useK0ShortScores && mlConfigurations.calculateK0ShortScores) || + (mlConfigurations.useLambdaScores && mlConfigurations.calculateLambdaScores) || + (mlConfigurations.useAntiLambdaScores && mlConfigurations.calculateAntiLambdaScores)) { + initCCDB(collision); } - histos.fill(HIST("hEventSelection"), 15 /* No other collision within the same ITS ROF */); - float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); - if (minOccupancy > 0 && collisionOccupancy < minOccupancy) { - return; - } - histos.fill(HIST("hEventSelection"), 16 /* Below min occupancy */); - if (maxOccupancy > 0 && collisionOccupancy > maxOccupancy) { + if (!IsEventAccepted(collision, true)) { return; } - histos.fill(HIST("hEventSelection"), 17 /* Above max occupancy */); float centrality = collision.centFT0C(); if (qaCentrality) { auto hRawCentrality = histos.get(HIST("hRawCentrality")); centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C())); } + float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); // gap side int gapSide = collision.gapSide(); @@ -1677,7 +1718,8 @@ struct derivedlambdakzeroanalysis { // Simulated processing (subscribes to MC information too) void processGenerated(soa::Join const& mcCollisions, soa::Join const& V0MCCores, soa::Join const& CascMCCores, soa::Join const& collisions) { - std::vector listBestCollisionIdx = fillGenEventHist(mcCollisions, collisions); + fillGeneratedEventProperties(mcCollisions, collisions); + std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, collisions); for (auto const& v0MC : V0MCCores) { if (!v0MC.has_straMCCollision()) continue; @@ -1685,12 +1727,12 @@ struct derivedlambdakzeroanalysis { if (!v0MC.isPhysicalPrimary()) continue; - float ptmc = RecoDecay::sqrtSumOfSquares(v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC()); + float ptmc = v0MC.ptMC(); float ymc = 1e3; if (v0MC.pdgCode() == 310) - ymc = RecoDecay::y(std::array{v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC(), v0MC.pzPosMC() + v0MC.pzNegMC()}, o2::constants::physics::MassKaonNeutral); + ymc = v0MC.rapidityMC(0); else if (TMath::Abs(v0MC.pdgCode()) == 3122) - ymc = RecoDecay::y(std::array{v0MC.pxPosMC() + v0MC.pxNegMC(), v0MC.pyPosMC() + v0MC.pyNegMC(), v0MC.pzPosMC() + v0MC.pzNegMC()}, o2::constants::physics::MassLambda); + ymc = v0MC.rapidityMC(1); if (TMath::Abs(ymc) > v0Selections.rapidityCut) continue; @@ -1700,6 +1742,14 @@ struct derivedlambdakzeroanalysis { if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); centrality = collision.centFT0C(); + float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); + + if (minOccupancy > 0 && collisionOccupancy < minOccupancy) { + continue; + } + if (maxOccupancy > 0 && collisionOccupancy > maxOccupancy) { + continue; + } } if (v0MC.pdgCode() == 310) { @@ -1723,12 +1773,12 @@ struct derivedlambdakzeroanalysis { if (!cascMC.isPhysicalPrimary()) continue; - float ptmc = RecoDecay::sqrtSumOfSquares(cascMC.pxMC(), cascMC.pyMC()); + float ptmc = cascMC.ptMC(); float ymc = 1e3; if (TMath::Abs(cascMC.pdgCode()) == 3312) - ymc = RecoDecay::y(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()}, o2::constants::physics::MassXiMinus); + ymc = cascMC.rapidityMC(0); else if (TMath::Abs(cascMC.pdgCode()) == 3334) - ymc = RecoDecay::y(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()}, o2::constants::physics::MassOmegaMinus); + ymc = cascMC.rapidityMC(2); if (TMath::Abs(ymc) > v0Selections.rapidityCut) continue; @@ -1738,6 +1788,14 @@ struct derivedlambdakzeroanalysis { if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); centrality = collision.centFT0C(); + float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); + + if (minOccupancy > 0 && collisionOccupancy < minOccupancy) { + continue; + } + if (maxOccupancy > 0 && collisionOccupancy > maxOccupancy) { + continue; + } } if (cascMC.pdgCode() == 3312) { @@ -1759,103 +1817,6 @@ struct derivedlambdakzeroanalysis { } } - // ______________________________________________________ - // Simulated processing - // Fill event information (for event loss estimation) and return the index to the recoed collision associated to a given MC collision. - std::vector fillGenEventHist(soa::Join const& mcCollisions, soa::Join const& collisions) - { - std::vector listBestCollisionIdx(mcCollisions.size()); - for (auto const& mcCollision : mcCollisions) { - histos.fill(HIST("hGenEvents"), mcCollision.multMCNParticlesEta05(), 0 /* all gen. events*/); - - auto groupedCollisions = collisions.sliceBy(perMcCollision, mcCollision.globalIndex()); - // Check if there is at least one of the reconstructed collisions associated to this MC collision - // If so, we consider it - bool atLeastOne = false; - int biggestNContribs = -1; - int bestCollisionIndex = -1; - float centrality = 100.5f; - int nCollisions = 0; - for (auto const& collision : groupedCollisions) { - if (requireSel8 && !collision.sel8()) { - continue; - } - if (std::abs(collision.posZ()) > 10.f) { - continue; - } - if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - continue; - } - if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { - continue; - } - if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { - continue; - } - if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { - continue; - } - if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { - continue; - } - if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { - continue; - } - if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { - continue; - } - if (requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - continue; - } - if (requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { - continue; - } - if (requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { - continue; - } - if (requireNoCollInTimeRangeVzDep && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeVzDependent)) { - continue; - } - if (requireNoCollInROFStd && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { - continue; - } - if (requireNoCollInROFStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { - continue; - } - - float collisionOccupancy = useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); - if (minOccupancy > 0 && collisionOccupancy < minOccupancy) { - continue; - } - if (maxOccupancy > 0 && collisionOccupancy > maxOccupancy) { - continue; - } - - if (biggestNContribs < collision.multPVTotalContributors()) { - biggestNContribs = collision.multPVTotalContributors(); - bestCollisionIndex = collision.globalIndex(); - centrality = collision.centFT0C(); - } - nCollisions++; - - atLeastOne = true; - } - listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; - - histos.fill(HIST("hCentralityVsNcoll_beforeEvSel"), centrality, groupedCollisions.size()); - histos.fill(HIST("hCentralityVsNcoll_afterEvSel"), centrality, nCollisions); - - histos.fill(HIST("hCentralityVsMultMC"), centrality, mcCollision.multMCNParticlesEta05()); - - if (atLeastOne) { - histos.fill(HIST("hGenEvents"), mcCollision.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); - - histos.fill(HIST("hGenEventCentrality"), centrality); - } - } - return listBestCollisionIdx; - } - // ______________________________________________________ // Simulated processing (subscribes to MC information too) void processBinnedGenerated( diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index 9e7e4da9953..01d843fa74e 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -20,6 +20,8 @@ /// \author David Dobrigkeit Chinellato (david.dobrigkeit.chinellato@cern.ch) /// \author Zhongbao Yin (Zhong-Bao.Yin@cern.ch) +#include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Common/DataModel/TrackSelectionTables.h" @@ -33,8 +35,6 @@ #include "Common/DataModel/Centrality.h" #include "Framework/StaticFor.h" #include "CCDB/BasicCCDBManager.h" -#include -#include using namespace o2; using namespace o2::constants::math; @@ -1451,9 +1451,16 @@ struct correlateStrangeness { continue; } if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) { + Int_t charge = 0; + if (mcParticle.pdgCode() < 0) + charge = -1; + if (mcParticle.pdgCode() > 0) + charge = 1; if (!doTriggPhysicalPrimary || mcParticle.isPhysicalPrimary()) { - triggerIndices.emplace_back(iteratorNum); - histos.fill(HIST("ClosureTest/hTrigger"), gpt, geta, bestCollisionFT0Mpercentile); + if ((triggerParticleCharge > 0 && charge > 0) || (triggerParticleCharge < 0 && charge < 0) || triggerParticleCharge == 0) { + triggerIndices.emplace_back(iteratorNum); + histos.fill(HIST("ClosureTest/hTrigger"), gpt, geta, bestCollisionFT0Mpercentile); + } } } if (!doAssocPhysicalPrimary || mcParticle.isPhysicalPrimary()) { diff --git a/PWGLF/Tasks/Strangeness/lambdapolarization.cxx b/PWGLF/Tasks/Strangeness/lambdapolarization.cxx index 6fc88bf79dd..b2fe709e01e 100644 --- a/PWGLF/Tasks/Strangeness/lambdapolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdapolarization.cxx @@ -325,7 +325,7 @@ struct lambdapolarization { return false; if (candidate.v0cosPA() < cfgv0CosPA) return false; - if (candidate.dcaV0daughters() > cfgDCAV0Dau) + if (std::abs(candidate.dcaV0daughters()) > cfgDCAV0Dau) return false; if (candidate.pt() < cfgV0PtMin) return false; diff --git a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx index 1081f0b872a..313a6747148 100644 --- a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx +++ b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx @@ -106,6 +106,7 @@ struct lambdapolsp { Configurable ConfV0CPAMin{"ConfV0CPAMin", 0.9998f, "Minimum CPA of V0"}; Configurable ConfV0TranRadV0Min{"ConfV0TranRadV0Min", 1.5f, "Minimum transverse radius"}; Configurable ConfV0TranRadV0Max{"ConfV0TranRadV0Max", 100.f, "Maximum transverse radius"}; + Configurable cMaxV0DCA{"cMaxV0DCA", 1.2, "Maximum V0 DCA to PV"}; Configurable cMinV0DCA{"cMinV0DCA", 0.05, "Minimum V0 daughters DCA to PV"}; Configurable cMaxV0LifeTime{"cMaxV0LifeTime", 20, "Maximum V0 life time"}; Configurable cSigmaMassKs0{"cSigmaMassKs0", 0.006, "Sigma cut on KS0 mass"}; @@ -161,6 +162,7 @@ struct lambdapolsp { AxisSpec etaAxis = {etaNbins, lbineta, hbineta, "Eta"}; AxisSpec spAxis = {spNbins, lbinsp, hbinsp, "Sp"}; AxisSpec qxZDCAxis = {QxyNbins, lbinQxy, hbinQxy, "Qx"}; + // AxisSpec psiACAxis = {120, -6.28, 6.28, "psiAC"}; if (checkwithpub) { if (useprofile == 1) { @@ -209,10 +211,14 @@ struct lambdapolsp { } histos.add("hCentrality", "Centrality distribution", kTH1F, {{centAxis}}); - // histos.add("hCentrality0", "Centrality distribution0", kTH1F, {{centAxis}}); - // histos.add("hCentrality1", "Centrality distribution1", kTH1F, {{centAxis}}); - // histos.add("hCentrality2", "Centrality distribution2", kTH1F, {{centAxis}}); - // histos.add("hCentrality3", "Centrality distribution3", kTH1F, {{centAxis}}); + // histos.add("hpsiApsiC", "hpsiApsiC", kTHnSparseF, {psiACAxis, psiACAxis}); + // histos.add("hpsiApsiC", "hpsiApsiC", kTH2F, {psiACAxis, psiACAxis}); + // histos.add("hphiminuspsiA", "hphiminuspisA", kTH1F, {{50, 0, 6.28}}, true); + // histos.add("hphiminuspsiC", "hphiminuspisC", kTH1F, {{50, 0, 6.28}}, true); + // histos.add("hCentrality0", "Centrality distribution0", kTH1F, {{centAxis}}); + // histos.add("hCentrality1", "Centrality distribution1", kTH1F, {{centAxis}}); + // histos.add("hCentrality2", "Centrality distribution2", kTH1F, {{centAxis}}); + // histos.add("hCentrality3", "Centrality distribution3", kTH1F, {{centAxis}}); if (!checkwithpub) { // histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{20, -10.0, 10.0}}); @@ -262,7 +268,9 @@ struct lambdapolsp { template bool SelectionV0(Collision const& collision, V0 const& candidate) { - + if (TMath::Abs(candidate.dcav0topv()) > cMaxV0DCA) { + return false; + } const float pT = candidate.pt(); // const std::vector decVtx = {candidate.x(), candidate.y(), candidate.z()}; const float tranRad = candidate.v0radius(); @@ -317,6 +325,9 @@ struct lambdapolsp { if (charge > 0 && sign < 0) { return false; }*/ + if (track.tpcNClsCrossedRows() < 70) { + return false; + } if (TMath::Abs(eta) > ConfDaughEta) { return false; } @@ -326,10 +337,10 @@ struct lambdapolsp { if (tpcNClsF < ConfDaughTPCnclsMin) { return false; } - /* if (track.tpcCrossedRowsOverFindableCls() < 0.8) { return false; - } + } + /* if (TMath::Abs(dcaXY) < ConfDaughDCAMin) { return false; }*/ @@ -358,7 +369,7 @@ struct lambdapolsp { ROOT::Math::PxPyPzMVector Lambda, Proton, Pion, fourVecDauCM; // ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY, eventplaneVec, eventplaneVecNorm, beamvector; ROOT::Math::XYZVector threeVecDauCM, threeVecDauCMXY; - float phiangle = 0.0; + double phiangle = 0.0; // double massPi = TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(); // double massPr = TDatabasePDG::Instance()->GetParticle(kProton)->Mass(); // double massLambda = TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(); @@ -385,8 +396,8 @@ struct lambdapolsp { } auto centrality = collision.centFT0C(); - // histos.fill(HIST("hCentrality0"), centrality); - if (!collision.triggerevent()) { + histos.fill(HIST("hCentrality0"), centrality); + if (!collision.triggereventsp()) { return; } // histos.fill(HIST("hCentrality1"), centrality); @@ -553,9 +564,14 @@ struct lambdapolsp { // eventplaneVec = ROOT::Math::XYZVector(collision.qFT0C(), collision.qFT0A(), 0); //this needs to be changed // eventplaneVecNorm = eventplaneVec.Cross(beamvector); //z' phiangle = TMath::ATan2(fourVecDauCM.Py(), fourVecDauCM.Px()); + // double phiangledir = fourVecDauCM.Phi(); auto phiminuspsiC = GetPhiInRange(phiangle - psiZDCC); auto phiminuspsiA = GetPhiInRange(phiangle - psiZDCA); + // histos.fill(HIST("hpsiApsiC"), psiZDCA, psiZDCC); + // histos.fill(HIST("hpsiApsiC"), GetPhiInRange(GetPhiInRange(phiangle) - GetPhiInRange(psiZDCA)), phiminuspsiA); + // histos.fill(HIST("hphiminuspsiA"), (phiminuspsiA)); + // histos.fill(HIST("hphiminuspsiC"), (phiminuspsiC)); // auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); auto cosThetaStar = fourVecDauCM.Pz() / fourVecDauCM.P(); // A0 correction auto PolC = TMath::Sin(phiminuspsiC); diff --git a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index 44e3ded502a..d9b15e16d2a 100644 --- a/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -51,6 +51,7 @@ struct NPCascCandidate { bool isGoodMatch; bool isGoodCascade; int pdgCodeMom; + int pdgCodeITStrack; bool isFromBeauty; bool isFromCharm; float pvX; @@ -597,8 +598,9 @@ struct NonPromptCascadeTask { fromHF = isFromHF(track.mcParticle()); pdgCodeMom = track.mcParticle().has_mothers() ? track.mcParticle().mothers_as()[0].pdgCode() : 0; } + int itsTrackPDG = ITStrack.has_mcParticle() ? ITStrack.mcParticle().pdgCode() : 0; - candidates.emplace_back(NPCascCandidate{track.globalIndex(), ITStrack.globalIndex(), trackedCascade.collisionId(), trackedCascade.matchingChi2(), trackedCascade.itsClsSize(), isGoodMatch, isGoodCascade, pdgCodeMom, std::get<0>(fromHF), std::get<1>(fromHF), + candidates.emplace_back(NPCascCandidate{track.globalIndex(), ITStrack.globalIndex(), trackedCascade.collisionId(), trackedCascade.matchingChi2(), trackedCascade.itsClsSize(), isGoodMatch, isGoodCascade, pdgCodeMom, itsTrackPDG, std::get<0>(fromHF), std::get<1>(fromHF), primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), track.pt(), track.eta(), track.phi(), protonTrack.pt(), protonTrack.eta(), pionTrack.pt(), pionTrack.eta(), bachelor.pt(), bachelor.eta(), @@ -627,7 +629,7 @@ struct NonPromptCascadeTask { auto mcCollision = particle.mcCollision_as(); auto label = collisions.iteratorAt(c.collisionID); - NPCTableMC(c.matchingChi2, c.itsClusSize, c.isGoodMatch, c.isGoodCascade, c.pdgCodeMom, c.isFromBeauty, c.isFromCharm, + NPCTableMC(c.matchingChi2, c.itsClusSize, c.isGoodMatch, c.isGoodCascade, c.pdgCodeMom, c.pdgCodeITStrack, c.isFromBeauty, c.isFromCharm, c.pvX, c.pvY, c.pvZ, c.cascPt, c.cascEta, c.cascPhi, c.protonPt, c.protonEta, c.pionPt, c.pionEta, c.bachPt, c.bachEta, @@ -847,7 +849,7 @@ struct NonPromptCascadeTask { daughtersDCA dDCA; fillDauDCA(trackedCascade, bachelor, protonTrack, pionTrack, primaryVertex, isOmega, dDCA); - candidates.emplace_back(NPCascCandidate{track.globalIndex(), ITStrack.globalIndex(), trackedCascade.collisionId(), trackedCascade.matchingChi2(), trackedCascade.itsClsSize(), 0, 0, 0, 0, 0, + candidates.emplace_back(NPCascCandidate{track.globalIndex(), ITStrack.globalIndex(), trackedCascade.collisionId(), trackedCascade.matchingChi2(), trackedCascade.itsClsSize(), 0, 0, 0, 0, 0, 0, primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), track.pt(), track.eta(), track.phi(), protonTrack.pt(), protonTrack.eta(), pionTrack.pt(), pionTrack.eta(), bachelor.pt(), bachelor.eta(), diff --git a/PWGLF/Tasks/Strangeness/phik0sanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0sanalysis.cxx index 34ad920e561..e9c37b8dc4b 100644 --- a/PWGLF/Tasks/Strangeness/phik0sanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0sanalysis.cxx @@ -24,9 +24,9 @@ #include #include #include +#include #include #include -#include #include #include "Framework/runDataProcessing.h" @@ -54,50 +54,17 @@ using namespace o2::framework::expressions; namespace { -static constexpr int nMultBin = 10; -static constexpr int nPtBinK0S = 4; -static constexpr int nPtBinPi = 3; - -constexpr float flowmPhiInc[nMultBin] = {1.01074f, 1.01073f, 1.01072f, 1.01074f, 1.01075f, 1.01074f, 1.01075f, 1.01074f, 1.01073f, 1.01074f}; -constexpr float fupmPhiInc[nMultBin] = {1.02778f, 1.02777f, 1.02776f, 1.02778f, 1.02779f, 1.02778f, 1.02779f, 1.02778f, 1.02777f, 1.02778f}; - -constexpr float flowmPhiFCut[nMultBin] = {1.01072f, 1.01073f, 1.01072f, 1.01074f, 1.01075f, 1.01076f, 1.01076f, 1.01076f, 1.01075f, 1.01073f}; -constexpr float fupmPhiFCut[nMultBin] = {1.02776f, 1.02777f, 1.02776f, 1.02778f, 1.02779f, 1.02778f, 1.02778f, 1.02778f, 1.02779f, 1.02777f}; - -constexpr float flowmPhiSCut[nMultBin] = {1.01072f, 1.01074f, 1.01070f, 1.01076f, 1.01075f, 1.01077f, 1.01075f, 1.01075f, 1.01076f, 1.01077f}; -constexpr float fupmPhiSCut[nMultBin] = {1.02776f, 1.02778f, 1.02774f, 1.02780f, 1.02779f, 1.02781f, 1.02779f, 1.02779f, 1.02780f, 1.02774f}; - -static constexpr float multBin[nMultBin + 1] = {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}; -static constexpr float pTBinK0S[nPtBinK0S + 1] = {0.0, 0.5, 0.8, 1.2, 10.0}; -static constexpr float pTBinPi[nPtBinPi + 1] = {0.0, 0.5, 1.2, 10.0}; - -static constexpr std::string_view PhiK0SSEInc[nMultBin] = {"h2PhiK0SSEInc_0_1", "h2PhiK0SSEInc_1_5", "h2PhiK0SSEInc_5_10", "h2PhiK0SSEInc_10_15", "h2PhiK0SSEInc_15_20", - "h2PhiK0SSEInc_20_30", "h2PhiK0SSEInc_30_40", "h2PhiK0SSEInc_40_50", "h2PhiK0SSEInc_50_70", "h2PhiK0SSEInc_70_100"}; -static constexpr std::string_view PhiK0SSEFCut[nMultBin] = {"h2PhiK0SSEFCut_0_1", "h2PhiK0SSEFCut_1_5", "h2PhiK0SSEFCut_5_10", "h2PhiK0SSEFCut_10_15", "h2PhiK0SSEFCut_15_20", - "h2PhiK0SSEFCut_20_30", "h2PhiK0SSEFCut_30_40", "h2PhiK0SSEFCut_40_50", "h2PhiK0SSEFCut_50_70", "h2PhiK0SSEFCut_70_100"}; -static constexpr std::string_view PhiK0SSESCut[nMultBin] = {"h2PhiK0SSESCut_0_1", "h2PhiK0SSESCut_1_5", "h2PhiK0SSESCut_5_10", "h2PhiK0SSESCut_10_15", "h2PhiK0SSESCut_15_20", - "h2PhiK0SSESCut_20_30", "h2PhiK0SSESCut_30_40", "h2PhiK0SSESCut_40_50", "h2PhiK0SSESCut_50_70", "h2PhiK0SSESCut_70_100"}; - -static constexpr std::string_view PhiPiSEInc[nMultBin] = {"h2PhiPiSEInc_0_1", "h2PhiPiSEInc_1_5", "h2PhiPiSEInc_5_10", "h2PhiPiSEInc_10_15", "h2PhiPiSEInc_15_20", - "h2PhiPiSEInc_20_30", "h2PhiPiSEInc_30_40", "h2PhiPiSEInc_40_50", "h2PhiPiSEInc_50_70", "h2PhiPiSEInc_70_100"}; -static constexpr std::string_view PhiPiSEFCut[nMultBin] = {"h2PhiPiSEFCut_0_1", "h2PhiPiSEFCut_1_5", "h2PhiPiSEFCut_5_10", "h2PhiPiSEFCut_10_15", "h2PhiPiSEFCut_15_20", - "h2PhiPiSEFCut_20_30", "h2PhiPiSEFCut_30_40", "h2PhiPiSEFCut_40_50", "h2PhiPiSEFCut_50_70", "h2PhiPiSEFCut_70_100"}; -static constexpr std::string_view PhiPiSESCut[nMultBin] = {"h2PhiPiSESCut_0_1", "h2PhiPiSESCut_1_5", "h2PhiPiSESCut_5_10", "h2PhiPiSESCut_10_15", "h2PhiPiSESCut_15_20", - "h2PhiPiSESCut_20_30", "h2PhiPiSESCut_30_40", "h2PhiPiSESCut_40_50", "h2PhiPiSESCut_50_70", "h2PhiPiSESCut_70_100"}; - -static constexpr std::string_view MCPhiK0SSEInc[nMultBin] = {"h2RecMCPhiK0SSEInc_0_1", "h2RecMCPhiK0SSEInc_1_5", "h2RecMCPhiK0SSEInc_5_10", "h2RecMCPhiK0SSEInc_10_15", "h2RecMCPhiK0SSEInc_15_20", - "h2RecMCPhiK0SSEInc_20_30", "h2RecMCPhiK0SSEInc_30_40", "h2RecMCPhiK0SSEInc_40_50", "h2RecMCPhiK0SSEInc_50_70", "h2RecMCPhiK0SSEInc_70_100"}; -static constexpr std::string_view MCPhiK0SSEFCut[nMultBin] = {"h2RecMCPhiK0SSEFCut_0_1", "h2RecMCPhiK0SSEFCut_1_5", "h2RecMCPhiK0SSEFCut_5_10", "h2RecMCPhiK0SSEFCut_10_15", "h2RecMCPhiK0SSEFCut_15_20", - "h2RecMCPhiK0SSEFCut_20_30", "h2RecMCPhiK0SSEFCut_30_40", "h2RecMCPhiK0SSEFCut_40_50", "h2RecMCPhiK0SSEFCut_50_70", "h2RecMCPhiK0SSEFCut_70_100"}; -static constexpr std::string_view MCPhiK0SSESCut[nMultBin] = {"h2RecMCPhiK0SSESCut_0_1", "h2RecMCPhiK0SSESCut_1_5", "h2RecMCPhiK0SSESCut_5_10", "h2RecMCPhiK0SSESCut_10_15", "h2RecMCPhiK0SSESCut_15_20", - "h2RecMCPhiK0SSESCut_20_30", "h2RecMCPhiK0SSESCut_30_40", "h2RecMCPhiK0SSESCut_40_50", "h2RecMCPhiK0SSESCut_50_70", "h2RecMCPhiK0SSESCut_70_100"}; - -static constexpr std::string_view MCPhiPiSEInc[nMultBin] = {"h2RecMCPhiPiSEInc_0_1", "h2RecMCPhiPiSEInc_1_5", "h2RecMCPhiPiSEInc_5_10", "h2RecMCPhiPiSEInc_10_15", "h2RecMCPhiPiSEInc_15_20", - "h2RecMCPhiPiSEInc_20_30", "h2RecMCPhiPiSEInc_30_40", "h2RecMCPhiPiSEInc_40_50", "h2RecMCPhiPiSEInc_50_70", "h2RecMCPhiPiSEInc_70_100"}; -static constexpr std::string_view MCPhiPiSEFCut[nMultBin] = {"h2RecMCPhiPiSEFCut_0_1", "h2RecMCPhiPiSEFCut_1_5", "h2RecMCPhiPiSEFCut_5_10", "h2RecMCPhiPiSEFCut_10_15", "h2RecMCPhiPiSEFCut_15_20", - "h2RecMCPhiPiSEFCut_20_30", "h2RecMCPhiPiSEFCut_30_40", "h2RecMCPhiPiSEFCut_40_50", "h2RecMCPhiPiSEFCut_50_70", "h2RecMCPhiPiSEFCut_70_100"}; -static constexpr std::string_view MCPhiPiSESCut[nMultBin] = {"h2RecMCPhiPiSESCut_0_1", "h2RecMCPhiPiSESCut_1_5", "h2RecMCPhiPiSESCut_5_10", "h2RecMCPhiPiSESCut_10_15", "h2RecMCPhiPiSESCut_15_20", - "h2RecMCPhiPiSESCut_20_30", "h2RecMCPhiPiSESCut_30_40", "h2RecMCPhiPiSESCut_40_50", "h2RecMCPhiPiSESCut_50_70", "h2RecMCPhiPiSESCut_70_100"}; +const int nMultBin = 10; +constexpr float multBin[nMultBin + 1] = {0.0f, 1.0f, 5.0f, 10.0f, 15.0f, 20.0f, 30.0f, 40.0f, 50.0f, 70.0f, 100.0f}; +auto vecMultBin = std::vector{multBin, multBin + nMultBin + 1}; + +const int nPtBinK0S = 7; +constexpr float pTBinK0S[nPtBinK0S + 1] = {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 6.0f}; +auto vecPtBinK0S = std::vector{pTBinK0S, pTBinK0S + nPtBinK0S + 1}; + +const int nPtBinPi = 8; +constexpr float pTBinPi[nPtBinPi + 1] = {0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.5f, 2.0f, 3.0f}; +auto vecPtBinPi = std::vector{pTBinPi, pTBinPi + nPtBinPi + 1}; } // namespace struct phik0shortanalysis { @@ -120,9 +87,12 @@ struct phik0shortanalysis { // Configurable for event selection Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + // Configurable on multiplicity bins + Configurable> binsMult{"binsMult", {0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}, "Multiplicity bin limits"}; + // Configurables for V0 selection - Configurable minTPCnClsFound{"minTPCnClsFound", 80.0f, "min number of found TPC clusters"}; - Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 80.0f, "min number of TPC crossed rows"}; + Configurable minTPCnClsFound{"minTPCnClsFound", 70, "min number of found TPC clusters"}; + Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 80, "min number of TPC crossed rows"}; Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; Configurable etaMax{"etaMax", 0.8f, "eta max"}; @@ -137,60 +107,48 @@ struct phik0shortanalysis { Configurable lowmK0S{"lowmK0S", 0.48, "Lower limit on K0Short mass"}; Configurable upmK0S{"upmK0S", 0.52, "Upper limit on K0Short mass"}; - // Configurable on K0S pT - Configurable> binspTK0S{"binspTK0S", std::vector{pTBinK0S, pTBinK0S + nPtBinK0S + 1}, "pT bin limits for K0S"}; + // Configurable on K0S pT bins + Configurable> binspTK0S{"binspTK0S", {0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0}, "pT bin limits for K0S"}; // Configurables on Phi mass - Configurable nBins{"nBins", 15, "N bins in cfgPhimassaxis"}; - Configurable> lowmPhiInc{"lowmPhiInc", std::vector{flowmPhiInc, flowmPhiInc + nMultBin}, "Lower limits on Phi mass Inclusive"}; - Configurable> upmPhiInc{"upmPhiInc", std::vector{fupmPhiInc, fupmPhiInc + nMultBin}, "Upper limits on Phi mass Inclusive"}; - Configurable> lowmPhiFCut{"lowmPhiFCut", std::vector{flowmPhiFCut, flowmPhiFCut + nMultBin}, "Lower limits on Phi mass First Cut"}; - Configurable> upmPhiFCut{"upmPhiFCut", std::vector{fupmPhiFCut, fupmPhiFCut + nMultBin}, "Upper limits on Phi mass First Cut"}; - Configurable> lowmPhiSCut{"lowmPhiSCut", std::vector{flowmPhiSCut, flowmPhiSCut + nMultBin}, "Lower limits on Phi mass Second Cut"}; - Configurable> upmPhiSCut{"upmPhiSCut", std::vector{fupmPhiSCut, fupmPhiSCut + nMultBin}, "Upper limits on Phi mass Second Cut"}; - Configurable lowmPhiMB{"lowmPhiMB", 1.01074f, "Upper limits on Phi mass Minimum Bias"}; - Configurable upmPhiMB{"upmPhiMB", 1.02778f, "Upper limits on Phi mass Minimum Bias"}; + Configurable nBins{"nBins", 14, "N bins in cfgPhimassaxis"}; + Configurable lowmPhi{"lowmPhiMB", 1.0095, "Upper limits on Phi mass for signal extraction"}; + Configurable upmPhi{"upmPhiMB", 1.029, "Upper limits on Phi mass for signal extraction"}; // Configurables for phi selection - Configurable cMinPtcut{"cMinPtcut", 0.15, "Track minimum pt cut"}; Configurable cfgCutCharge{"cfgCutCharge", 0.0, "Cut on charge"}; Configurable cfgPrimaryTrack{"cfgPrimaryTrack", false, "Primary track selection"}; Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; Configurable cfgPVContributor{"cfgPVContributor", true, "PV contributor track selection"}; - Configurable cMaxDCArToPVcut{"cMaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; - Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; + Configurable cMinKaonPtcut{"cMinKaonPtcut", 0.15f, "Track minimum pt cut"}; + Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0f, "Track DCAz cut to PV Maximum"}; + Configurable cMaxDCArToPV1{"cMaxDCArToPV1", 0.004f, "Track DCAr cut to PV config 1"}; + Configurable cMaxDCArToPV2{"cMaxDCArToPV2", 0.013f, "Track DCAr cut to PV config 2"}; + Configurable cMaxDCArToPV3{"cMaxDCArToPV3", 1.0f, "Track DCAr cut to PV config 3"}; Configurable isNoTOF{"isNoTOF", false, "isNoTOF"}; Configurable nsigmaCutTPCKa{"nsigmacutTPC", 3.0, "Value of the TPC Nsigma cut"}; Configurable nsigmaCutCombinedKa{"nsigmaCutCombined", 3.0, "Value of the TOF Nsigma cut"}; // Configurables for pions selection(extra with respect to a few of those defined for V0) - Configurable minITSnCls{"minITSnCls", 4.0f, "min number of ITS clusters"}; + Configurable minITSnCls{"minITSnCls", 4, "min number of ITS clusters"}; Configurable maxChi2ITS{"maxChi2ITS", 36.0f, "max chi2 per cluster ITS"}; Configurable dcaxyMax{"dcaxyMax", 0.1f, "Maximum DCAxy to primary vertex"}; Configurable dcazMax{"dcazMax", 0.1f, "Maximum DCAz to primary vertex"}; Configurable NSigmaTOFPion{"NSigmaTOFPion", 5.0, "NSigmaTOFPion"}; - // Configurable on pion pT - Configurable> binspTPi{"binspTPi", std::vector{pTBinPi, pTBinPi + nPtBinPi + 1}, "pT bin limits for pions"}; + // Configurable on pion pT bins + Configurable> binspTPi{"binspTPi", {0.2, 0.4, 0.6, 0.8, 1.0f, 1.2, 1.5, 2.0, 3.0}, "pT bin limits for pions"}; // Configurables for delta y selection - Configurable nBinsy{"nBinsy", 16, "Number of bins in y and deltay axis"}; - Configurable cfgInclusiveDeltay{"cfgInclusiveDeltay", 0.8, "Inclusive upper bound on Deltay selection"}; - Configurable cfgFirstCutonDeltay{"cgfFirstCutonDeltay", 0.5, "First upper bound on Deltay selection"}; - Configurable cfgSecondCutonDeltay{"cgfSecondCutonDeltay", 0.2, "Second upper bound on Deltay selection"}; - - // Configurable for event mixing - Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, "Number of mixed events per event"}; + Configurable nBinsy{"nBinsy", 10, "Number of bins in y and deltay axis"}; + Configurable cfgyAcceptance{"cfgyAcceptance", 0.5f, "Rapidity acceptance"}; + Configurable cfgFirstCutonDeltay{"cgfFirstCutonDeltay", 0.5f, "First upper bound on Deltay selection"}; + Configurable cfgSecondCutonDeltay{"cgfSecondCutonDeltay", 0.1f, "Second upper bound on Deltay selection"}; // Configurable for RecMC Configurable cfgiskNoITSROFrameBorder{"cfgiskNoITSROFrameBorder", false, "kNoITSROFrameBorder request on RecMC collisions"}; - // Configurable axis - ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; - ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {20, 0, 100}, "multiplicity percentile for bin"}; - ConfigurableAxis axisMultiplicity{"axisMultiplicity", {2000, 0, 10000}, "TPC multiplicity for bin"}; - // Constants double massKa = o2::constants::physics::MassKPlus; double massPi = o2::constants::physics::MassPiPlus; @@ -232,28 +190,21 @@ struct phik0shortanalysis { // Necessary to flag INEL>0 events in GenMC Service pdgDB; - void init(InitContext const&) + void init(InitContext&) { // Axes AxisSpec K0SmassAxis = {200, 0.45f, 0.55f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; AxisSpec PhimassAxis = {200, 0.9f, 1.2f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec sigPhimassAxis = {nBins, lowmPhi, upmPhi, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; AxisSpec vertexZAxis = {100, -15.f, 15.f, "vrtx_{Z} [cm]"}; - AxisSpec yAxis = {nBinsy, -0.8f, 0.8f, "#it{y}"}; - AxisSpec deltayAxis = {nBinsy, 0.0f, 1.6f, "|#it{#Deltay}|"}; + AxisSpec yAxis = {nBinsy, -cfgyAcceptance, cfgyAcceptance, "#it{y}"}; + AxisSpec deltayAxis = {nBinsy, 0.0f, 1.0f, "|#it{#Deltay}|"}; AxisSpec multAxis = {120, 0.0f, 120.0f, "centFT0M"}; - AxisSpec binnedmultAxis{{0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0}, "centFT0M"}; - AxisSpec ptAxis = {100, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec binnedptK0SAxis{{0.0, 0.5, 0.8, 1.2, 10.0}, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec binnedptPiAxis{{0.0, 0.5, 1.2, 10.0}, "#it{p}_{T} (GeV/#it{c})"}; - std::vector cfgPhimassAxisInc; - std::vector cfgPhimassAxisFCut; - std::vector cfgPhimassAxisSCut; - for (int i = 0; i < nMultBin; i++) { - cfgPhimassAxisInc.push_back({nBins, lowmPhiInc->at(i), upmPhiInc->at(i), "#it{M}_{inv} [GeV/#it{c}^{2}]"}); - cfgPhimassAxisFCut.push_back({nBins, lowmPhiFCut->at(i), upmPhiFCut->at(i), "#it{M}_{inv} [GeV/#it{c}^{2}]"}); - cfgPhimassAxisSCut.push_back({nBins, lowmPhiSCut->at(i), upmPhiSCut->at(i), "#it{M}_{inv} [GeV/#it{c}^{2}]"}); - } - AxisSpec cfgPhimassAxisMB = {nBins, lowmPhiMB, upmPhiMB, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec binnedmultAxis{(std::vector)binsMult, "centFT0M"}; + AxisSpec ptK0SAxis = {60, 0.0f, 6.0f, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec binnedptK0SAxis{(std::vector)binspTK0S, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec ptPiAxis = {30, 0.0f, 3.0f, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec binnedptPiAxis{(std::vector)binspTPi, "#it{p}_{T} (GeV/#it{c})"}; // Histograms // Number of events per selection @@ -268,17 +219,6 @@ struct phik0shortanalysis { eventHist.add("hVertexZ", "hVertexZ", kTH1F, {vertexZAxis}); eventHist.add("hMultiplicityPercent", "Multiplicity Percentile", kTH1F, {multAxis}); - // Histo to check phi numbers in data - eventHist.add("thereisnoPhiwK0S", "thereisnoPhiwK0S", kTH1F, {{3, -0.5, 2.5}}); - eventHist.get(HIST("thereisnoPhiwK0S"))->GetXaxis()->SetBinLabel(1, "Inclusive"); - eventHist.get(HIST("thereisnoPhiwK0S"))->GetXaxis()->SetBinLabel(2, "|#Delta y|<0.5"); - eventHist.get(HIST("thereisnoPhiwK0S"))->GetXaxis()->SetBinLabel(3, "|#Delta y|<0.2"); - - eventHist.add("thereisnoPhiwPi", "thereisnoPhiwPi", kTH1F, {{3, -0.5, 2.5}}); - eventHist.get(HIST("thereisnoPhiwPi"))->GetXaxis()->SetBinLabel(1, "Inclusive"); - eventHist.get(HIST("thereisnoPhiwPi"))->GetXaxis()->SetBinLabel(2, "|#Delta y|<0.5"); - eventHist.get(HIST("thereisnoPhiwPi"))->GetXaxis()->SetBinLabel(3, "|#Delta y|<0.2"); - // Number of MC events per selection for Rec and Gen MCeventHist.add("hRecMCEventSelection", "hRecMCEventSelection", kTH1F, {{8, -0.5f, 7.5f}}); MCeventHist.get(HIST("hRecMCEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); @@ -290,22 +230,6 @@ struct phik0shortanalysis { MCeventHist.get(HIST("hRecMCEventSelection"))->GetXaxis()->SetBinLabel(7, "With at least a gen coll"); MCeventHist.get(HIST("hRecMCEventSelection"))->GetXaxis()->SetBinLabel(8, "With at least a #phi"); - // MC Event information for Rec and Gen - MCeventHist.add("hRecMCVertexZ", "hRecMCVertexZ", kTH1F, {vertexZAxis}); - MCeventHist.add("hRecMCMultiplicityPercent", "RecMC Multiplicity Percentile", kTH1F, {multAxis}); - MCeventHist.add("hRecMCGenMultiplicityPercent", "RecMC Gen Multiplicity Percentile", kTH1F, {binnedmultAxis}); - - // Histo to check phi numbers in RecMC - MCeventHist.add("thereisnoPhiwK0SMC", "thereisnoPhiwK0SMC", kTH1F, {{3, -0.5, 2.5}}); - MCeventHist.get(HIST("thereisnoPhiwK0SMC"))->GetXaxis()->SetBinLabel(1, "Inclusive"); - MCeventHist.get(HIST("thereisnoPhiwK0SMC"))->GetXaxis()->SetBinLabel(2, "|#Delta y|<0.5"); - MCeventHist.get(HIST("thereisnoPhiwK0SMC"))->GetXaxis()->SetBinLabel(3, "|#Delta y|<0.2"); - - MCeventHist.add("thereisnoPhiwPiMC", "thereisnoPhiwPiMC", kTH1F, {{3, -0.5, 2.5}}); - MCeventHist.get(HIST("thereisnoPhiwPiMC"))->GetXaxis()->SetBinLabel(1, "Inclusive"); - MCeventHist.get(HIST("thereisnoPhiwPiMC"))->GetXaxis()->SetBinLabel(2, "|#Delta y|<0.5"); - MCeventHist.get(HIST("thereisnoPhiwPiMC"))->GetXaxis()->SetBinLabel(3, "|#Delta y|<0.2"); - MCeventHist.add("hGenMCEventSelection", "hGenMCEventSelection", kTH1F, {{5, -0.5f, 4.5f}}); MCeventHist.get(HIST("hGenMCEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); MCeventHist.get(HIST("hGenMCEventSelection"))->GetXaxis()->SetBinLabel(2, "posZ cut"); @@ -313,6 +237,11 @@ struct phik0shortanalysis { MCeventHist.get(HIST("hGenMCEventSelection"))->GetXaxis()->SetBinLabel(4, "With at least a #phi"); MCeventHist.get(HIST("hGenMCEventSelection"))->GetXaxis()->SetBinLabel(5, "With at least a reco coll"); + // MC Event information for Rec and Gen + MCeventHist.add("hRecMCVertexZ", "hRecMCVertexZ", kTH1F, {vertexZAxis}); + MCeventHist.add("hRecMCMultiplicityPercent", "RecMC Multiplicity Percentile", kTH1F, {multAxis}); + MCeventHist.add("hRecMCGenMultiplicityPercent", "RecMC Gen Multiplicity Percentile", kTH1F, {binnedmultAxis}); + MCeventHist.add("hGenMCVertexZ", "hGenMCVertexZ", kTH1F, {vertexZAxis}); MCeventHist.add("hGenMCMultiplicityPercent", "GenMC Multiplicity Percentile", kTH1F, {binnedmultAxis}); @@ -320,113 +249,85 @@ struct phik0shortanalysis { PhicandHist.add("hEta", "Eta distribution", kTH1F, {{200, -1.0f, 1.0f}}); PhicandHist.add("hDcaxy", "Dcaxy distribution", kTH1F, {{200, -1.0f, 1.0f}}); PhicandHist.add("hDcaz", "Dcaz distribution", kTH1F, {{200, -1.0f, 1.0f}}); - PhicandHist.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH2F, {ptAxis, {100, -10.0f, 10.0f}}); - PhicandHist.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH2F, {ptAxis, {100, -10.0f, 10.0f}}); + PhicandHist.add("hNsigmaKaonTPC", "NsigmaKaon TPC distribution", kTH2F, {ptK0SAxis, {100, -10.0f, 10.0f}}); + PhicandHist.add("hNsigmaKaonTOF", "NsigmaKaon TOF distribution", kTH2F, {ptK0SAxis, {100, -10.0f, 10.0f}}); // K0S topological/PID cuts K0SHist.add("hDCAV0Daughters", "hDCAV0Daughters", kTH1F, {{55, 0.0f, 2.2f}}); K0SHist.add("hV0CosPA", "hV0CosPA", kTH1F, {{100, 0.95f, 1.f}}); - K0SHist.add("hNSigmaPosPionFromK0S", "hNSigmaPosPionFromK0Short", kTH2F, {ptAxis, {100, -5.f, 5.f}}); - K0SHist.add("hNSigmaNegPionFromK0S", "hNSigmaNegPionFromK0Short", kTH2F, {ptAxis, {100, -5.f, 5.f}}); + K0SHist.add("hNSigmaPosPionFromK0S", "hNSigmaPosPionFromK0Short", kTH2F, {ptK0SAxis, {100, -5.f, 5.f}}); + K0SHist.add("hNSigmaNegPionFromK0S", "hNSigmaNegPionFromK0Short", kTH2F, {ptK0SAxis, {100, -5.f, 5.f}}); // Phi invariant mass for computing purities and normalisation - PhipurHist.add("h2PhipurInvMass", "Invariant mass of Phi for Purity (no K0S/Pi)", kTH2F, {multAxis, PhimassAxis}); + PhipurHist.add("h2PhipurInvMass", "Invariant mass of Phi for Purity (no K0S/Pi)", kTH2F, {binnedmultAxis, PhimassAxis}); - PhipurHist.add("h3PhipurK0SInvMassInclusive", "Invariant mass of Phi for Purity (K0S) Inclusive", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhipurHist.add("h3PhipurK0SInvMassFirstCut", "Invariant mass of Phi for Purity (K0S) Deltay < FirstCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhipurHist.add("h3PhipurK0SInvMassSecondCut", "Invariant mass of Phi for Purity (K0S) Deltay < SecondCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); + PhipurHist.add("h3PhipurK0SInvMassInclusive", "Invariant mass of Phi for Purity (K0S) Inclusive", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); + PhipurHist.add("h3PhipurK0SInvMassFirstCut", "Invariant mass of Phi for Purity (K0S) Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); + PhipurHist.add("h3PhipurK0SInvMassSecondCut", "Invariant mass of Phi for Purity (K0S) Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); - PhipurHist.add("h3PhipurPiInvMassInclusive", "Invariant mass of Phi for Purity (Pi) Inclusive", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhipurHist.add("h3PhipurPiInvMassFirstCut", "Invariant mass of Phi for Purity (Pi) Deltay < FirstCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhipurHist.add("h3PhipurPiInvMassSecondCut", "Invariant mass of Phi for Purity (Pi) Deltay < SecondCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); + PhipurHist.add("h3PhipurPiInvMassInclusive", "Invariant mass of Phi for Purity (Pi) Inclusive", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); + PhipurHist.add("h3PhipurPiInvMassFirstCut", "Invariant mass of Phi for Purity (Pi) Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); + PhipurHist.add("h3PhipurPiInvMassSecondCut", "Invariant mass of Phi for Purity (Pi) Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); // MCPhi invariant mass for computing purities - MCPhipurHist.add("h2MCPhipurInvMass", "Invariant mass of Phi for Purity (no K0S/Pi)", kTH2F, {multAxis, PhimassAxis}); + MCPhipurHist.add("h2MCPhipurInvMass", "Invariant mass of Phi for Purity (no K0S/Pi)", kTH2F, {binnedmultAxis, PhimassAxis}); - MCPhipurHist.add("h3MCPhipurK0SInvMassInclusive", "Invariant mass of Phi for Purity (K0S) Inclusive", kTH3F, {multAxis, ptAxis, PhimassAxis}); - MCPhipurHist.add("h3MCPhipurK0SInvMassFirstCut", "Invariant mass of Phi for Purity (K0S) Deltay < FirstCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); - MCPhipurHist.add("h3MCPhipurK0SInvMassSecondCut", "Invariant mass of Phi for Purity (K0S) Deltay < SecondCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); + MCPhipurHist.add("h3MCPhipurK0SInvMassInclusive", "Invariant mass of Phi for Purity (K0S) Inclusive", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); + MCPhipurHist.add("h3MCPhipurK0SInvMassFirstCut", "Invariant mass of Phi for Purity (K0S) Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); + MCPhipurHist.add("h3MCPhipurK0SInvMassSecondCut", "Invariant mass of Phi for Purity (K0S) Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); - MCPhipurHist.add("h3MCPhipurPiInvMassInclusive", "Invariant mass of Phi for Purity (Pi) Inclusive", kTH3F, {multAxis, ptAxis, PhimassAxis}); - MCPhipurHist.add("h3MCPhipurPiInvMassFirstCut", "Invariant mass of Phi for Purity (Pi) Deltay < FirstCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); - MCPhipurHist.add("h3MCPhipurPiInvMassSecondCut", "Invariant mass of Phi for Purity (Pi) Deltay < SecondCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); + MCPhipurHist.add("h3MCPhipurPiInvMassInclusive", "Invariant mass of Phi for Purity (Pi) Inclusive", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); + MCPhipurHist.add("h3MCPhipurPiInvMassFirstCut", "Invariant mass of Phi for Purity (Pi) Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); + MCPhipurHist.add("h3MCPhipurPiInvMassSecondCut", "Invariant mass of Phi for Purity (Pi) Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); - // 2D mass for Phi and K0S for Same Event and Mixed Event - for (int i = 0; i < nMultBin; i++) { - PhiK0SHist.add(PhiK0SSEInc[i].data(), "2D Invariant mass of Phi and K0Short for Same Event Inclusive", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisInc.at(i)}); - PhiK0SHist.add(PhiK0SSEFCut[i].data(), "2D Invariant mass of Phi and K0Short for Same Event Deltay < FirstCut", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisFCut.at(i)}); - PhiK0SHist.add(PhiK0SSESCut[i].data(), "2D Invariant mass of Phi and K0Short for Same Event Deltay < SecondCut", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisSCut.at(i)}); - } - PhiK0SHist.add("h2PhiK0SSEInc_0_100", "2D Invariant mass of Phi and K0Short for Same Event Inclusive MB", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisMB}); - PhiK0SHist.add("h2PhiK0SSEFCut_0_100", "2D Invariant mass of Phi and K0Short for Same Event Deltay < FirstCut MB", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisMB}); - PhiK0SHist.add("h2PhiK0SSESCut_0_100", "2D Invariant mass of Phi and K0Short for Same Event Deltay < SecondCut MB", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisMB}); - - PhiK0SHist.add("h4PhiK0SInvMassMixedEventInclusive", "2D Invariant mass of Phi and K0Short for Mixed Event Inclusive", kTHnSparseF, {multAxis, binnedptK0SAxis, K0SmassAxis, PhimassAxis}); - PhiK0SHist.add("h4PhiK0SInvMassMixedEventFirstCut", "2D Invariant mass of Phi and K0Short for Mixed Event Deltay < FirstCut", kTHnSparseF, {multAxis, binnedptK0SAxis, K0SmassAxis, PhimassAxis}); - PhiK0SHist.add("h4PhiK0SInvMassMixedEventSecondCut", "2D Invariant mass of Phi and K0Short for Mixed Event Deltay < SecondCut", kTHnSparseF, {multAxis, binnedptK0SAxis, K0SmassAxis, PhimassAxis}); + // 2D mass for Phi and K0S for Data + PhiK0SHist.add("h4PhiK0SSEInc", "2D Invariant mass of Phi and K0Short for Same Event Inclusive", kTHnSparseF, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis, sigPhimassAxis}); + PhiK0SHist.add("h4PhiK0SSEFCut", "2D Invariant mass of Phi and K0Short for Same Event Deltay < FirstCut", kTHnSparseF, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis, sigPhimassAxis}); + PhiK0SHist.add("h4PhiK0SSESCut", "2D Invariant mass of Phi and K0Short for Same Event Deltay < SecondCut", kTHnSparseF, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis, sigPhimassAxis}); // MC 2D mass for Phi and K0S - for (int i = 0; i < nMultBin; i++) { - MCPhiK0SHist.add(MCPhiK0SSEInc[i].data(), "2D Invariant mass of Phi and K0Short for RecMC Inclusive", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisInc.at(i)}); - MCPhiK0SHist.add(MCPhiK0SSEFCut[i].data(), "2D Invariant mass of Phi and K0Short for RecMC Deltay < FirstCut", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisFCut.at(i)}); - MCPhiK0SHist.add(MCPhiK0SSESCut[i].data(), "2D Invariant mass of Phi and K0Short for RecMC Deltay < SecondCut", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisSCut.at(i)}); - } - MCPhiK0SHist.add("h2RecMCPhiK0SSEInc_0_100", "2D Invariant mass of Phi and K0Short for RecMC Inclusive MB", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisMB}); - MCPhiK0SHist.add("h2RecMCPhiK0SSEFCut_0_100", "2D Invariant mass of Phi and K0Short for RecMC Deltay < FirstCut MB", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisMB}); - MCPhiK0SHist.add("h2RecMCPhiK0SSESCut_0_100", "2D Invariant mass of Phi and K0Short for RecMC Deltay < SecondCut MB", kTH3F, {binnedptK0SAxis, K0SmassAxis, cfgPhimassAxisMB}); + MCPhiK0SHist.add("h3RecMCPhiK0SSEInc", "2D Invariant mass of Phi and K0Short for RecMC Inclusive", kTH3F, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis}); + MCPhiK0SHist.add("h3RecMCPhiK0SSEFCut", "2D Invariant mass of Phi and K0Short for RecMC Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis}); + MCPhiK0SHist.add("h3RecMCPhiK0SSESCut", "2D Invariant mass of Phi and K0Short for RecMC Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis}); // GenMC K0S coupled to Phi - MCPhiK0SHist.add("h2PhiK0SGenMCInclusive", "K0Short coupled to Phi for GenMC Inclusive", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); - MCPhiK0SHist.add("h2PhiK0SGenMCFirstCut", "K0Short coupled to Phi for GenMC Deltay < FirstCut", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); - MCPhiK0SHist.add("h2PhiK0SGenMCSecondCut", "K0Short coupled to Phi for GenMC Deltay < SecondCut", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); + MCPhiK0SHist.add("h2PhiK0SGenMCInclusive", "K0Short coupled to Phi for GenMC Inclusive", kTH2F, {binnedmultAxis, binnedptK0SAxis}); + MCPhiK0SHist.add("h2PhiK0SGenMCFirstCut", "K0Short coupled to Phi for GenMC Deltay < FirstCut", kTH2F, {binnedmultAxis, binnedptK0SAxis}); + MCPhiK0SHist.add("h2PhiK0SGenMCSecondCut", "K0Short coupled to Phi for GenMC Deltay < SecondCut", kTH2F, {binnedmultAxis, binnedptK0SAxis}); - MCPhiK0SHist.add("h2PhiK0SGenMCInclusiveAssocReco", "K0Short coupled to Phi for GenMC Inclusive Associated Reco Collision", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); - MCPhiK0SHist.add("h2PhiK0SGenMCFirstCutAssocReco", "K0Short coupled to Phi for GenMC Deltay < FirstCut Associated Reco Collision", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); - MCPhiK0SHist.add("h2PhiK0SGenMCSecondCutAssocReco", "K0Short coupled to Phi for GenMC Deltay < SecondCut Associated Reco Collision", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); + MCPhiK0SHist.add("h2PhiK0SGenMCInclusiveAssocReco", "K0Short coupled to Phi for GenMC Inclusive Associated Reco Collision", kTH2F, {binnedmultAxis, binnedptK0SAxis}); + MCPhiK0SHist.add("h2PhiK0SGenMCFirstCutAssocReco", "K0Short coupled to Phi for GenMC Deltay < FirstCut Associated Reco Collision", kTH2F, {binnedmultAxis, binnedptK0SAxis}); + MCPhiK0SHist.add("h2PhiK0SGenMCSecondCutAssocReco", "K0Short coupled to Phi for GenMC Deltay < SecondCut Associated Reco Collision", kTH2F, {binnedmultAxis, binnedptK0SAxis}); - // Phi mass vs Pion NSigma dE/dx for Same Event and Mixed Event - for (int i = 0; i < nMultBin; i++) { - PhiPionHist.add(PhiPiSEInc[i].data(), "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Inclusive", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisInc.at(i)}); - PhiPionHist.add(PhiPiSEFCut[i].data(), "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Deltay < FirstCut", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisFCut.at(i)}); - PhiPionHist.add(PhiPiSESCut[i].data(), "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Deltay < SecondCut", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisSCut.at(i)}); - } - PhiPionHist.add("h2PhiPiSEInc_0_100", "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Inclusive MB", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisMB}); - PhiPionHist.add("h2PhiPiSEFCut_0_100", "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Deltay < FirstCut MB", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisMB}); - PhiPionHist.add("h2PhiPiSESCut_0_100", "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Deltay < SecondCut MB", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisMB}); - - PhiPionHist.add("h5PhiInvMassPiNSigmadEdxMixedEventInclusive", "Phi Invariant mass vs Pion nSigma TPC/TOF for Mixed Event Inclusive", kTHnSparseF, {multAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, PhimassAxis}); - PhiPionHist.add("h5PhiInvMassPiNSigmadEdxMixedEventFirstCut", "Phi Invariant mass vs Pion nSigma TPC/TOF for Mixed Event Deltay < FirstCut", kTHnSparseF, {multAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, PhimassAxis}); - PhiPionHist.add("h5PhiInvMassPiNSigmadEdxMixedEventSecondCut", "Phi Invariant mass vs Pion nSigma TPC/TOF for Mixed Event Deltay < SecondCut", kTHnSparseF, {multAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, PhimassAxis}); + // Phi mass vs Pion NSigma dE/dx for Data + PhiPionHist.add("h5PhiPiSEInc", "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Inclusive", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, sigPhimassAxis}); + PhiPionHist.add("h5PhiPiSEFCut", "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Deltay < FirstCut", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, sigPhimassAxis}); + PhiPionHist.add("h5PhiPiSESCut", "Phi Invariant mass vs Pion nSigma TPC/TOF for Same Event Deltay < SecondCut", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, sigPhimassAxis}); // MC Phi mass vs Pion NSigma dE/dx - for (int i = 0; i < nMultBin; i++) { - MCPhiPionHist.add(MCPhiPiSEInc[i].data(), "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Inclusive", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisInc.at(i)}); - MCPhiPionHist.add(MCPhiPiSEFCut[i].data(), "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Deltay < FirstCut", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisFCut.at(i)}); - MCPhiPionHist.add(MCPhiPiSESCut[i].data(), "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Deltay < SecondCut", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisSCut.at(i)}); - } - MCPhiPionHist.add("h2RecMCPhiPiSEInc_0_100", "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Inclusive MB", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisMB}); - MCPhiPionHist.add("h2RecMCPhiPiSEFCut_0_100", "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Deltay < FirstCut MB", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisMB}); - MCPhiPionHist.add("h2RecMCPhiPiSESCut_0_100", "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Deltay < SecondCut MB", kTHnSparseF, {binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}, cfgPhimassAxisMB}); + MCPhiPionHist.add("h4RecMCPhiPiSEInc", "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Inclusive", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}}); + MCPhiPionHist.add("h4RecMCPhiPiSEFCut", "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Deltay < FirstCut", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}}); + MCPhiPionHist.add("h4RecMCPhiPiSESCut", "Phi Invariant mass vs Pion nSigma TPC/TOF for RecMC Deltay < SecondCut", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}}); // GenMC Pion coupled to Phi - MCPhiPionHist.add("h2PhiPiGenMCInclusive", "Pion coupled to Phi for GenMC Inclusive", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); - MCPhiPionHist.add("h2PhiPiGenMCFirstCut", "Pion coupled to Phi for GenMC Deltay < FirstCut", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); - MCPhiPionHist.add("h2PhiPiGenMCSecondCut", "Pion coupled to Phi for GenMC Deltay < SecondCut", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); + MCPhiPionHist.add("h2PhiPiGenMCInclusive", "Pion coupled to Phi for GenMC Inclusive", kTH2F, {binnedmultAxis, binnedptPiAxis}); + MCPhiPionHist.add("h2PhiPiGenMCFirstCut", "Pion coupled to Phi for GenMC Deltay < FirstCut", kTH2F, {binnedmultAxis, binnedptPiAxis}); + MCPhiPionHist.add("h2PhiPiGenMCSecondCut", "Pion coupled to Phi for GenMC Deltay < SecondCut", kTH2F, {binnedmultAxis, binnedptPiAxis}); - MCPhiPionHist.add("h2PhiPiGenMCInclusiveAssocReco", "Pion coupled to Phi for GenMC Inclusive Associated Reco Collision", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); - MCPhiPionHist.add("h2PhiPiGenMCFirstCutAssocReco", "Pion coupled to Phi for GenMC Deltay < FirstCut Associated Reco Collision", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); - MCPhiPionHist.add("h2PhiPiGenMCSecondCutAssocReco", "Pion coupled to Phi for GenMC Deltay < SecondCut Associated Reco Collision", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); + MCPhiPionHist.add("h2PhiPiGenMCInclusiveAssocReco", "Pion coupled to Phi for GenMC Inclusive Associated Reco Collision", kTH2F, {binnedmultAxis, binnedptPiAxis}); + MCPhiPionHist.add("h2PhiPiGenMCFirstCutAssocReco", "Pion coupled to Phi for GenMC Deltay < FirstCut Associated Reco Collision", kTH2F, {binnedmultAxis, binnedptPiAxis}); + MCPhiPionHist.add("h2PhiPiGenMCSecondCutAssocReco", "Pion coupled to Phi for GenMC Deltay < SecondCut Associated Reco Collision", kTH2F, {binnedmultAxis, binnedptPiAxis}); // MCPhi invariant mass for computing efficiencies and MCnormalisation - PhieffHist.add("h2PhieffInvMass", "Invariant mass of Phi for Efficiency (no K0S/Pi)", kTH2F, {multAxis, PhimassAxis}); + PhieffHist.add("h2PhieffInvMass", "Invariant mass of Phi for Efficiency (no K0S/Pi)", kTH2F, {binnedmultAxis, PhimassAxis}); - PhieffHist.add("h3PhieffK0SInvMassInclusive", "Invariant mass of Phi for Efficiency (K0S) Inclusive", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhieffHist.add("h3PhieffK0SInvMassFirstCut", "Invariant mass of Phi for Efficiency (K0S) Deltay < FirstCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhieffHist.add("h3PhieffK0SInvMassSecondCut", "Invariant mass of Phi for Efficiency (K0S) Deltay < SecondCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); + PhieffHist.add("h3PhieffK0SInvMassInclusive", "Invariant mass of Phi for Efficiency (K0S) Inclusive", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); + PhieffHist.add("h3PhieffK0SInvMassFirstCut", "Invariant mass of Phi for Efficiency (K0S) Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); + PhieffHist.add("h3PhieffK0SInvMassSecondCut", "Invariant mass of Phi for Efficiency (K0S) Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptK0SAxis, PhimassAxis}); - PhieffHist.add("h3PhieffPiInvMassInclusive", "Invariant mass of Phi for Efficiency (Pi) Inclusive", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhieffHist.add("h3PhieffPiInvMassFirstCut", "Invariant mass of Phi for Efficiency (Pi) Deltay < FirstCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); - PhieffHist.add("h3PhieffPiInvMassSecondCut", "Invariant mass of Phi for Efficiency (Pi) Deltay < SecondCut", kTH3F, {multAxis, ptAxis, PhimassAxis}); + PhieffHist.add("h3PhieffPiInvMassInclusive", "Invariant mass of Phi for Efficiency (Pi) Inclusive", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); + PhieffHist.add("h3PhieffPiInvMassFirstCut", "Invariant mass of Phi for Efficiency (Pi) Deltay < FirstCut", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); + PhieffHist.add("h3PhieffPiInvMassSecondCut", "Invariant mass of Phi for Efficiency (Pi) Deltay < SecondCut", kTH3F, {binnedmultAxis, binnedptPiAxis, PhimassAxis}); // GenMC Phi and Phi coupled to K0S and Pion PhieffHist.add("h1PhiGenMC", "Phi for GenMC", kTH1F, {{10, -0.5f, 9.5f}}); @@ -449,11 +350,11 @@ struct phik0shortanalysis { // MCK0S invariant mass and GenMC K0S for computing efficiencies K0SeffHist.add("h3K0SeffInvMass", "Invariant mass of K0Short for Efficiency", kTH3F, {binnedmultAxis, binnedptK0SAxis, K0SmassAxis}); - K0SeffHist.add("h2K0SGenMC", "K0Short for GenMC", kTH2F, {{10, -0.5f, 9.5f}, {4, -0.5f, 3.5f}}); + K0SeffHist.add("h2K0SGenMC", "K0Short for GenMC", kTH2F, {binnedmultAxis, binnedptK0SAxis}); // MCPion invariant mass and GenMC Pion for computing efficiencies PioneffHist.add("h4PieffInvMass", "Invariant mass of Pion for Efficiency", kTHnSparseF, {binnedmultAxis, binnedptPiAxis, {100, -10.0f, 10.0f}, {100, -10.0f, 10.0f}}); - PioneffHist.add("h2PiGenMC", "Pion for GenMC", kTH2F, {{10, -0.5f, 9.5f}, {3, -0.5f, 2.5f}}); + PioneffHist.add("h2PiGenMC", "Pion for GenMC", kTH2F, {binnedmultAxis, binnedptPiAxis}); // y acceptance studies yaccHist.add("hyaccK0SRecMC", "K0S y acceptance in RecMC", kTH3F, {binnedmultAxis, binnedptK0SAxis, yAxis}); @@ -474,7 +375,7 @@ struct phik0shortanalysis { return false; if (QA) eventHist.fill(HIST("hEventSelection"), 1); // sel8 collisions - if (std::abs(collision.posZ()) > cutzvertex) + if (std::abs(collision.posZ()) >= cutzvertex) return false; if (QA) { eventHist.fill(HIST("hEventSelection"), 2); // vertex-Z selected @@ -496,12 +397,10 @@ struct phik0shortanalysis { return false; if (QA) MCeventHist.fill(HIST("hRecMCEventSelection"), 2); // kNoTimeFrameBorder collisions - if (cfgiskNoITSROFrameBorder) { - if (!collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) - return false; - if (QA) - MCeventHist.fill(HIST("hRecMCEventSelection"), 3); // kNoITSROFrameBorder collisions (by default not requested by the selection) - } + if (cfgiskNoITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + if (QA) + MCeventHist.fill(HIST("hRecMCEventSelection"), 3); // kNoITSROFrameBorder collisions (by default not requested by the selection) if (std::abs(collision.posZ()) > cutzvertex) return false; if (QA) { @@ -554,18 +453,20 @@ struct phik0shortanalysis { template bool selectionTrackResonance(const T& track) { - if (std::abs(track.pt()) < cMinPtcut) + if (cfgPrimaryTrack && !track.isPrimaryTrack()) return false; - if (std::abs(track.dcaXY()) > cMaxDCArToPVcut) + if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) return false; - if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut) + if (cfgPVContributor && !track.isPVContributor()) return false; - if (cfgPrimaryTrack && !track.isPrimaryTrack()) + if (track.pt() < cMinKaonPtcut) return false; - if (cfgGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + if (std::abs(track.dcaZ()) > cMaxDCAzToPVcut) return false; - if (cfgPVContributor && !track.isPVContributor()) + if (std::abs(track.dcaXY()) > cMaxDCArToPV1 + (cMaxDCArToPV2 / std::pow(track.pt(), cMaxDCArToPV3))) + return false; + if (track.tpcNClsFound() < minTPCnClsFound) return false; return true; } @@ -583,6 +484,16 @@ struct phik0shortanalysis { return false; } + template + bool selectionPIDKaonpTdependent(const T& candidate) + { + if (candidate.pt() < 0.5 && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) + return true; + if (candidate.pt() >= 0.5 && candidate.hasTOF() && ((candidate.tofNSigmaKa() * candidate.tofNSigmaKa()) + (candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa())) < (nsigmaCutCombinedKa * nsigmaCutCombinedKa)) + return true; + return false; + } + // Reconstruct the Phi template TLorentzVector recMother(const T1& candidate1, const T2& candidate2, float masscand1, float masscand2) @@ -607,7 +518,10 @@ struct phik0shortanalysis { if (track.itsChi2NCl() > maxChi2ITS) return false; - if (track.pt() < 1.2) { + if (track.pt() < 0.2) + return false; + + if (track.pt() < 0.8) { if (!track.hasTPC()) return false; if (track.tpcNClsFound() < minTPCnClsFound) @@ -618,7 +532,7 @@ struct phik0shortanalysis { return false; } - if (track.pt() > 0.5) { + if (track.pt() >= 0.5) { if (!track.hasTOF()) return false; } @@ -631,8 +545,8 @@ struct phik0shortanalysis { } // Fill 2D invariant mass histogram for V0 and Phi - template - void fillInvMass2D(TLorentzVector V0, const std::vector listPhi, float multiplicity, double weightInclusive, double weightLtFirstCut, double weightLtSecondCut) + template + void fillInvMass2D(TLorentzVector V0, const std::vector listPhi, float multiplicity, const std::array weights) { double massV0 = V0.M(); double ptV0 = V0.Pt(); @@ -643,45 +557,29 @@ struct phik0shortanalysis { double rapidityPhi = listPhi[phitag].Rapidity(); double deltay = std::abs(rapidityV0 - rapidityPhi); - if constexpr (!isMix) { // same event - PhiK0SHist.fill(HIST(PhiK0SSEInc[iBin]), ptV0, massV0, massPhi, weightInclusive); - PhiK0SHist.fill(HIST("h2PhiK0SSEInc_0_100"), ptV0, massV0, massPhi, weightInclusive); + if constexpr (!isMC) { // same event + PhiK0SHist.fill(HIST("h4PhiK0SSEInc"), multiplicity, ptV0, massV0, massPhi, weights.at(0)); if (deltay > cfgFirstCutonDeltay) continue; - PhiK0SHist.fill(HIST(PhiK0SSEFCut[iBin]), ptV0, massV0, massPhi, weightLtFirstCut); - PhiK0SHist.fill(HIST("h2PhiK0SSEFCut_0_100"), ptV0, massV0, massPhi, weightLtFirstCut); + PhiK0SHist.fill(HIST("h4PhiK0SSEFCut"), multiplicity, ptV0, massV0, massPhi, weights.at(1)); if (deltay > cfgSecondCutonDeltay) continue; - PhiK0SHist.fill(HIST(PhiK0SSESCut[iBin]), ptV0, massV0, massPhi, weightLtSecondCut); - PhiK0SHist.fill(HIST("h2PhiK0SSESCut_0_100"), ptV0, massV0, massPhi, weightLtSecondCut); - } else { // mixed event - PhiK0SHist.fill(HIST("h4PhiK0SInvMassMixedEventInclusive"), multiplicity, ptV0, massV0, massPhi, weightInclusive); + PhiK0SHist.fill(HIST("h4PhiK0SSESCut"), multiplicity, ptV0, massV0, massPhi, weights.at(2)); + } else { // MC event + MCPhiK0SHist.fill(HIST("h3RecMCPhiK0SSEInc"), multiplicity, ptV0, massV0, weights.at(0)); if (deltay > cfgFirstCutonDeltay) continue; - PhiK0SHist.fill(HIST("h4PhiK0SInvMassMixedEventFirstCut"), multiplicity, ptV0, massV0, massPhi, weightLtFirstCut); + MCPhiK0SHist.fill(HIST("h3RecMCPhiK0SSEFCut"), multiplicity, ptV0, massV0, weights.at(1)); if (deltay > cfgSecondCutonDeltay) continue; - PhiK0SHist.fill(HIST("h4PhiK0SInvMassMixedEventSecondCut"), multiplicity, ptV0, massV0, massPhi, weightLtSecondCut); - } - - if constexpr (isMC) { // MC event - MCPhiK0SHist.fill(HIST(MCPhiK0SSEInc[iBin]), ptV0, massV0, massPhi, weightInclusive); - MCPhiK0SHist.fill(HIST("h2RecMCPhiK0SSEInc_0_100"), ptV0, massV0, massPhi, weightInclusive); - if (deltay > cfgFirstCutonDeltay) - continue; - MCPhiK0SHist.fill(HIST(MCPhiK0SSEFCut[iBin]), ptV0, massV0, massPhi, weightLtFirstCut); - MCPhiK0SHist.fill(HIST("h2RecMCPhiK0SSEFCut_0_100"), ptV0, massV0, massPhi, weightLtFirstCut); - if (deltay > cfgSecondCutonDeltay) - continue; - MCPhiK0SHist.fill(HIST(MCPhiK0SSESCut[iBin]), ptV0, massV0, massPhi, weightLtSecondCut); - MCPhiK0SHist.fill(HIST("h2RecMCPhiK0SSESCut_0_100"), ptV0, massV0, massPhi, weightLtSecondCut); + MCPhiK0SHist.fill(HIST("h3RecMCPhiK0SSESCut"), multiplicity, ptV0, massV0, weights.at(2)); } } } // Fill Phi invariant mass vs Pion nSigmadE/dx histogram - template - void fillInvMassNSigma(TLorentzVector Pi, float nSigmaTPCPi, float nSigmaTOFPi, const std::vector listPhi, float multiplicity, double weightInclusive, double weightLtFirstCut, double weightLtSecondCut) + template + void fillInvMassNSigma(TLorentzVector Pi, float nSigmaTPCPi, float nSigmaTOFPi, const std::vector listPhi, float multiplicity, const std::array weights) { double rapidityPi = Pi.Rapidity(); double ptPi = Pi.Pt(); @@ -691,38 +589,22 @@ struct phik0shortanalysis { double rapidityPhi = listPhi[phitag].Rapidity(); double deltay = std::abs(rapidityPi - rapidityPhi); - if constexpr (!isMix) { // same event - PhiPionHist.fill(HIST(PhiPiSEInc[iBin]), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightInclusive); - PhiPionHist.fill(HIST("h2PhiPiSEInc_0_100"), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightInclusive); + if constexpr (!isMC) { // same event + PhiPionHist.fill(HIST("h5PhiPiSEInc"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weights.at(0)); if (deltay > cfgFirstCutonDeltay) continue; - PhiPionHist.fill(HIST(PhiPiSEFCut[iBin]), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtFirstCut); - PhiPionHist.fill(HIST("h2PhiPiSEFCut_0_100"), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtFirstCut); + PhiPionHist.fill(HIST("h5PhiPiSEFCut"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weights.at(1)); if (deltay > cfgSecondCutonDeltay) continue; - PhiPionHist.fill(HIST(PhiPiSESCut[iBin]), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtSecondCut); - PhiPionHist.fill(HIST("h2PhiPiSESCut_0_100"), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtSecondCut); - } else { // mixed event - PhiPionHist.fill(HIST("h5PhiInvMassPiNSigmadEdxMixedEventInclusive"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightInclusive); - if (deltay > cfgFirstCutonDeltay) - continue; - PhiPionHist.fill(HIST("h5PhiInvMassPiNSigmadEdxMixedEventFirstCut"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtFirstCut); - if (deltay > cfgSecondCutonDeltay) - continue; - PhiPionHist.fill(HIST("h5PhiInvMassPiNSigmadEdxMixedEventSecondCut"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtSecondCut); - } - - if constexpr (isMC) { // MC event - MCPhiPionHist.fill(HIST(MCPhiPiSEInc[iBin]), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightInclusive); - MCPhiPionHist.fill(HIST("h2RecMCPhiPiSEInc_0_100"), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightInclusive); + PhiPionHist.fill(HIST("h5PhiPiSESCut"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weights.at(2)); + } else { // MC event + MCPhiPionHist.fill(HIST("h4RecMCPhiPiSEInc"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, weights.at(0)); if (deltay > cfgFirstCutonDeltay) continue; - MCPhiPionHist.fill(HIST(MCPhiPiSEFCut[iBin]), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtFirstCut); - MCPhiPionHist.fill(HIST("h2RecMCPhiPiSEFCut_0_100"), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtFirstCut); + MCPhiPionHist.fill(HIST("h4RecMCPhiPiSEFCut"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, weights.at(1)); if (deltay > cfgSecondCutonDeltay) continue; - MCPhiPionHist.fill(HIST(MCPhiPiSESCut[iBin]), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtSecondCut); - MCPhiPionHist.fill(HIST("h2RecMCPhiPiSESCut_0_100"), ptPi, nSigmaTPCPi, nSigmaTOFPi, massPhi, weightLtSecondCut); + MCPhiPionHist.fill(HIST("h4RecMCPhiPiSESCut"), multiplicity, ptPi, nSigmaTPCPi, nSigmaTOFPi, weights.at(2)); } } } @@ -744,7 +626,7 @@ struct phik0shortanalysis { bool isFilledhV0 = false; for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection PhicandHist.fill(HIST("hEta"), track1.eta()); @@ -757,7 +639,7 @@ struct phik0shortanalysis { // Loop over all negative candidates for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -766,7 +648,7 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; if (!isCountedPhi) { @@ -801,7 +683,7 @@ struct phik0shortanalysis { TLorentzVector recK0S; recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recK0S.Rapidity()) > cfgyAcceptance) continue; int ipTBinK0S = 0; @@ -842,7 +724,7 @@ struct phik0shortanalysis { TLorentzVector recPi; recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPi.Rapidity()) > cfgyAcceptance) continue; int ipTBinPi = 0; @@ -884,14 +766,6 @@ struct phik0shortanalysis { float multiplicity = collision.centFT0M(); eventHist.fill(HIST("hMultiplicityPercent"), multiplicity); - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < multiplicity && multiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - // Defining positive and negative tracks for phi reconstruction auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -907,23 +781,23 @@ struct phik0shortanalysis { TLorentzVector recK0S; recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recK0S.Rapidity()) > cfgyAcceptance) continue; std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; + std::array counts{}; // Phi reconstruction // Loop over positive candidates for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); // Loop over all negative candidates for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -932,88 +806,29 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; listrecPhi.push_back(recPhi); - if (lowmPhiInc->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiInc->at(iBin)) - countInclusive++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - if (lowmPhiFCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiFCut->at(iBin)) - countLtFirstCut++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - if (lowmPhiSCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiSCut->at(iBin)) - countLtSecondCut++; + if (lowmPhi <= recPhi.M() && recPhi.M() <= upmPhi) { + counts.at(0)++; + if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) + continue; + counts.at(1)++; + if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) + continue; + counts.at(2)++; + } } } - float weightInclusive, weightLtFirstCut, weightLtSecondCut; - if (countInclusive > 0) { - weightInclusive = 1. / static_cast(countInclusive); - } else { - weightInclusive = 0; - eventHist.fill(HIST("thereisnoPhiwK0S"), 0); - } - if (countLtFirstCut > 0) { - weightLtFirstCut = 1. / static_cast(countLtFirstCut); - } else { - weightLtFirstCut = 0; - eventHist.fill(HIST("thereisnoPhiwK0S"), 1); - } - if (countLtSecondCut > 0) { - weightLtSecondCut = 1. / static_cast(countLtSecondCut); - } else { - weightLtSecondCut = 0; - eventHist.fill(HIST("thereisnoPhiwK0S"), 2); + std::array weights{}; + for (unsigned int i = 0; i < counts.size(); i++) { + weights.at(i) = (counts.at(i) > 0 ? 1. / static_cast(counts.at(i)) : 0); } - switch (iBin) { - case 0: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } + fillInvMass2D(recK0S, listrecPhi, multiplicity, weights); } } @@ -1027,14 +842,6 @@ struct phik0shortanalysis { float multiplicity = collision.centFT0M(); eventHist.fill(HIST("hMultiplicityPercent"), multiplicity); - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < multiplicity && multiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - // Defining positive and negative tracks for phi reconstruction auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -1048,23 +855,27 @@ struct phik0shortanalysis { TLorentzVector recPi; recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPi.Rapidity()) > cfgyAcceptance) continue; + float nsigmaTPC, nsigmaTOF; + nsigmaTPC = (track.hasTPC() ? track.tpcNSigmaPi() : -9.99); + nsigmaTOF = (track.hasTOF() ? track.tofNSigmaPi() : -9.99); + std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; + std::array counts{}; // Phi reconstruction // Loop over positive candidates for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); // Loop over all negative candidates for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -1073,341 +884,33 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) - continue; - - listrecPhi.push_back(recPhi); - - if (lowmPhiInc->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiInc->at(iBin)) - countInclusive++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - if (lowmPhiFCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiFCut->at(iBin)) - countLtFirstCut++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - if (lowmPhiSCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiSCut->at(iBin)) - countLtSecondCut++; - } - } - - float nsigmaTPC, nsigmaTOF; - if (track.hasTPC()) - nsigmaTPC = track.tpcNSigmaPi(); - else - nsigmaTPC = -9.99; - if (track.hasTOF()) - nsigmaTOF = track.tofNSigmaPi(); - else - nsigmaTOF = -9.99; - - float weightInclusive, weightLtFirstCut, weightLtSecondCut; - if (countInclusive > 0) { - weightInclusive = 1. / static_cast(countInclusive); - } else { - weightInclusive = 0; - eventHist.fill(HIST("thereisnoPhiwPi"), 0); - } - if (countLtFirstCut > 0) { - weightLtFirstCut = 1. / static_cast(countLtFirstCut); - } else { - weightLtFirstCut = 0; - eventHist.fill(HIST("thereisnoPhiwPi"), 1); - } - if (countLtSecondCut > 0) { - weightLtSecondCut = 1. / static_cast(countLtSecondCut); - } else { - weightLtSecondCut = 0; - eventHist.fill(HIST("thereisnoPhiwPi"), 2); - } - - switch (iBin) { - case 0: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } - } - } - - PROCESS_SWITCH(phik0shortanalysis, processSEPhiPion, "Process Same Event for Phi-Pion Analysis", false); - - void processMEPhiK0S(soa::Filtered const& collisions, FullTracks const&, FullV0s const& V0s, V0DauTracks const&) - { - // Mixing the events with similar vertex z and multiplicity - BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicity}, true}; - for (auto const& [collision1, collision2] : o2::soa::selfCombinations(binningOnPositions, cfgNoMixedEvents, -1, collisions, collisions)) { - if (!collision1.isInelGt0() || !collision2.isInelGt0()) - continue; - - float multiplicity = collision1.centFT0M(); - - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < multiplicity && multiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - - // Defining V0s from collision1 - auto V0ThisColl = V0s.sliceByCached(aod::v0::collisionId, collision1.globalIndex(), cache); - - // Defining positive and negative tracks for phi reconstruction from collision1 and collision2, respectively - auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); - auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); - - for (const auto& v0 : V0ThisColl) { - const auto& posDaughterTrack = v0.posTrack_as(); - const auto& negDaughterTrack = v0.negTrack_as(); - - // Cut on V0 dynamic columns - if (!selectionV0(v0, posDaughterTrack, negDaughterTrack)) - continue; - - TLorentzVector recK0S; - recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) - continue; - - std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; - - // Combinatorial background simulation - for (auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posThisColl, negThisColl))) { - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1) || !selectionTrackResonance(track2) || !selectionPIDKaon(track2)) - continue; // topological and PID selection - - TLorentzVector recPhi; - recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; listrecPhi.push_back(recPhi); - countInclusive++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - countLtFirstCut++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - countLtSecondCut++; - } - - float weightInclusive = 1. / static_cast(countInclusive); - float weightLtFirstCut = 1. / static_cast(countLtFirstCut); - float weightLtSecondCut = 1. / static_cast(countLtSecondCut); - - switch (iBin) { - case 0: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMass2D(recK0S, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; + if (lowmPhi <= recPhi.M() && recPhi.M() <= upmPhi) { + counts.at(0)++; + if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) + continue; + counts.at(1)++; + if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) + continue; + counts.at(2)++; } - default: - break; } } - } - } - PROCESS_SWITCH(phik0shortanalysis, processMEPhiK0S, "Process Mixed Event for Phi-K0S Analysis", false); - - void processMEPhiPion(soa::Filtered const& collisions, FullTracks const& fullTracks) - { - // Mixing the events with similar vertex z and multiplicity - BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicity}, true}; - for (auto const& [collision1, collision2] : o2::soa::selfCombinations(binningOnPositions, cfgNoMixedEvents, -1, collisions, collisions)) { - if (!collision1.isInelGt0() || !collision2.isInelGt0()) - continue; - - float multiplicity = collision1.centFT0M(); - - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < multiplicity && multiplicity <= multBin[i + 1]) { - iBin = i; - break; - } + std::array weights{}; + for (unsigned int i = 0; i < counts.size(); i++) { + weights.at(i) = (counts.at(i) > 0 ? 1. / static_cast(counts.at(i)) : 0); } - // Defining V0s from collision1 - auto trackThisColl = fullTracks.sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); - - // Defining positive and negative tracks for phi reconstruction from collision1 and collision2, respectively - auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); - auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); - - for (const auto& track : trackThisColl) { - - if (!selectionPion(track)) - continue; - - TLorentzVector recPi; - recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) - continue; - - std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; - - // Combinatorial background simulation - for (auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(posThisColl, negThisColl))) { - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1) || !selectionTrackResonance(track2) || !selectionPIDKaon(track2)) - continue; // topological and PID selection - - TLorentzVector recPhi; - recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) - continue; - - listrecPhi.push_back(recPhi); - - countInclusive++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - countLtFirstCut++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - countLtSecondCut++; - } - - float nsigmaTPC, nsigmaTOF; - if (track.hasTPC()) - nsigmaTPC = track.tpcNSigmaPi(); - else - nsigmaTPC = -9.99; - if (track.hasTOF()) - nsigmaTOF = track.tofNSigmaPi(); - else - nsigmaTOF = -9.99; - - float weightInclusive = 1. / static_cast(countInclusive); - float weightLtFirstCut = 1. / static_cast(countLtFirstCut); - float weightLtSecondCut = 1. / static_cast(countLtSecondCut); - - switch (iBin) { - case 0: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } - } + fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, multiplicity, weights); } } - PROCESS_SWITCH(phik0shortanalysis, processMEPhiPion, "Process Mixed Event for Phi-Pion Analysis", false); + PROCESS_SWITCH(phik0shortanalysis, processSEPhiPion, "Process Same Event for Phi-Pion Analysis", false); void processRecMCPhiQA(SimCollisions::iterator const& collision, FullMCTracks const& fullMCTracks, FullV0s const& V0s, V0DauMCTracks const&, MCCollisions const&, aod::McParticles const&) { @@ -1432,7 +935,7 @@ struct phik0shortanalysis { bool isCountedPhi = false; for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); @@ -1442,7 +945,7 @@ struct phik0shortanalysis { // Loop over all negative candidates for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -1475,7 +978,7 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; if (!isCountedPhi) { @@ -1521,7 +1024,7 @@ struct phik0shortanalysis { TLorentzVector recK0S; recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recK0S.Rapidity()) > cfgyAcceptance) continue; int ipTBinK0S = 0; @@ -1567,7 +1070,7 @@ struct phik0shortanalysis { TLorentzVector recPi; recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPi.Rapidity()) > cfgyAcceptance) continue; int ipTBinPi = 0; @@ -1612,14 +1115,6 @@ struct phik0shortanalysis { const auto& mcCollision = collision.mcCollision_as(); float genmultiplicity = mcCollision.centFT0M(); - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < genmultiplicity && genmultiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - // Defining positive and negative tracks for phi reconstruction auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -1656,19 +1151,19 @@ struct phik0shortanalysis { TLorentzVector recK0S; recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recK0S.Rapidity()) > cfgyAcceptance) continue; K0SeffHist.fill(HIST("h3K0SeffInvMass"), genmultiplicity, recK0S.Pt(), recK0S.M()); std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; + std::array counts{}; bool isCountedPhi = false; // Phi reconstruction for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); @@ -1677,7 +1172,7 @@ struct phik0shortanalysis { continue; for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -1710,7 +1205,7 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; listrecPhi.push_back(recPhi); @@ -1720,83 +1215,24 @@ struct phik0shortanalysis { isCountedPhi = true; } - if (lowmPhiInc->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiInc->at(iBin)) - countInclusive++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - if (lowmPhiFCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiFCut->at(iBin)) - countLtFirstCut++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - if (lowmPhiSCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiSCut->at(iBin)) - countLtSecondCut++; + if (lowmPhi <= recPhi.M() && recPhi.M() <= upmPhi) { + counts.at(0)++; + if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) + continue; + counts.at(1)++; + if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) + continue; + counts.at(2)++; + } } } - float weightInclusive, weightLtFirstCut, weightLtSecondCut; - if (countInclusive > 0) { - weightInclusive = 1. / static_cast(countInclusive); - } else { - weightInclusive = 0; - MCeventHist.fill(HIST("thereisnoPhiwK0SMC"), 0); - } - if (countLtFirstCut > 0) { - weightLtFirstCut = 1. / static_cast(countLtFirstCut); - } else { - weightLtFirstCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwK0SMC"), 1); - } - if (countLtSecondCut > 0) { - weightLtSecondCut = 1. / static_cast(countLtSecondCut); - } else { - weightLtSecondCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwK0SMC"), 2); + std::array weights{}; + for (unsigned int i = 0; i < counts.size(); i++) { + weights.at(i) = (counts.at(i) > 0 ? 1. / static_cast(counts.at(i)) : 0); } - switch (iBin) { - case 0: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } + fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weights); } } @@ -1813,14 +1249,6 @@ struct phik0shortanalysis { const auto& mcCollision = collision.mcCollision_as(); float genmultiplicity = mcCollision.centFT0M(); - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < genmultiplicity && genmultiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - // Defining positive and negative tracks for phi reconstruction auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -1841,29 +1269,23 @@ struct phik0shortanalysis { TLorentzVector recPi; recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPi.Rapidity()) > cfgyAcceptance) continue; float nsigmaTPC, nsigmaTOF; - if (track.hasTPC()) - nsigmaTPC = track.tpcNSigmaPi(); - else - nsigmaTPC = -9.99; - if (track.hasTOF()) - nsigmaTOF = track.tofNSigmaPi(); - else - nsigmaTOF = -9.99; + nsigmaTPC = (track.hasTPC() ? track.tpcNSigmaPi() : -9.99); + nsigmaTOF = (track.hasTOF() ? track.tofNSigmaPi() : -9.99); PioneffHist.fill(HIST("h4PieffInvMass"), genmultiplicity, recPi.Pt(), nsigmaTPC, nsigmaTOF); std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; + std::array counts{}; bool isCountedPhi = false; // Phi reconstruction for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); @@ -1872,7 +1294,7 @@ struct phik0shortanalysis { continue; for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -1905,7 +1327,7 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; listrecPhi.push_back(recPhi); @@ -1915,83 +1337,24 @@ struct phik0shortanalysis { isCountedPhi = true; } - if (lowmPhiInc->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiInc->at(iBin)) - countInclusive++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - if (lowmPhiFCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiFCut->at(iBin)) - countLtFirstCut++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - if (lowmPhiSCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiSCut->at(iBin)) - countLtSecondCut++; + if (lowmPhi <= recPhi.M() && recPhi.M() <= upmPhi) { + counts.at(0)++; + if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) + continue; + counts.at(1)++; + if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) + continue; + counts.at(2)++; + } } } - float weightInclusive, weightLtFirstCut, weightLtSecondCut; - if (countInclusive > 0) { - weightInclusive = 1. / static_cast(countInclusive); - } else { - weightInclusive = 0; - MCeventHist.fill(HIST("thereisnoPhiwPiMC"), 0); - } - if (countLtFirstCut > 0) { - weightLtFirstCut = 1. / static_cast(countLtFirstCut); - } else { - weightLtFirstCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwPiMC"), 1); - } - if (countLtSecondCut > 0) { - weightLtSecondCut = 1. / static_cast(countLtSecondCut); - } else { - weightLtSecondCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwPiMC"), 2); + std::array weights{}; + for (unsigned int i = 0; i < counts.size(); i++) { + weights.at(i) = (counts.at(i) > 0 ? 1. / static_cast(counts.at(i)) : 0); } - switch (iBin) { - case 0: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } + fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weights); } } @@ -2017,14 +1380,14 @@ struct phik0shortanalysis { bool isCountedPhi = false; for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); // Loop over all negative candidates for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -2033,7 +1396,7 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; if (!isCountedPhi) { @@ -2056,7 +1419,7 @@ struct phik0shortanalysis { TLorentzVector recK0S; recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recK0S.Rapidity()) > cfgyAcceptance) continue; int ipTBinK0S = 0; @@ -2096,7 +1459,7 @@ struct phik0shortanalysis { TLorentzVector recPi; recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPi.Rapidity()) > cfgyAcceptance) continue; int ipTBinPi = 0; @@ -2141,14 +1504,6 @@ struct phik0shortanalysis { const auto& mcCollision = collision.mcCollision_as(); float genmultiplicity = mcCollision.centFT0M(); - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < genmultiplicity && genmultiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - // Defining positive and negative tracks for phi reconstruction auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -2163,21 +1518,21 @@ struct phik0shortanalysis { TLorentzVector recK0S; recK0S.SetXYZM(v0.px(), v0.py(), v0.pz(), v0.mK0Short()); - if (std::abs(recK0S.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recK0S.Rapidity()) > cfgyAcceptance) continue; std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; + std::array counts{}; // Phi reconstruction for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -2186,88 +1541,29 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; listrecPhi.push_back(recPhi); - if (lowmPhiInc->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiInc->at(iBin)) - countInclusive++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - if (lowmPhiFCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiFCut->at(iBin)) - countLtFirstCut++; - if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - if (lowmPhiSCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiSCut->at(iBin)) - countLtSecondCut++; + if (lowmPhi <= recPhi.M() && recPhi.M() <= upmPhi) { + counts.at(0)++; + if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) + continue; + counts.at(1)++; + if (std::abs(recK0S.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) + continue; + counts.at(2)++; + } } } - float weightInclusive, weightLtFirstCut, weightLtSecondCut; - if (countInclusive > 0) { - weightInclusive = 1. / static_cast(countInclusive); - } else { - weightInclusive = 0; - MCeventHist.fill(HIST("thereisnoPhiwK0SMC"), 0); - } - if (countLtFirstCut > 0) { - weightLtFirstCut = 1. / static_cast(countLtFirstCut); - } else { - weightLtFirstCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwK0SMC"), 1); - } - if (countLtSecondCut > 0) { - weightLtSecondCut = 1. / static_cast(countLtSecondCut); - } else { - weightLtSecondCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwK0SMC"), 2); + std::array weights{}; + for (unsigned int i = 0; i < counts.size(); i++) { + weights.at(i) = (counts.at(i) > 0 ? 1. / static_cast(counts.at(i)) : 0); } - switch (iBin) { - case 0: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } + fillInvMass2D(recK0S, listrecPhi, genmultiplicity, weights); } } @@ -2284,14 +1580,6 @@ struct phik0shortanalysis { const auto& mcCollision = collision.mcCollision_as(); float genmultiplicity = mcCollision.centFT0M(); - int iBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < genmultiplicity && genmultiplicity <= multBin[i + 1]) { - iBin = i; - break; - } - } - // Defining positive and negative tracks for phi reconstruction auto posThisColl = posMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto negThisColl = negMCTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); @@ -2305,31 +1593,25 @@ struct phik0shortanalysis { TLorentzVector recPi; recPi.SetXYZM(track.px(), track.py(), track.pz(), massPi); - if (std::abs(recPi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPi.Rapidity()) > cfgyAcceptance) continue; float nsigmaTPC, nsigmaTOF; - if (track.hasTPC()) - nsigmaTPC = track.tpcNSigmaPi(); - else - nsigmaTPC = -9.99; - if (track.hasTOF()) - nsigmaTOF = track.tofNSigmaPi(); - else - nsigmaTOF = -9.99; + nsigmaTPC = (track.hasTPC() ? track.tpcNSigmaPi() : -9.99); + nsigmaTOF = (track.hasTOF() ? track.tofNSigmaPi() : -9.99); std::vector listrecPhi; - int countInclusive = 0, countLtFirstCut = 0, countLtSecondCut = 0; + std::array counts{}; // Phi reconstruction for (auto track1 : posThisColl) { // loop over all selected tracks - if (!selectionTrackResonance(track1) || !selectionPIDKaon(track1)) + if (!selectionTrackResonance(track1) || !selectionPIDKaonpTdependent(track1)) continue; // topological and PID selection auto track1ID = track1.globalIndex(); for (auto track2 : negThisColl) { - if (!selectionTrackResonance(track2) || !selectionPIDKaon(track2)) + if (!selectionTrackResonance(track2) || !selectionPIDKaonpTdependent(track2)) continue; // topological and PID selection auto track2ID = track2.globalIndex(); @@ -2338,88 +1620,29 @@ struct phik0shortanalysis { TLorentzVector recPhi; recPhi = recMother(track1, track2, massKa, massKa); - if (std::abs(recPhi.Rapidity()) > cfgInclusiveDeltay) + if (std::abs(recPhi.Rapidity()) > cfgyAcceptance) continue; listrecPhi.push_back(recPhi); - if (lowmPhiInc->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiInc->at(iBin)) - countInclusive++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) - continue; - if (lowmPhiFCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiFCut->at(iBin)) - countLtFirstCut++; - if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) - continue; - if (lowmPhiSCut->at(iBin) <= recPhi.M() && recPhi.M() <= upmPhiSCut->at(iBin)) - countLtSecondCut++; + if (lowmPhi <= recPhi.M() && recPhi.M() <= upmPhi) { + counts.at(0)++; + if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgFirstCutonDeltay) + continue; + counts.at(1)++; + if (std::abs(recPi.Rapidity() - recPhi.Rapidity()) > cfgSecondCutonDeltay) + continue; + counts.at(2)++; + } } } - float weightInclusive, weightLtFirstCut, weightLtSecondCut; - if (countInclusive > 0) { - weightInclusive = 1. / static_cast(countInclusive); - } else { - weightInclusive = 0; - MCeventHist.fill(HIST("thereisnoPhiwPiMC"), 0); - } - if (countLtFirstCut > 0) { - weightLtFirstCut = 1. / static_cast(countLtFirstCut); - } else { - weightLtFirstCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwPiMC"), 1); - } - if (countLtSecondCut > 0) { - weightLtSecondCut = 1. / static_cast(countLtSecondCut); - } else { - weightLtSecondCut = 0; - MCeventHist.fill(HIST("thereisnoPhiwPiMC"), 2); + std::array weights{}; + for (unsigned int i = 0; i < counts.size(); i++) { + weights.at(i) = (counts.at(i) > 0 ? 1. / static_cast(counts.at(i)) : 0); } - switch (iBin) { - case 0: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 1: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 2: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 3: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 4: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 5: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 6: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 7: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 8: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - case 9: { - fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weightInclusive, weightLtFirstCut, weightLtSecondCut); - break; - } - default: - break; - } + fillInvMassNSigma(recPi, nsigmaTPC, nsigmaTOF, listrecPhi, genmultiplicity, weights); } } @@ -2472,7 +1695,7 @@ struct phik0shortanalysis { } if (!isPosKaon || !isNegKaon) continue; - if (std::abs(mcParticle1.y()) > cfgInclusiveDeltay) + if (std::abs(mcParticle1.y()) > cfgyAcceptance) continue; if (!isCountedPhi) { @@ -2491,7 +1714,7 @@ struct phik0shortanalysis { continue; if (!mcParticle2.isPhysicalPrimary()) continue; - if (std::abs(mcParticle2.y()) > cfgInclusiveDeltay) + if (std::abs(mcParticle2.y()) > cfgyAcceptance) continue; int ipTBinK0S = 0; @@ -2533,7 +1756,7 @@ struct phik0shortanalysis { continue; if (!mcParticle2.isPhysicalPrimary()) continue; - if (std::abs(mcParticle2.y()) > cfgInclusiveDeltay) + if (std::abs(mcParticle2.y()) > cfgyAcceptance) continue; int ipTBinPi = 0; @@ -2590,31 +1813,27 @@ struct phik0shortanalysis { float multiplicity = mcCollision.centFT0M(); MCeventHist.fill(HIST("hGenMCMultiplicityPercent"), multiplicity); - int imultBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < multiplicity && multiplicity <= multBin[i + 1]) { - imultBin = i; - break; - } - } - for (auto mcParticle1 : mcParticles) { if (mcParticle1.pdgCode() != 310) continue; if (!mcParticle1.isPhysicalPrimary()) continue; - if (std::abs(mcParticle1.y()) > cfgInclusiveDeltay) + auto kDaughters1 = mcParticle1.daughters_as(); + if (kDaughters1.size() != 2) + continue; + bool isPosPion = false, isNegPion = false; + for (auto kDaughter1 : kDaughters1) { + if (kDaughter1.pdgCode() == 211) + isPosPion = true; + if (kDaughter1.pdgCode() == -211) + isNegPion = true; + } + if (!isPosPion || !isNegPion) + continue; + if (std::abs(mcParticle1.y()) > cfgyAcceptance) continue; - int ipTBin = 0; - for (int i = 0; i < nPtBinK0S; i++) { - if (pTBinK0S[i] < mcParticle1.pt() && mcParticle1.pt() <= pTBinK0S[i + 1]) { - ipTBin = i; - break; - } - } - - K0SeffHist.fill(HIST("h2K0SGenMC"), imultBin, ipTBin); + K0SeffHist.fill(HIST("h2K0SGenMC"), multiplicity, mcParticle1.pt()); bool isCountedPhi = false; @@ -2623,19 +1842,19 @@ struct phik0shortanalysis { for (auto mcParticle2 : mcParticles) { if (mcParticle2.pdgCode() != 333) continue; - auto kDaughters = mcParticle2.daughters_as(); - if (kDaughters.size() != 2) + auto kDaughters2 = mcParticle2.daughters_as(); + if (kDaughters2.size() != 2) continue; bool isPosKaon = false, isNegKaon = false; - for (auto kDaughter : kDaughters) { - if (kDaughter.pdgCode() == 321) + for (auto kDaughter2 : kDaughters2) { + if (kDaughter2.pdgCode() == 321) isPosKaon = true; - if (kDaughter.pdgCode() == -321) + if (kDaughter2.pdgCode() == -321) isNegKaon = true; } if (!isPosKaon || !isNegKaon) continue; - if (std::abs(mcParticle2.y()) > cfgInclusiveDeltay) + if (std::abs(mcParticle2.y()) > cfgyAcceptance) continue; if (!isCountedPhi) { @@ -2644,25 +1863,25 @@ struct phik0shortanalysis { } if (!isCountedPhiInclusive) { - MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCInclusive"), imultBin, ipTBin); + MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCInclusive"), multiplicity, mcParticle1.pt()); if (isAssocColl) - MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCInclusiveAssocReco"), imultBin, ipTBin); + MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCInclusiveAssocReco"), multiplicity, mcParticle1.pt()); isCountedPhiInclusive = true; } if (std::abs(mcParticle1.y() - mcParticle2.y()) > cfgFirstCutonDeltay) continue; if (!isCountedPhiFirstCut) { - MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCFirstCut"), imultBin, ipTBin); + MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCFirstCut"), multiplicity, mcParticle1.pt()); if (isAssocColl) - MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCFirstCutAssocReco"), imultBin, ipTBin); + MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCFirstCutAssocReco"), multiplicity, mcParticle1.pt()); isCountedPhiFirstCut = true; } if (std::abs(mcParticle1.y() - mcParticle2.y()) > cfgSecondCutonDeltay) continue; if (!isCountedPhiSecondCut) { - MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCSecondCut"), imultBin, ipTBin); + MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCSecondCut"), multiplicity, mcParticle1.pt()); if (isAssocColl) - MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCSecondCutAssocReco"), imultBin, ipTBin); + MCPhiK0SHist.fill(HIST("h2PhiK0SGenMCSecondCutAssocReco"), multiplicity, mcParticle1.pt()); isCountedPhiSecondCut = true; } } @@ -2689,31 +1908,15 @@ struct phik0shortanalysis { float multiplicity = mcCollision.centFT0M(); MCeventHist.fill(HIST("hGenMCMultiplicityPercent"), multiplicity); - int imultBin = 0; - for (int i = 0; i < nMultBin; i++) { - if (multBin[i] < multiplicity && multiplicity <= multBin[i + 1]) { - imultBin = i; - break; - } - } - for (auto mcParticle1 : mcParticles) { if (std::abs(mcParticle1.pdgCode()) != 211) continue; if (!mcParticle1.isPhysicalPrimary()) continue; - if (std::abs(mcParticle1.y()) > cfgInclusiveDeltay) + if (std::abs(mcParticle1.y()) > cfgyAcceptance) continue; - int ipTBin = 0; - for (int i = 0; i < nPtBinPi; i++) { - if (pTBinPi[i] < mcParticle1.pt() && mcParticle1.pt() <= pTBinPi[i + 1]) { - ipTBin = i; - break; - } - } - - PioneffHist.fill(HIST("h2PiGenMC"), imultBin, ipTBin); + PioneffHist.fill(HIST("h2PiGenMC"), multiplicity, mcParticle1.pt()); bool isCountedPhi = false; @@ -2734,7 +1937,7 @@ struct phik0shortanalysis { } if (!isPosKaon || !isNegKaon) continue; - if (std::abs(mcParticle2.y()) > cfgInclusiveDeltay) + if (std::abs(mcParticle2.y()) > cfgyAcceptance) continue; if (!isCountedPhi) { @@ -2743,25 +1946,25 @@ struct phik0shortanalysis { } if (!isCountedPhiInclusive) { - MCPhiPionHist.fill(HIST("h2PhiPiGenMCInclusive"), imultBin, ipTBin); + MCPhiPionHist.fill(HIST("h2PhiPiGenMCInclusive"), multiplicity, mcParticle1.pt()); if (isAssocColl) - MCPhiPionHist.fill(HIST("h2PhiPiGenMCInclusiveAssocReco"), imultBin, ipTBin); + MCPhiPionHist.fill(HIST("h2PhiPiGenMCInclusiveAssocReco"), multiplicity, mcParticle1.pt()); isCountedPhiInclusive = true; } if (std::abs(mcParticle1.y() - mcParticle2.y()) > cfgFirstCutonDeltay) continue; if (!isCountedPhiFirstCut) { - MCPhiPionHist.fill(HIST("h2PhiPiGenMCFirstCut"), imultBin, ipTBin); + MCPhiPionHist.fill(HIST("h2PhiPiGenMCFirstCut"), multiplicity, mcParticle1.pt()); if (isAssocColl) - MCPhiPionHist.fill(HIST("h2PhiPiGenMCFirstCutAssocReco"), imultBin, ipTBin); + MCPhiPionHist.fill(HIST("h2PhiPiGenMCFirstCutAssocReco"), multiplicity, mcParticle1.pt()); isCountedPhiFirstCut = true; } if (std::abs(mcParticle1.y() - mcParticle2.y()) > cfgSecondCutonDeltay) continue; if (!isCountedPhiSecondCut) { - MCPhiPionHist.fill(HIST("h2PhiPiGenMCSecondCut"), imultBin, ipTBin); + MCPhiPionHist.fill(HIST("h2PhiPiGenMCSecondCut"), multiplicity, mcParticle1.pt()); if (isAssocColl) - MCPhiPionHist.fill(HIST("h2PhiPiGenMCSecondCutAssocReco"), imultBin, ipTBin); + MCPhiPionHist.fill(HIST("h2PhiPiGenMCSecondCutAssocReco"), multiplicity, mcParticle1.pt()); isCountedPhiSecondCut = true; } } diff --git a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx index 687c444bb71..2b07b4c0958 100644 --- a/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/sigmaanalysis.cxx @@ -60,10 +60,6 @@ using V0Sigmas = soa::Join analyseSigma{"analyseSigma", false, "process Sigma-like candidates"}; - // Configurable analyseAntiSigma{"analyseAntiSigma", false, "process AntiSigma-like candidates"}; - // Analysis strategy: Configurable fUseMLSel{"fUseMLSel", false, "Flag to use ML selection. If False, the standard selection is applied."}; Configurable fProcessMonteCarlo{"fProcessMonteCarlo", false, "Flag to process MC data."}; @@ -87,6 +83,8 @@ struct sigmaanalysis { Configurable LambdaMinv0cospa{"LambdaMinv0cospa", 0.95, "Min V0 CosPA"}; Configurable LambdaWindow{"LambdaWindow", 0.015, "Mass window around expected (in GeV/c2)"}; Configurable LambdaMaxRap{"LambdaMaxRap", 0.8, "Max lambda rapidity"}; + Configurable LambdaMaxTPCNSigmas{"LambdaMaxTPCNSigmas", 1e+9, "Max TPC NSigmas for daughters"}; + Configurable LambdaMaxTOFNSigmas{"LambdaMaxTOFNSigmas", 1e+9, "Max TOF NSigmas for daughters"}; //// Photon standard criteria: // Configurable PhotonMaxDauPseudoRap{"PhotonMaxDauPseudoRap", 0.9, "Max pseudorapidity of daughter tracks"}; @@ -109,6 +107,7 @@ struct sigmaanalysis { // TODO: Include PsiPair selection Configurable SigmaMaxRap{"SigmaMaxRap", 0.5, "Max sigma0 rapidity"}; + Configurable SigmaOPAngle{"SigmaOPAngle", 1.0, "Max sigma0 opening angle between daughters (radians)"}; // Axis // base properties @@ -133,7 +132,7 @@ struct sigmaanalysis { ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {500, 0.0f, 50.0f}, "DCA (cm)"}; ConfigurableAxis axisDCAdau{"axisDCAdau", {50, 0.0f, 5.0f}, "DCA (cm)"}; ConfigurableAxis axisCosPA{"axisCosPA", {200, 0.5f, 1.0f}, "Cosine of pointing angle"}; - ConfigurableAxis axisCandSel{"axisCandSel", {25, 0.5f, +25.5f}, "Candidate Selection"}; + ConfigurableAxis axisCandSel{"axisCandSel", {26, 0.5f, +26.5f}, "Candidate Selection"}; // ML ConfigurableAxis MLProb{"MLOutput", {100, 0.0f, 1.0f}, ""}; @@ -144,9 +143,9 @@ struct sigmaanalysis { histos.add("hEventCentrality", "hEventCentrality", kTH1F, {axisCentrality}); // All candidates received - histos.add("GeneralQA/h2dArmenterosAll", "h2dArmenterosAll", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("GeneralQA/h2dArmenterosSelected", "h2dArmenterosSelected", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("GeneralQA/hMassSigma0All", "hMassSigma0All", kTH1F, {axisSigmaMass}); + histos.add("GeneralQA/h2dArmenterosBeforeSel", "h2dArmenterosBeforeSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); + histos.add("GeneralQA/h2dArmenterosAfterSel", "h2dArmenterosAfterSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); + histos.add("GeneralQA/hMassSigma0BeforeSel", "hMassSigma0BeforeSel", kTH1F, {axisSigmaMass}); // Candidates Counters histos.add("GeneralQA/hCandidateAnalysisSelection", "hCandidateAnalysisSelection", kTH1F, {axisCandSel}); @@ -173,6 +172,9 @@ struct sigmaanalysis { histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(21, "Lambda Alpha Cut"); histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(22, "Lambda CosPA Cut"); histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(23, "Lambda Y Cut"); + histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(24, "Sigma Y Cut"); + histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(25, "Sigma OP Angle Cut"); + histos.get(HIST("GeneralQA/hCandidateAnalysisSelection"))->GetXaxis()->SetBinLabel(26, "Lambda/ALambda PID Cut"); // Photon Selection QA histos histos.add("GeneralQA/hPhotonMass", "hPhotonMass", kTH1F, {axisPhotonMass}); @@ -203,10 +205,16 @@ struct sigmaanalysis { histos.add("GeneralQA/hLambdaCosPA", "hLambdaCosPA", kTH1F, {axisCosPA}); histos.add("GeneralQA/hLambdaY", "hLambdaY", kTH1F, {axisRapidity}); histos.add("GeneralQA/hSigmaY", "hSigmaY", kTH1F, {axisRapidity}); + histos.add("GeneralQA/hSigmaOPAngle", "hSigmaOPAngle", kTH1F, {{140, 0.0f, +7.0f}}); + histos.add("GeneralQA/h2dTPCvsTOFNSigma_LambdaPr", "h2dTPCvsTOFNSigma_LambdaPr", kTH2F, {{120, -30, 30}, {120, -30, 30}}); + histos.add("GeneralQA/h2dTPCvsTOFNSigma_LambdaPi", "h2dTPCvsTOFNSigma_LambdaPi", kTH2F, {{120, -30, 30}, {120, -30, 30}}); + histos.add("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPr", "h2dTPCvsTOFNSigma_ALambdaPr", kTH2F, {{120, -30, 30}, {120, -30, 30}}); + histos.add("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPi", "h2dTPCvsTOFNSigma_ALambdaPi", kTH2F, {{120, -30, 30}, {120, -30, 30}}); histos.add("GeneralQA/hPhotonMassSelected", "hPhotonMassSelected", kTH1F, {axisPhotonMass}); histos.add("GeneralQA/hLambdaMassSelected", "hLambdaMassSelected", kTH1F, {axisLambdaMass}); histos.add("GeneralQA/hAntiLambdaMassSelected", "hAntiLambdaMassSelected", kTH1F, {axisLambdaMass}); + // For Signal Extraction // Sigma0 @@ -223,22 +231,78 @@ struct sigmaanalysis { if (fProcessMonteCarlo) { // Event counter - histos.add("hMCEventCentrality", "hMCEventCentrality", kTH1F, {axisCentrality}); + histos.add("MC/hMCEventCentrality", "hMCEventCentrality", kTH1F, {axisCentrality}); // Kinematic histos.add("MC/h3dMassSigma0", "h3dMassSigma0", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); histos.add("MC/h3dMassAntiSigma0", "h3dMassSigma0", kTH3F, {axisCentrality, axisPt, axisSigmaMass}); - histos.add("MC/h2dArmenterosAll", "h2dArmenterosAll", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); - histos.add("MC/h2dArmenterosSelected", "h2dArmenterosSelected", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); + histos.add("MC/h2dArmenterosBeforeSel", "h2dArmenterosBeforeSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); + histos.add("MC/h2dArmenterosAfterSel", "h2dArmenterosAfterSel", {HistType::kTH2F, {axisAPAlpha, axisAPQt}}); // Sigma0 QA - histos.add("MC/hMassSigma0All", "hMassSigma0All", kTH1F, {axisSigmaMass}); - histos.add("MC/hPtSigma0All", "hPtSigma0All", kTH1F, {axisPt}); + histos.add("MC/hMassSigma0BeforeSel", "hMassSigma0BeforeSel", kTH1F, {axisSigmaMass}); + histos.add("MC/hPtSigma0BeforeSel", "hPtSigma0BeforeSel", kTH1F, {axisPt}); histos.add("MC/hMassSigma0", "hMassSigma0", kTH1F, {axisSigmaMass}); histos.add("MC/hPtSigma0", "hPtSigma0", kTH1F, {axisPt}); histos.add("MC/hMassAntiSigma0", "hMassAntiSigma0", kTH1F, {axisSigmaMass}); histos.add("MC/hPtAntiSigma0", "hPtAntiSigma0", kTH1F, {axisPt}); + + // For background decomposition + histos.add("MC/h2dPtVsMassSigma_SignalBkg", "h2dPtVsMassSigma_SignalBkg", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_SignalOnly", "h2dPtVsMassSigma_SignalOnly", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_TrueDaughters", "h2dPtVsMassSigma_TrueDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_TrueGammaFakeLambda", "h2dPtVsMassSigma_TrueGammaFakeLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_FakeGammaTrueLambda", "h2dPtVsMassSigma_FakeGammaTrueLambda", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dPtVsMassSigma_FakeDaughters", "h2dPtVsMassSigma_FakeDaughters", kTH2D, {axisPt, axisSigmaMass}); + histos.add("MC/h2dTrueDaughtersMatrix", "h2dTrueDaughtersMatrix", kTHnSparseD, {{10001, -5000.5f, +5000.5f}, {10001, -5000.5f, +5000.5f}}); + + // For new selection studies: + //// Opening angle between daughters + histos.add("MC/h2dPtVsOPAngle_SignalOnly", "h2dPtVsOPAngle_SignalOnly", kTH2D, {axisPt, {140, 0.0f, +7.0f}}); + histos.add("MC/h2dPtVsOPAngle_TrueDaughters", "h2dPtVsOPAngle_TrueDaughters", kTH2D, {axisPt, {140, 0.0f, +7.0f}}); + histos.add("MC/h2dPtVsMassSigma_AfterOPAngleSel", "h2dPtVsMassSigma_AfterOPAngleSel", kTH2D, {axisPt, axisSigmaMass}); + + // For efficiency/Purity studies + // Before any selection + histos.add("MC/hPtTrueLambda_BeforeSel", "hPtTrueLambda_BeforeSel", kTH1F, {axisPt}); // Signal only + histos.add("MC/hPtTrueGamma_BeforeSel", "hPtTrueGamma_BeforeSel", kTH1F, {axisPt}); // Signal only + histos.add("MC/hPtTrueSigma_BeforeSel", "hPtTrueSigma_BeforeSel", kTH1F, {axisPt}); // Signal only + histos.add("MC/hPtLambdaCand_BeforeSel", "hPtLambdaCand_BeforeSel", kTH1F, {axisPt}); // Bkg + Signal + histos.add("MC/hPtGammaCand_BeforeSel", "hPtGammaCand_BeforeSel", kTH1F, {axisPt}); // Bkg + Signal + histos.add("MC/hPtSigmaCand_BeforeSel", "hPtGammaCand_BeforeSel", kTH1F, {axisPt}); // Bkg + Signal + + // After analysis selections + histos.add("MC/hPtTrueLambda_AfterSel", "hPtTrueLambda_AfterSel", kTH1F, {axisPt}); // Signal only + histos.add("MC/hPtTrueGamma_AfterSel", "hPtTrueGamma_AfterSel", kTH1F, {axisPt}); // Signal only + histos.add("MC/hPtTrueSigma_AfterSel", "hPtTrueSigma_AfterSel", kTH1F, {axisPt}); // Signal only + + histos.add("MC/hPtLambdaCand_AfterSel", "hPtLambdaCand_AfterSel", kTH1F, {axisPt}); + histos.add("MC/hPtGammaCand_AfterSel", "hPtGammaCand_AfterSel", kTH1F, {axisPt}); + histos.add("MC/hPtSigmaCand_AfterSel", "hPtSigmaCand_AfterSel", kTH1F, {axisPt}); + + // TPC vs TOF N Sigmas distributions + histos.add("MC/h3dTPCvsTOFNSigma_LambdaPr", "h3dTPCvsTOFNSigma_LambdaPr", kTH3F, {{120, -30, 30}, {120, -30, 30}, axisPt}); + histos.add("MC/h3dTPCvsTOFNSigma_LambdaPi", "h3dTPCvsTOFNSigma_LambdaPi", kTH3F, {{120, -30, 30}, {120, -30, 30}, axisPt}); + histos.add("MC/h3dTPCvsTOFNSigma_TrueLambdaPr", "h3dTPCvsTOFNSigma_TrueLambdaPr", kTH3F, {{120, -30, 30}, {120, -30, 30}, axisPt}); + histos.add("MC/h3dTPCvsTOFNSigma_TrueLambdaPi", "h3dTPCvsTOFNSigma_TrueLambdaPi", kTH3F, {{120, -30, 30}, {120, -30, 30}, axisPt}); + + // Testing New Selections: + //// Opening Angle + histos.add("MC/hPtTrueSigma_AngleSel", "hPtTrueSigma_AngleSel", kTH1F, {axisPt}); + histos.add("MC/hPtSigmaCand_AngleSel", "hPtSigmaCand_AngleSel", kTH1F, {axisPt}); + + //// TPC PID + histos.add("MC/hPtTrueLambda_TPCPID", "hPtTrueLambda_TPCPID", kTH1F, {axisPt}); + histos.add("MC/hPtLambdaCandidates_TPCPID", "hPtLambdaCandidates_TPCPID", kTH1F, {axisPt}); + + //// TOF PID + histos.add("MC/hPtTrueLambda_TOFPID", "hPtTrueLambda_TOFPID", kTH1F, {axisPt}); + histos.add("MC/hPtLambdaCandidates_TOFPID", "hPtLambdaCandidates_TOFPID", kTH1F, {axisPt}); + + //// TPC+TOF PID + histos.add("MC/hPtTrueLambda_TPCTOFPID", "hPtTrueLambda_TPCTOFPID", kTH1F, {axisPt}); + histos.add("MC/hPtLambdaCandidates_TPCTOFPID", "hPtLambdaCandidates_TPCTOFPID", kTH1F, {axisPt}); } } @@ -360,12 +424,12 @@ struct sigmaanalysis { histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 23.); if (TMath::Abs(cand.sigmaRapidity()) > SigmaMaxRap) return false; + histos.fill(HIST("GeneralQA/hSigmaOPAngle"), cand.sigmaOPAngle()); histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 24.); - histos.fill(HIST("GeneralQA/hPhotonMassSelected"), cand.photonMass()); - histos.fill(HIST("GeneralQA/hLambdaMassSelected"), cand.lambdaMass()); - histos.fill(HIST("GeneralQA/hAntiLambdaMassSelected"), cand.antilambdaMass()); + if (cand.sigmaOPAngle() > SigmaOPAngle) + return false; + histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 25.); } - return true; } @@ -381,28 +445,127 @@ struct sigmaanalysis { void processMonteCarlo(aod::Sigma0Collision const& coll, V0MCSigmas const& v0s) { - histos.fill(HIST("hMCEventCentrality"), coll.centFT0C()); + histos.fill(HIST("MC/hMCEventCentrality"), coll.centFT0C()); for (auto& sigma : v0s) { // selecting Sigma0-like candidates - if (sigma.isSigma() || sigma.isAntiSigma()) { - histos.fill(HIST("MC/h2dArmenterosAll"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("MC/h2dArmenterosAll"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("MC/hMassSigma0All"), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtSigma0All"), sigma.sigmapT()); - if (!processSigmaCandidate(sigma)) - continue; + histos.fill(HIST("MC/h2dArmenterosBeforeSel"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST("MC/h2dArmenterosBeforeSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); + histos.fill(HIST("MC/hMassSigma0BeforeSel"), sigma.sigmaMass()); + histos.fill(HIST("MC/hPtSigma0BeforeSel"), sigma.sigmapT()); + + if (sigma.photonCandPDGCode() == 22) + histos.fill(HIST("MC/hPtTrueGamma_BeforeSel"), sigma.photonPt()); + if (sigma.lambdaCandPDGCode() == 3122) + histos.fill(HIST("MC/hPtTrueLambda_BeforeSel"), sigma.lambdaPt()); + if (sigma.isSigma() || sigma.isAntiSigma()) + histos.fill(HIST("MC/hPtTrueSigma_BeforeSel"), sigma.sigmapT()); + + histos.fill(HIST("MC/hPtGammaCand_BeforeSel"), sigma.photonPt()); + histos.fill(HIST("MC/hPtLambdaCand_BeforeSel"), sigma.lambdaPt()); + histos.fill(HIST("MC/hPtSigmaCand_BeforeSel"), sigma.sigmapT()); + + if (!processSigmaCandidate(sigma)) + continue; + + // Purity Study + PID study: + bool fPassTPCPID = false; + bool fPassTOFPID = false; + + histos.fill(HIST("MC/hPtGammaCand_AfterSel"), sigma.photonPt()); + histos.fill(HIST("MC/hPtSigmaCand_AfterSel"), sigma.sigmapT()); + + if (sigma.photonCandPDGCode() == 22) + histos.fill(HIST("MC/hPtTrueGamma_AfterSel"), sigma.photonPt()); + + // For Lambda PID Studies + if (sigma.lambdaAlpha() > 0) { + histos.fill(HIST("MC/hPtLambdaCand_AfterSel"), sigma.lambdaPt()); + histos.fill(HIST("MC/h3dTPCvsTOFNSigma_LambdaPr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.sigmapT()); + histos.fill(HIST("MC/h3dTPCvsTOFNSigma_LambdaPi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.sigmapT()); + + if (sigma.lambdaCandPDGCode() == 3122) { + histos.fill(HIST("MC/hPtTrueLambda_AfterSel"), sigma.lambdaPt()); + histos.fill(HIST("MC/h3dTPCvsTOFNSigma_TrueLambdaPr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma(), sigma.sigmapT()); + histos.fill(HIST("MC/h3dTPCvsTOFNSigma_TrueLambdaPi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma(), sigma.sigmapT()); + } + + // TPC PID: + if ((TMath::Abs(sigma.lambdaPosPrTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaNegPiTPCNSigma()) < LambdaMaxTPCNSigmas)) { + fPassTPCPID = true; + histos.fill(HIST("MC/hPtLambdaCandidates_TPCPID"), sigma.lambdaPt()); + if (sigma.lambdaCandPDGCode() == 3122) + histos.fill(HIST("MC/hPtTrueLambda_TPCPID"), sigma.lambdaPt()); + } + + // TOF PID: + if ((TMath::Abs(sigma.lambdaPrTOFNSigma()) < LambdaMaxTOFNSigmas) && (TMath::Abs(sigma.lambdaPiTOFNSigma()) < LambdaMaxTOFNSigmas)) { + fPassTOFPID = true; + histos.fill(HIST("MC/hPtLambdaCandidates_TOFPID"), sigma.lambdaPt()); + if (sigma.lambdaCandPDGCode() == 3122) + histos.fill(HIST("MC/hPtTrueLambda_TOFPID"), sigma.lambdaPt()); + } + // TPC + TOF PID: + if (fPassTPCPID && fPassTOFPID) { + histos.fill(HIST("MC/hPtLambdaCandidates_TPCTOFPID"), sigma.lambdaPt()); + if (sigma.lambdaCandPDGCode() == 3122) + histos.fill(HIST("MC/hPtTrueLambda_TPCTOFPID"), sigma.lambdaPt()); + } + } + + // For Opening Angle study + if (sigma.sigmaOPAngle() <= SigmaOPAngle) { + histos.fill(HIST("MC/h2dPtVsMassSigma_AfterOPAngleSel"), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("MC/hPtSigmaCand_AngleSel"), sigma.sigmapT()); + if (sigma.isSigma() || sigma.isAntiSigma()) + histos.fill(HIST("MC/hPtTrueSigma_AngleSel"), sigma.sigmapT()); + } + + // For background studies: + histos.fill(HIST("MC/h2dPtVsMassSigma_SignalBkg"), sigma.sigmapT(), sigma.sigmaMass()); + // Real Gamma x Real Lambda - but not from the same sigma0/antisigma0! + if ((sigma.photonCandPDGCode() == 22) && ((sigma.lambdaCandPDGCode() == 3122) || (sigma.lambdaCandPDGCode() == -3122)) && !(sigma.isSigma()) && !(sigma.isAntiSigma())) { + histos.fill(HIST("MC/h2dPtVsMassSigma_TrueDaughters"), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("MC/h2dTrueDaughtersMatrix"), sigma.lambdaCandPDGCodeMother(), sigma.photonCandPDGCodeMother()); + histos.fill(HIST("MC/h2dPtVsOPAngle_TrueDaughters"), sigma.sigmapT(), sigma.sigmaOPAngle()); + } + // Real Gamma x fake Lambda + if ((sigma.photonCandPDGCode() == 22) && (sigma.lambdaCandPDGCode() != 3122) && (sigma.lambdaCandPDGCode() != -3122)) + histos.fill(HIST("MC/h2dPtVsMassSigma_TrueGammaFakeLambda"), sigma.sigmapT(), sigma.sigmaMass()); + + // Fake Gamma x Real Lambda + if ((sigma.photonCandPDGCode() != 22) && ((sigma.lambdaCandPDGCode() == 3122) || (sigma.lambdaCandPDGCode() == -3122))) + histos.fill(HIST("MC/h2dPtVsMassSigma_FakeGammaTrueLambda"), sigma.sigmapT(), sigma.sigmaMass()); - histos.fill(HIST("MC/h2dArmenterosSelected"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("MC/h2dArmenterosSelected"), sigma.lambdaAlpha(), sigma.lambdaQt()); + // Fake Gamma x Fake Lambda + if ((sigma.photonCandPDGCode() != 22) && (sigma.lambdaCandPDGCode() != 3122) && (sigma.lambdaCandPDGCode() != -3122)) + histos.fill(HIST("MC/h2dPtVsMassSigma_FakeDaughters"), sigma.sigmapT(), sigma.sigmaMass()); + // MC association (signal study) + if (sigma.isSigma() || sigma.isAntiSigma()) { + histos.fill(HIST("MC/h2dPtVsMassSigma_SignalOnly"), sigma.sigmapT(), sigma.sigmaMass()); + histos.fill(HIST("MC/h2dPtVsOPAngle_SignalOnly"), sigma.sigmapT(), sigma.sigmaOPAngle()); + histos.fill(HIST("MC/hPtTrueSigma_AfterSel"), sigma.sigmapT()); + histos.fill(HIST("GeneralQA/hPhotonMassSelected"), sigma.photonMass()); if (sigma.isSigma()) { - histos.fill(HIST("MC/hMassSigma0"), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtSigma0"), sigma.sigmapT()); - histos.fill(HIST("MC/h3dMassSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + // PID selections + if ((TMath::Abs(sigma.lambdaPosPrTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaNegPiTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaPrTOFNSigma()) < LambdaMaxTOFNSigmas) && (TMath::Abs(sigma.lambdaPiTOFNSigma()) < LambdaMaxTOFNSigmas)) { + histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); + histos.fill(HIST("GeneralQA/hLambdaMassSelected"), sigma.lambdaMass()); + histos.fill(HIST("MC/hMassSigma0"), sigma.sigmaMass()); + histos.fill(HIST("MC/hPtSigma0"), sigma.sigmapT()); + histos.fill(HIST("MC/h3dMassSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + } } else { - histos.fill(HIST("MC/hMassAntiSigma0"), sigma.sigmaMass()); - histos.fill(HIST("MC/hPtAntiSigma0"), sigma.sigmapT()); - histos.fill(HIST("MC/h3dMassAntiSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + // PID selections + if ((TMath::Abs(sigma.lambdaPosPiTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaNegPrTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.aLambdaPrTOFNSigma()) < LambdaMaxTOFNSigmas) && (TMath::Abs(sigma.aLambdaPiTOFNSigma()) < LambdaMaxTOFNSigmas)) { + histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST("GeneralQA/hAntiLambdaMassSelected"), sigma.antilambdaMass()); + histos.fill(HIST("MC/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); + histos.fill(HIST("MC/hMassAntiSigma0"), sigma.sigmaMass()); + histos.fill(HIST("MC/hPtAntiSigma0"), sigma.sigmapT()); + histos.fill(HIST("MC/h3dMassAntiSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + } } } } @@ -412,9 +575,9 @@ struct sigmaanalysis { { histos.fill(HIST("hEventCentrality"), coll.centFT0C()); for (auto& sigma : v0s) { // selecting Sigma0-like candidates - histos.fill(HIST("GeneralQA/h2dArmenterosAll"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("GeneralQA/h2dArmenterosAll"), sigma.lambdaAlpha(), sigma.lambdaQt()); - histos.fill(HIST("GeneralQA/hMassSigma0All"), sigma.sigmaMass()); + histos.fill(HIST("GeneralQA/h2dArmenterosBeforeSel"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST("GeneralQA/h2dArmenterosBeforeSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); + histos.fill(HIST("GeneralQA/hMassSigma0BeforeSel"), sigma.sigmaMass()); nSigmaCandidates++; if (nSigmaCandidates % 50000 == 0) { @@ -423,19 +586,35 @@ struct sigmaanalysis { if (!processSigmaCandidate(sigma)) continue; - histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), sigma.photonAlpha(), sigma.photonQt()); - histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), sigma.lambdaAlpha(), sigma.lambdaQt()); - + histos.fill(HIST("GeneralQA/hPhotonMassSelected"), sigma.photonMass()); if (sigma.lambdaAlpha() > 0) { - histos.fill(HIST("Sigma0/hMassSigma0"), sigma.sigmaMass()); - histos.fill(HIST("Sigma0/hPtSigma0"), sigma.sigmapT()); - histos.fill(HIST("Sigma0/hRapiditySigma0"), sigma.sigmaRapidity()); - histos.fill(HIST("Sigma0/h3dMassSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + // PID selections + histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_LambdaPr"), sigma.lambdaPosPrTPCNSigma(), sigma.lambdaPrTOFNSigma()); + histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_LambdaPi"), sigma.lambdaNegPiTPCNSigma(), sigma.lambdaPiTOFNSigma()); + if ((TMath::Abs(sigma.lambdaPosPrTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaNegPiTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaPrTOFNSigma()) < LambdaMaxTOFNSigmas) && (TMath::Abs(sigma.lambdaPiTOFNSigma()) < LambdaMaxTOFNSigmas)) { + histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); + histos.fill(HIST("GeneralQA/hLambdaMassSelected"), sigma.lambdaMass()); + histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 26.); + histos.fill(HIST("Sigma0/hMassSigma0"), sigma.sigmaMass()); + histos.fill(HIST("Sigma0/hPtSigma0"), sigma.sigmapT()); + histos.fill(HIST("Sigma0/hRapiditySigma0"), sigma.sigmaRapidity()); + histos.fill(HIST("Sigma0/h3dMassSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + } } else { - histos.fill(HIST("AntiSigma0/hMassAntiSigma0"), sigma.sigmaMass()); - histos.fill(HIST("AntiSigma0/hPtAntiSigma0"), sigma.sigmapT()); - histos.fill(HIST("AntiSigma0/hRapidityAntiSigma0"), sigma.sigmaRapidity()); - histos.fill(HIST("AntiSigma0/h3dMassAntiSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + // PID selections + histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPr"), sigma.lambdaNegPrTPCNSigma(), sigma.aLambdaPrTOFNSigma()); + histos.fill(HIST("GeneralQA/h2dTPCvsTOFNSigma_ALambdaPi"), sigma.lambdaPosPiTPCNSigma(), sigma.aLambdaPiTOFNSigma()); + if ((TMath::Abs(sigma.lambdaPosPiTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.lambdaNegPrTPCNSigma()) < LambdaMaxTPCNSigmas) && (TMath::Abs(sigma.aLambdaPrTOFNSigma()) < LambdaMaxTOFNSigmas) && (TMath::Abs(sigma.aLambdaPiTOFNSigma()) < LambdaMaxTOFNSigmas)) { + histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.photonAlpha(), sigma.photonQt()); + histos.fill(HIST("GeneralQA/h2dArmenterosAfterSel"), sigma.lambdaAlpha(), sigma.lambdaQt()); + histos.fill(HIST("GeneralQA/hAntiLambdaMassSelected"), sigma.antilambdaMass()); + histos.fill(HIST("GeneralQA/hCandidateAnalysisSelection"), 26.); + histos.fill(HIST("AntiSigma0/hMassAntiSigma0"), sigma.sigmaMass()); + histos.fill(HIST("AntiSigma0/hPtAntiSigma0"), sigma.sigmapT()); + histos.fill(HIST("AntiSigma0/hRapidityAntiSigma0"), sigma.sigmaRapidity()); + histos.fill(HIST("AntiSigma0/h3dMassAntiSigma0"), coll.centFT0C(), sigma.sigmapT(), sigma.sigmaMass()); + } } } } diff --git a/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx b/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx index 777554a5916..7706fe720bb 100644 --- a/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx +++ b/PWGLF/Tasks/Strangeness/strange-yield-pbpb.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -81,9 +82,10 @@ struct strangeYieldPbPb { Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; - Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; Configurable studyUPConly{"studyUPConly", false, "is UPC-only analysis"}; + Configurable useUPCflag{"useUPCflag", false, "select UPC flagged events"}; Configurable verbose{"verbose", false, "additional printouts"}; @@ -172,13 +174,13 @@ struct strangeYieldPbPb { Configurable doPlainTopoQA{"doPlainTopoQA", true, "do simple 1D QA of candidates"}; struct : ConfigurableGroup { - ConfigurableAxis axisFT0Aampl{"FT0Aamplitude", {100, 0.0f, 2000.0f}, "FT0Aamplitude"}; - ConfigurableAxis axisFT0Campl{"FT0Camplitude", {100, 0.0f, 2000.0f}, "FT0Camplitude"}; - ConfigurableAxis axisFV0Aampl{"FV0Aamplitude", {100, 0.0f, 2000.0f}, "FV0Aamplitude"}; - ConfigurableAxis axisFDDAampl{"FDDAamplitude", {100, 0.0f, 2000.0f}, "FDDAamplitude"}; - ConfigurableAxis axisFDDCampl{"FDDCamplitude", {100, 0.0f, 2000.0f}, "FDDCamplitude"}; - ConfigurableAxis axisZNAampl{"ZNAamplitude", {100, 0.0f, 250.0f}, "ZNAamplitude"}; - ConfigurableAxis axisZNCampl{"ZNCamplitude", {100, 0.0f, 250.0f}, "ZNCamplitude"}; + ConfigurableAxis axisFT0Aampl{"axisFT0Aampl", {100, 0.0f, 2000.0f}, "FT0Aamplitude"}; + ConfigurableAxis axisFT0Campl{"axisFT0Campl", {100, 0.0f, 2000.0f}, "FT0Camplitude"}; + ConfigurableAxis axisFV0Aampl{"axisFV0Aampl", {100, 0.0f, 2000.0f}, "FV0Aamplitude"}; + ConfigurableAxis axisFDDAampl{"axisFDDAampl", {100, 0.0f, 2000.0f}, "FDDAamplitude"}; + ConfigurableAxis axisFDDCampl{"axisFDDCampl", {100, 0.0f, 2000.0f}, "FDDCamplitude"}; + ConfigurableAxis axisZNAampl{"axisZNAampl", {100, 0.0f, 250.0f}, "ZNAamplitude"}; + ConfigurableAxis axisZNCampl{"axisZNCampl", {100, 0.0f, 250.0f}, "ZNCamplitude"}; } axisDetectors; // for MC @@ -209,8 +211,16 @@ struct strangeYieldPbPb { axisOmegaMass, axisOmegaMass}; - ConfigurableAxis axisNch{"axisNch", {2000, -0.5f, 1999.5f}, "Number of charged particles"}; - ConfigurableAxis axisFT0C{"FT0C", + ConfigurableAxis axisNTracksGlobal{"axisNTracksGlobal", {100, -0.5f, 99.5f}, "Number of global tracks"}; + ConfigurableAxis axisNTracksPVeta1{"axisNTracksPVeta1", {100, -0.5f, 99.5f}, "Number of PV contributors in |eta| < 1"}; + ConfigurableAxis axisNTracksTotalExceptITSonly{"axisNTracksTotalExceptITSonly", {100, -0.5f, 99.5f}, "Number of ITS-TPC and TPC only tracks"}; + ConfigurableAxis axisNchInvMass{"axisNchInvMass", {20, -0.5f, 19.5f}, "Number of charged particles for kTHnSparseF"}; + + ConfigurableAxis axisFT0C_QA{"axisFT0C_QA", + {VARIABLE_WIDTH, 0., 0.01, 0.05, 0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 105.5}, + "FT0C (%)"}; + + ConfigurableAxis axisFT0C{"axisFT0C", {VARIABLE_WIDTH, 0., 0.01, 0.05, 0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 105.5}, "FT0C (%)"}; @@ -340,11 +350,11 @@ struct strangeYieldPbPb { void addKinematicQAHistograms(HistogramRegistry& histos) { const bool isCascade = (partID > 2.5) ? true : false; - histos.add(Form("%s/h2dPosEtaPt", particlenames[partID].data()), "h2dPosEtaPt", kTH3F, {axisPtCoarse, axisEta, axisSelGap}); - histos.add(Form("%s/h2dNegEtaPt", particlenames[partID].data()), "h2dNegEtaPt", kTH3F, {axisPtCoarse, axisEta, axisSelGap}); - histos.add(Form("%s/h2dRapPt", particlenames[partID].data()), "h2dRapPt", kTH3F, {axisPtCoarse, axisRap, axisSelGap}); + histos.add(Form("%s/h3dPosEtaPt", particlenames[partID].data()), "h3dPosEtaPt", kTH3F, {axisPtCoarse, axisEta, axisSelGap}); + histos.add(Form("%s/h3dNegEtaPt", particlenames[partID].data()), "h3dNegEtaPt", kTH3F, {axisPtCoarse, axisEta, axisSelGap}); + histos.add(Form("%s/h3dRapPt", particlenames[partID].data()), "h3dRapPt", kTH3F, {axisPtCoarse, axisRap, axisSelGap}); if (isCascade) { - histos.add(Form("%s/h2dBachEtaPt", particlenames[partID].data()), "h2dBachEtaPt", kTH3F, {axisPtCoarse, axisEta, axisSelGap}); + histos.add(Form("%s/h3dBachEtaPt", particlenames[partID].data()), "h3dBachEtaPt", kTH3F, {axisPtCoarse, axisEta, axisSelGap}); } } @@ -354,30 +364,30 @@ struct strangeYieldPbPb { const bool isCascade = (partID > 2.5) ? true : false; if (doDetectPropQA == 1) { if (isCascade) { - histos.add(Form("%s/h8dDetectPropVsCentrality", particlenames[partID].data()), "h8dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add(Form("%s/h8dDetectPropVsCentrality", particlenames[partID].data()), "h8dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); } else { - histos.add(Form("%s/h6dDetectPropVsCentrality", particlenames[partID].data()), "h6dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); + histos.add(Form("%s/h6dDetectPropVsCentrality", particlenames[partID].data()), "h6dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse}); } - histos.add(Form("%s/h4dPosDetectPropVsCentrality", particlenames[partID].data()), "h4dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); - histos.add(Form("%s/h4dNegDetectPropVsCentrality", particlenames[partID].data()), "h4dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); - histos.add(Form("%s/h4dBachDetectPropVsCentrality", particlenames[partID].data()), "h4dBachDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add(Form("%s/h4dPosDetectPropVsCentrality", particlenames[partID].data()), "h4dPosDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add(Form("%s/h4dNegDetectPropVsCentrality", particlenames[partID].data()), "h4dNegDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); + histos.add(Form("%s/h4dBachDetectPropVsCentrality", particlenames[partID].data()), "h4dBachDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse}); } if (doDetectPropQA == 2) { if (isCascade) { - histos.add(Form("%s/h9dDetectPropVsCentrality", particlenames[partID].data()), "h9dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h9dDetectPropVsCentrality", particlenames[partID].data()), "h9dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); } else { - histos.add(Form("%s/h7dDetectPropVsCentrality", particlenames[partID].data()), "h7dDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h7dDetectPropVsCentrality", particlenames[partID].data()), "h7dDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMapCoarse, axisITScluMapCoarse, axisDetMapCoarse, axisITScluMapCoarse, axisPtCoarse, axisInvMass.at(partID)}); } - histos.add(Form("%s/h5dPosDetectPropVsCentrality", particlenames[partID].data()), "h5dPosDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); - histos.add(Form("%s/h5dNegDetectPropVsCentrality", particlenames[partID].data()), "h5dNegDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); - histos.add(Form("%s/h5dBachDetectPropVsCentrality", particlenames[partID].data()), "h5dBachDetectPropVsCentrality", kTHnF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h5dPosDetectPropVsCentrality", particlenames[partID].data()), "h5dPosDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h5dNegDetectPropVsCentrality", particlenames[partID].data()), "h5dNegDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); + histos.add(Form("%s/h5dBachDetectPropVsCentrality", particlenames[partID].data()), "h5dBachDetectPropVsCentrality", kTHnSparseF, {axisFT0C, axisDetMap, axisITScluMap, axisPtCoarse, axisInvMass.at(partID)}); } } template void addHistograms(HistogramRegistry& histos) { - histos.add(Form("%s/h5dMass", particlenames[partID].data()), "h5dMass", kTHnF, {axisFT0C, axisPt, axisInvMass.at(partID), axisSelGap, {100, -0.5f, 99.5f}}); + histos.add(Form("%s/h6dMass", particlenames[partID].data()), "h6dMass", kTHnSparseF, {axisFT0C, axisPt, axisInvMass.at(partID), axisSelGap, axisNchInvMass, axisRap}); histos.add(Form("%s/h2dMass", particlenames[partID].data()), "h2dMass", kTH2F, {axisInvMass.at(partID), axisSelGap}); if (doPlainTopoQA) { addTopoHistograms(histos); @@ -464,11 +474,11 @@ struct strangeYieldPbPb { } histos.fill(HIST(particlenames[partID]) + HIST("/h2dMass"), invMass, gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h5dMass"), centrality, pT, invMass, gap, coll.multNTracksGlobal()); + histos.fill(HIST(particlenames[partID]) + HIST("/h6dMass"), centrality, pT, invMass, gap, coll.multAllTracksTPCOnly() + coll.multAllTracksITSTPC(), rapidity); if (doKienmaticQA) { - histos.fill(HIST(particlenames[partID]) + HIST("/h2dPosEtaPt"), pT, cand.positiveeta(), gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h2dNegEtaPt"), pT, cand.negativeeta(), gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h2dRapPt"), pT, rapidity, gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dPosEtaPt"), pT, cand.positiveeta(), gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dNegEtaPt"), pT, cand.negativeeta(), gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dRapPt"), pT, rapidity, gap); } if (doPlainTopoQA) { histos.fill(HIST(particlenames[partID]) + HIST("/hPosDCAToPV"), cand.dcapostopv()); @@ -614,12 +624,12 @@ struct strangeYieldPbPb { } } histos.fill(HIST(particlenames[partID]) + HIST("/h2dMass"), invMass, gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h5dMass"), centrality, pT, invMass, gap, coll.multNTracksGlobal()); + histos.fill(HIST(particlenames[partID]) + HIST("/h6dMass"), centrality, pT, invMass, gap, coll.multAllTracksTPCOnly() + coll.multAllTracksITSTPC(), rapidity); if (doKienmaticQA) { - histos.fill(HIST(particlenames[partID]) + HIST("/h2dPosEtaPt"), pT, cand.positiveeta(), gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h2dNegEtaPt"), pT, cand.negativeeta(), gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h2dBachEtaPt"), pT, cand.bacheloreta(), gap); - histos.fill(HIST(particlenames[partID]) + HIST("/h2dRapPt"), pT, rapidity, gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dPosEtaPt"), pT, cand.positiveeta(), gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dNegEtaPt"), pT, cand.negativeeta(), gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dBachEtaPt"), pT, cand.bacheloreta(), gap); + histos.fill(HIST(particlenames[partID]) + HIST("/h3dRapPt"), pT, rapidity, gap); } if (doPlainTopoQA) { histos.fill(HIST(particlenames[partID]) + HIST("/hCascCosPA"), pT, cand.casccosPA(coll.posX(), coll.posY(), coll.posZ())); @@ -813,7 +823,7 @@ struct strangeYieldPbPb { maskSelectionAntiOmega = maskTopologicalCasc | maskKinematicCasc | maskTrackPropertiesCasc | maskAntiOmegaSpecific | (std::bitset(1) << selPhysPrimAntiOmega); // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1F, {{15, -0.5f, +14.5f}}); + histos.add("hEventSelection", "hEventSelection", kTH1F, {{16, -0.5f, +15.5f}}); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "kIsTriggerTVX"); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); @@ -829,19 +839,21 @@ struct strangeYieldPbPb { histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(13, "Below min occup."); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(14, "Above max occup."); histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(15, "isUPC"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(16, "has UPC flag"); // Event QA - histos.add("eventQA/hEventCentrality", "hEventCentrality", kTH1F, {axisFT0C}); - histos.add("eventQA/hCentralityVsNch", "hCentralityVsNch", kTH2F, {axisFT0C, axisNch}); - histos.add("eventQA/hEventOccupancy", "hEventOccupancy", kTH1F, {axisOccupancy}); - histos.add("eventQA/hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH2F, {axisFT0C, axisOccupancy}); - histos.add("eventQA/hEventNchCorrelationAfCuts", "hEventNchCorrelationAfCuts", kTH2F, {{5000, 0, 5000}, {5000, 0, 2500}}); - histos.add("eventQA/hEventGlobalTracksVsCentrality", "hEventGlobalTracksVsCentrality", kTH2F, {{100, 0, 100}, {2500, 0, 2500}}); + histos.add("eventQA/hCentrality", "hCentrality", kTH2F, {axisFT0C_QA, axisSelGap}); + histos.add("eventQA/hCentralityVsTracksPVeta1", "hCentralityVsTracksPVeta1", kTH3F, {axisFT0C_QA, axisNTracksPVeta1, axisSelGap}); + histos.add("eventQA/hCentralityVsTracksTotalExceptITSonly", "hCentralityVsTracksTotalExceptITSonly", kTH3F, {axisFT0C_QA, axisNTracksTotalExceptITSonly, axisSelGap}); + histos.add("eventQA/hOccupancy", "hOccupancy", kTH2F, {axisOccupancy, axisSelGap}); + histos.add("eventQA/hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH3F, {axisFT0C_QA, axisOccupancy, axisSelGap}); + histos.add("eventQA/hTracksPVeta1VsTracksGlobal", "hTracksPVeta1VsTracksGlobal", kTH3F, {axisNTracksPVeta1, axisNTracksGlobal, axisSelGap}); + histos.add("eventQA/hCentralityVsTracksGlobal", "hCentralityVsTracksGlobal", kTH3F, {axisFT0C_QA, axisNTracksGlobal, axisSelGap}); histos.add("eventQA/hGapSide", "Gap side; Entries", kTH1F, {{5, -0.5, 4.5}}); histos.add("eventQA/hSelGapSide", "Selected gap side; Entries", kTH1F, {axisSelGap}); - histos.add("eventQA/hPosX", "Vertex position in x", kTH1F, {{100, -0.1, 0.1}}); - histos.add("eventQA/hPosY", "Vertex position in y", kTH1F, {{100, -0.1, 0.1}}); - histos.add("eventQA/hPosZ", "Vertex position in z", kTH1F, {{100, -20., 20.}}); + histos.add("eventQA/hPosX", "Vertex position in x", kTH2F, {{100, -0.1, 0.1}, axisSelGap}); + histos.add("eventQA/hPosY", "Vertex position in y", kTH2F, {{100, -0.1, 0.1}, axisSelGap}); + histos.add("eventQA/hPosZ", "Vertex position in z", kTH2F, {{100, -20., 20.}, axisSelGap}); histos.add("eventQA/hFT0", "hFT0", kTH3F, {axisDetectors.axisFT0Aampl, axisDetectors.axisFT0Campl, axisSelGap}); histos.add("eventQA/hFDD", "hFDD", kTH3F, {axisDetectors.axisFDDAampl, axisDetectors.axisFDDCampl, axisSelGap}); histos.add("eventQA/hZN", "hZN", kTH3F, {axisDetectors.axisZNAampl, axisDetectors.axisZNCampl, axisSelGap}); @@ -942,19 +954,20 @@ struct strangeYieldPbPb { } template - void fillHistogramsQA(TCollision const& collision) + void fillHistogramsQA(TCollision const& collision, int const& gap) { // QA histograms float centrality = collision.centFT0C(); - histos.fill(HIST("eventQA/hEventCentrality"), centrality); - histos.fill(HIST("eventQA/hCentralityVsNch"), centrality, collision.multNTracksPVeta1()); - histos.fill(HIST("eventQA/hEventOccupancy"), collision.trackOccupancyInTimeRange()); - histos.fill(HIST("eventQA/hCentralityVsOccupancy"), centrality, collision.trackOccupancyInTimeRange()); - histos.fill(HIST("eventQA/hEventNchCorrelationAfCuts"), collision.multNTracksPVeta1(), collision.multNTracksGlobal()); - histos.fill(HIST("eventQA/hEventGlobalTracksVsCentrality"), centrality, collision.multNTracksGlobal()); - histos.fill(HIST("eventQA/hPosX"), collision.posX()); - histos.fill(HIST("eventQA/hPosY"), collision.posY()); - histos.fill(HIST("eventQA/hPosZ"), collision.posZ()); + histos.fill(HIST("eventQA/hCentrality"), centrality, gap); + histos.fill(HIST("eventQA/hCentralityVsTracksTotalExceptITSonly"), centrality, collision.multAllTracksTPCOnly() + collision.multAllTracksITSTPC(), gap); + histos.fill(HIST("eventQA/hCentralityVsTracksPVeta1"), centrality, collision.multNTracksPVeta1(), gap); + histos.fill(HIST("eventQA/hOccupancy"), collision.trackOccupancyInTimeRange(), gap); + histos.fill(HIST("eventQA/hCentralityVsOccupancy"), centrality, collision.trackOccupancyInTimeRange(), gap); + histos.fill(HIST("eventQA/hTracksPVeta1VsTracksGlobal"), collision.multNTracksPVeta1(), collision.multNTracksGlobal(), gap); + histos.fill(HIST("eventQA/hCentralityVsTracksGlobal"), centrality, collision.multNTracksGlobal(), gap); + histos.fill(HIST("eventQA/hPosX"), collision.posX(), gap); + histos.fill(HIST("eventQA/hPosY"), collision.posY(), gap); + histos.fill(HIST("eventQA/hPosZ"), collision.posZ(), gap); } template @@ -1033,6 +1046,12 @@ struct strangeYieldPbPb { histos.fill(HIST("hEventSelection"), 14 /* is UPC compatible */); } + if (useUPCflag && (collision.flags() < 1)) { + return false; + } else if (collision.flags() >= 1) { + histos.fill(HIST("hEventSelection"), 15 /* UPC event */); + } + return true; } @@ -1504,7 +1523,7 @@ struct strangeYieldPbPb { if (studyUPConly && (selGapSide < -0.5)) return; - fillHistogramsQA(collision); + fillHistogramsQA(collision, selGapSide); for (auto& v0 : fullV0s) { if ((v0.v0Type() != v0cuts.v0TypeSelection) && (v0cuts.v0TypeSelection > 0)) @@ -1530,7 +1549,7 @@ struct strangeYieldPbPb { if (studyUPConly && (selGapSide < -0.5)) return; - fillHistogramsQA(collision); + fillHistogramsQA(collision, selGapSide); for (auto& casc : fullCascades) { std::bitset selMap = computeBitmapCascade(casc, collision); diff --git a/PWGMM/Mult/Tasks/CMakeLists.txt b/PWGMM/Mult/Tasks/CMakeLists.txt index 4828a7ea434..9012d14f2c1 100644 --- a/PWGMM/Mult/Tasks/CMakeLists.txt +++ b/PWGMM/Mult/Tasks/CMakeLists.txt @@ -34,6 +34,11 @@ o2physics_add_dpl_workflow(dndeta-mft PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(dndeta-mft-pbpb + SOURCES dndeta-mft-pbpb.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(flatenicity-fv0 SOURCES flatenicityFV0.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx b/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx new file mode 100644 index 00000000000..a800b3a1002 --- /dev/null +++ b/PWGMM/Mult/Tasks/dndeta-mft-pbpb.cxx @@ -0,0 +1,1537 @@ +// 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 dndeta-mft-pbpb.cxx +/// \struct dndeta analysis at forward pseudorapidity +/// \brief Task for calculating dNdeta in Pb-Pb collisions using MFT detector +/// \author Gyula Bencedi +/// \since Nov 2024 +/// @note based on dndeta-mft.cxx +/// + +#include +#include +#include + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RuntimeError.h" +#include "Framework/runDataProcessing.h" + +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/MathConstants.h" + +#include "MathUtils/Utils.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" + +#include + +#include "Index.h" +#include "bestCollisionTable.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::track; +using namespace o2::aod::fwdtrack; + +AxisSpec PtAxis = {1001, -0.005, 10.005}; +AxisSpec MultAxis = {701, -0.5, 700.5, "N_{trk}"}; +AxisSpec ZAxis = {60, -30., 30.}; +AxisSpec DeltaZAxis = {61, -6.1, 6.1}; +AxisSpec DCAxyAxis = {500, -1, 50}; +AxisSpec PhiAxis = {629, 0, o2::constants::math::TwoPI, "Rad", "#phi"}; +AxisSpec EtaAxis = {20, -4., -2.}; + +struct PseudorapidityDensityMFT { + SliceCache cache; + + // Histogram registry + HistogramRegistry registry{ + "registry", + {}, + OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry QAregistry{ + "QAregistry", + {}, + OutputObjHandlingPolicy::AnalysisObject, + false, + true}; + + // analysis specific conf. + Configurable usePhiCut{"usePhiCut", false, "use azimuthal angle cut"}; + Configurable cfgPhiCut{"cfgPhiCut", 0.1f, + "Cut on azimuthal angle of MFT tracks"}; + + // track selection conf. + struct : ConfigurableGroup { + Configurable cfg_eta_min{"cfg_eta_min", -3.6f, ""}; + Configurable cfg_eta_max{"cfg_eta_max", -2.5f, ""}; + Configurable cfg_min_ncluster_mft{"cfg_min_ncluster_mft", 5, + "minimum number of MFT clusters"}; + Configurable cfg_min_pt{"cfg_min_pt", 0., + "minimum pT of the MFT tracks"}; + Configurable cfg_require_ca{ + "cfg_require_ca", false, + "Use Cellular Automaton track-finding algorithm"}; + Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 2.0f, "Cut on dcaXY"}; + } trkcuts; + + // event selection conf. + Configurable cfgCutZvtx{"cfgCutZvtx", 10.0f, "Cut on z-vtx"}; + Configurable cfgCutCent{"cfgCutCent", 80.0f, + "Cut on maximum centrality"}; + Configurable useZDiffCut{"useZvtxDiffCut", false, + "use Zvtx reco-mc diff. cut"}; + Configurable maxZvtxDiff{ + "maxZvtxDiff", 1.0f, + "max allowed Z vtx difference for reconstruced collisions (cm)"}; + Configurable requireNoCollInTimeRangeStd{ + "requireNoCollInTimeRangeStd", false, + "reject collisions corrupted by the cannibalism, with other collisions " + "within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{ + "requireNoCollInTimeRangeNarrow", false, + "reject collisions corrupted by the cannibalism, with other collisions " + "within +/- 10 microseconds"}; + ConfigurableAxis OccupancyBins{"OccupancyBins", + {VARIABLE_WIDTH, 0.0f, 250.0f, 500.0f, 750.0f, + 1000.0f, 1500.0f, 2000.0f, 3000.0f, 4500.0f, + 6000.0f, 8000.0f, 10000.0f, 50000.0f}, + "Occupancy"}; + Configurable minOccupancy{ + "minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{ + "maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + ConfigurableAxis CentBins{ + "CentBins", + {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, + ""}; + + Service pdg; + + /// @brief init function, definition of histograms + void init(InitContext&) + { + if (static_cast(doprocessDataInclusive) + + static_cast(doprocessDatawBestTracksInclusive) > + 1) { + LOGP(fatal, + "Either processDataInclusive OR " + "processDatawBestTracksInclusive should be enabled!"); + } + if (static_cast(doprocessDataCent) + + static_cast(doprocessDatawBestTracksCent) > + 1) { + LOGP(fatal, + "Either processDataCent OR processDatawBestTracksCent should " + "be enabled!"); + } + if (static_cast(doprocessMCInclusive) + + static_cast(doprocessMCwBestTracksInclusive) > + 1) { + LOGP(fatal, + "Either processMCInclusive OR processMCwBestTracksInclusive " + "should be enabled!"); + } + if (static_cast(doprocessMCCent) + + static_cast(doprocessMCwBestTracksCent) > + 1) { + LOGP(fatal, + "Either processMCCent OR processMCwBestTracksCent should be " + "enabled!"); + } + + auto hev = registry.add("hEvtSel", "hEvtSel", HistType::kTH1F, + {{10, -0.5f, +9.5f}}); + hev->GetXaxis()->SetBinLabel(1, "All collisions"); + hev->GetXaxis()->SetBinLabel(2, "Ev. sel."); + hev->GetXaxis()->SetBinLabel(3, "kIsGoodZvtxFT0vsPV"); + hev->GetXaxis()->SetBinLabel(4, "NoSameBunchPileup"); + hev->GetXaxis()->SetBinLabel(5, "Z-vtx cut"); + hev->GetXaxis()->SetBinLabel(6, "kNoCollInTimeRangeStd"); + hev->GetXaxis()->SetBinLabel(7, "kNoCollInTimeRangeNarrow"); + hev->GetXaxis()->SetBinLabel(8, "Below min occup."); + hev->GetXaxis()->SetBinLabel(9, "Above max occup."); + + auto hBcSel = registry.add("hBcSel", "hBcSel", HistType::kTH1F, + {{3, -0.5f, +2.5f}}); + hBcSel->GetXaxis()->SetBinLabel(1, "Good BCs"); + hBcSel->GetXaxis()->SetBinLabel(2, "BCs with collisions"); + hBcSel->GetXaxis()->SetBinLabel(3, "BCs with pile-up/splitting"); + + AxisSpec CentAxis = {CentBins, "Centrality", "CentralityAxis"}; + AxisSpec OccupancyAxis = {OccupancyBins, "Occupancy", "OccupancyAxis"}; + + if (doprocessDataInclusive || doprocessDatawBestTracksInclusive) { + registry.add({"Events/Selection", + ";status;events", + {HistType::kTH1F, {{2, 0.5, 2.5}}}}); + auto hstat = registry.get(HIST("Events/Selection")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "All"); + x->SetBinLabel(2, "Selected"); + + registry.add({"Events/NtrkZvtx", + "; N_{trk}; Z_{vtx} (cm);", + {HistType::kTH2F, {MultAxis, ZAxis}}}); + registry.add({"Tracks/EtaZvtx", + "; #eta; Z_{vtx} (cm);", + {HistType::kTH2F, {EtaAxis, ZAxis}}}); + registry.add({"Tracks/PhiEta", + "; #varphi; #eta;", + {HistType::kTH2F, {PhiAxis, EtaAxis}}}); + QAregistry.add({"Tracks/Chi2Eta", + "; #chi^{2}; #it{#eta};", + {HistType::kTH2F, {{600, 0, 20}, {100, -8, 8}}}}); + QAregistry.add( + {"Tracks/Chi2", "; #chi^{2};", {HistType::kTH1F, {{600, 0, 20}}}}); + QAregistry.add({"Tracks/NclustersEta", + "; nClusters; #eta;", + {HistType::kTH2F, {{7, 4, 10}, {100, -8, 8}}}}); + QAregistry.add("Events/Occupancy", "; Z_{vtx} (cm); Occupancy", + HistType::kTH2F, {ZAxis, OccupancyAxis}, false); + + if (doprocessDatawBestTracksInclusive) { + registry.add({"Events/NtrkZvtxBest", + "; N_{trk}; Z_{vtx} (cm);", + {HistType::kTH2F, {MultAxis, ZAxis}}}); + registry.add({"Tracks/EtaZvtxBest", + "; #eta; Z_{vtx} (cm);", + {HistType::kTH2F, {EtaAxis, ZAxis}}}); + registry.add({"Tracks/PhiEtaBest", + "; #varphi; #eta;", + {HistType::kTH2F, {PhiAxis, EtaAxis}}}); + QAregistry.add({"Tracks/NclustersEtaBest", + "; nClusters; #eta;", + {HistType::kTH2F, {{7, 4, 10}, {100, -8, 8}}}}); + QAregistry.add({"Tracks/DCAXYPt", + " ; p_{T} (GeV/c) ; DCA_{XY} (cm); centrality", + {HistType::kTH2F, {PtAxis, DCAxyAxis}}}); + QAregistry.add({"Tracks/DCAXY", + " ; DCA_{XY} (cm)", + {HistType::kTH1F, {DCAxyAxis}}}); + QAregistry.add({"Tracks/ReTracksEtaZvtx", + "; #eta; #it{z}_{vtx} (cm); tracks", + {HistType::kTH2F, {EtaAxis, ZAxis}}}); + QAregistry.add({"Tracks/ReTracksPhiEta", + "; #varphi; #eta; tracks", + {HistType::kTH2F, {PhiAxis, EtaAxis}}}); + QAregistry.add({"Tracks/TrackAmbDegree", + " ; N_{coll}^{comp}", + {HistType::kTH1F, {{51, -0.5, 50.5}}}}); + } + } + + if (doprocessDataCent || doprocessDatawBestTracksCent) { + registry.add({"Events/Centrality/Selection", + ";status;centrality;events", + {HistType::kTH2F, {{2, 0.5, 2.5}, CentAxis}}}); + auto hstat = registry.get(HIST("Events/Centrality/Selection")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "All"); + x->SetBinLabel(2, "Selected"); + + registry.add({"Events/Centrality/NtrkZvtx", + "; N_{trk}; Z_{vtx} (cm); centrality", + {HistType::kTH3F, {MultAxis, ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/EtaZvtx", + "; #eta; Z_{vtx} (cm); centrality", + {HistType::kTH3F, {EtaAxis, ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/PhiEta", + "; #varphi; #eta; centrality", + {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); + QAregistry.add({"Events/Centrality/hcentFT0C", + " ; cent FT0C", + {HistType::kTH1F, {{1000, 0, 100}}}, + true}); + QAregistry.add( + {"Tracks/Centrality/Chi2Eta", + "; #chi^{2}; #it{#eta}; centrality", + {HistType::kTH3F, {{600, 0, 20}, {100, -8, 8}, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/Chi2", + "; #chi^{2}; centrality", + {HistType::kTH2F, {{600, 0, 20}, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/NclustersEta", + "; nClusters; #eta; centrality", + {HistType::kTH3F, {{7, 4, 10}, {100, -8, 8}, CentAxis}}}); + QAregistry.add("Events/Centrality/Occupancy", + "; Z_{vtx} (cm); centrality; Occupancy", HistType::kTH3F, + {ZAxis, CentAxis, OccupancyAxis}, false); + QAregistry.add("Tracks/Centrality/Occupancy", "dndeta occupancy", + HistType::kTHnSparseF, + {ZAxis, CentAxis, EtaAxis, PhiAxis, OccupancyAxis}, false); + + if (doprocessDatawBestTracksCent) { + registry.add({"Events/Centrality/NtrkZvtxBest", + "; N_{trk}; Z_{vtx} (cm); centrality", + {HistType::kTH3F, {MultAxis, ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/EtaZvtxBest", + "; #eta; Z_{vtx} (cm); centrality", + {HistType::kTH3F, {EtaAxis, ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/PhiEtaBest", + "; #varphi; #eta; centrality", + {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); + QAregistry.add( + {"Tracks/Centrality/NclustersEtaBest", + "; nClusters; #eta; centrality", + {HistType::kTH3F, {{7, 4, 10}, {100, -8, 8}, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/TrackAmbDegree", + " ; N_{coll}^{comp}", + {HistType::kTH2F, {{51, -0.5, 50.5}, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/DCAXY", + " ; DCA_{XY} (cm)", + {HistType::kTH2F, {DCAxyAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/DCAXYPt", + " ; p_{T} (GeV/c) ; DCA_{XY} (cm); centrality", + {HistType::kTH3F, {PtAxis, DCAxyAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/ReTracksEtaZvtx", + "; #eta; #it{z}_{vtx} (cm); tracks", + {HistType::kTH3F, {EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/ReTracksPhiEta", + "; #varphi; #eta; tracks", + {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); + QAregistry.add("Events/Centrality/OccupancyBest", + "; Z_{vtx} (cm); centrality; Occupancy", HistType::kTH3F, + {ZAxis, CentAxis, OccupancyAxis}, false); + QAregistry.add("Tracks/Centrality/OccupancyBest", "dndeta occupancy", + HistType::kTHnSparseF, + {ZAxis, CentAxis, EtaAxis, PhiAxis, OccupancyAxis}, + false); + } + } + + if (doprocessMCInclusive || doprocessMCwBestTracksInclusive) { + registry.add({"Events/EvtEffGen", + ";status;events", + {HistType::kTH1F, {{3, 0.5, 3.5}}}}); + auto heff = registry.get(HIST("Events/EvtEffGen")); + auto* x = heff->GetXaxis(); + x->SetBinLabel(1, "All reconstructed"); + x->SetBinLabel(2, "Selected reconstructed"); + x->SetBinLabel(3, "All generated"); + + registry.add({"Events/NtrkZvtxGen_t", + "; N_{trk}; Z_{vtx} (cm);", + {HistType::kTH2F, {MultAxis, ZAxis}}}); + registry.add({"Events/NtrkZvtxGen", + "; N_{trk}; Z_{vtx} (cm);", + {HistType::kTH2F, {MultAxis, ZAxis}}}); + registry.add({"Tracks/EtaZvtxGen", + "; #eta; Z_{vtx} (cm);", + {HistType::kTH2F, {EtaAxis, ZAxis}}}); + registry.add({"Tracks/PhiEtaGen", + "; #varphi; #eta;", + {HistType::kTH2F, {PhiAxis, EtaAxis}}}); + registry.add({"Tracks/EtaZvtxGen_t", + "; #eta; Z_{vtx} (cm);", + {HistType::kTH2F, {EtaAxis, ZAxis}}}); + registry.add({"Tracks/PhiEtaGen_t", + "; #varphi; #eta;", + {HistType::kTH2F, {PhiAxis, EtaAxis}}}); + QAregistry.add({"Events/NotFoundEventZvtx", + " ; #it{z}_{vtx} (cm)", + {HistType::kTH1F, {ZAxis}}}); + QAregistry.add({"Events/ZvtxDiff", + " ; Z_{rec} - Z_{gen} (cm)", + {HistType::kTH1F, {DeltaZAxis}}}); + QAregistry.add( + {"Events/SplitMult", " ; N_{gen}", {HistType::kTH1F, {MultAxis}}}); + } + + if (doprocessMCCent || doprocessMCwBestTracksCent) { + registry.add({"Events/Centrality/EvtEffGen", + ";status;events", + {HistType::kTH2F, {{3, 0.5, 3.5}, CentAxis}}}); + auto heff = registry.get(HIST("Events/Centrality/EvtEffGen")); + auto* x = heff->GetXaxis(); + x->SetBinLabel(1, "All reconstructed"); + x->SetBinLabel(2, "Selected reconstructed"); + x->SetBinLabel(3, "All generated"); + + registry.add({"Events/Centrality/NtrkZvtxGen_t", + "; N_{trk}; Z_{vtx} (cm);", + {HistType::kTH3F, {MultAxis, ZAxis, CentAxis}}}); + registry.add({"Events/Centrality/NtrkZvtxGen", + "; N_{trk}; Z_{vtx} (cm);", + {HistType::kTH3F, {MultAxis, ZAxis, CentAxis}}}); + registry.add({"Events/Centrality/hRecCent", + "Events/Centrality/hRecCent", + {HistType::kTH1F, {CentAxis}}}); + registry.add({"Events/Centrality/hRecZvtxCent", + "Events/Centrality/hRecZvtxCent", + {HistType::kTH2F, {ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/EtaZvtxGen", + "; #eta; Z_{vtx} (cm);", + {HistType::kTH3F, {EtaAxis, ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/PhiEtaGen", + "; #varphi; #eta;", + {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/EtaZvtxGen_t", + "; #eta; Z_{vtx} (cm);", + {HistType::kTH3F, {EtaAxis, ZAxis, CentAxis}}}); + registry.add({"Tracks/Centrality/PhiEtaGen_t", + "; #varphi; #eta;", + {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); + QAregistry.add({"Events/Centrality/NotFoundEventZvtx", + " ; #it{z}_{vtx} (cm)", + {HistType::kTH2F, {ZAxis, CentAxis}}}); + QAregistry.add({"Events/Centrality/ZvtxDiff", + " ; Z_{rec} - Z_{gen} (cm)", + {HistType::kTH2F, {DeltaZAxis, CentAxis}}}); + QAregistry.add({"Events/Centrality/SplitMult", + " ; N_{gen}", + {HistType::kTH2F, {MultAxis, CentAxis}}}); + } + + if (doprocessTrkEffIdxInlusive) { + QAregistry.add( + {"Tracks/hPtPhiEtaZvtxEffGen", + "hPtPhiEtaZvtxEffGen", + {HistType::kTHnSparseF, {PtAxis, PhiAxis, EtaAxis, ZAxis}}}); + QAregistry.add( + {"Tracks/hPtPhiEtaZvtxEffRec", + "hPtPhiEtaZvtxEffRec", + {HistType::kTHnSparseF, {PtAxis, PhiAxis, EtaAxis, ZAxis}}}); + QAregistry.add({"Tracks/hPhiEtaDuplicates", + " ; p_{T} (GeV/c);", + {HistType::kTH2F, {PhiAxis, EtaAxis}}}); + QAregistry.add( + {"Tracks/hPtPhiEtaZvtxEffDuplicates", + "hPtPhiEtaZvtxEffDuplicates", + {HistType::kTHnSparseF, {PtAxis, PhiAxis, EtaAxis, ZAxis}}}); + QAregistry.add( + {"Tracks/hPtPhiEtaZvtxEffGenDuplicates", + "hPtPhiEtaZvtxEffGenDuplicates", + {HistType::kTHnSparseF, {PtAxis, PhiAxis, EtaAxis, ZAxis}}}); + QAregistry.add({"Tracks/NmftTrkPerPart", + "; #it{N}_{mft tracks per particle};", + {HistType::kTH1F, {{200, -0.5, 200.}}}}); + } + + if (doprocessTrkEffIdxCent) { + QAregistry.add({"Tracks/Centrality/hPtPhiEtaZvtxEffGen", + "hPtPhiEtaZvtxEffGen", + {HistType::kTHnSparseF, + {PtAxis, PhiAxis, EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hPtPhiEtaZvtxEffRec", + "hPtPhiEtaZvtxEffRec", + {HistType::kTHnSparseF, + {PtAxis, PhiAxis, EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hPhiEtaDuplicates", + " ; p_{T} (GeV/c);", + {HistType::kTH3F, {PhiAxis, EtaAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hPtPhiEtaZvtxEffDuplicates", + "hPtPhiEtaZvtxEffDuplicates", + {HistType::kTHnSparseF, + {PtAxis, PhiAxis, EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hPtPhiEtaZvtxEffGenDuplicates", + "hPtPhiEtaZvtxEffGenDuplicates", + {HistType::kTHnSparseF, + {PtAxis, PhiAxis, EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/NmftTrkPerPart", + "; #it{N}_{mft tracks per particle};", + {HistType::kTH2F, {{200, -0.5, 200.}, CentAxis}}}); + } + + if (doprocessTrkEffBestInclusive) { + QAregistry.add( + {"Tracks/hPtPhiEtaZvtxEffBestGen", + "hPtPhiEtaZvtxEffGen", + {HistType::kTHnSparseF, {PtAxis, PhiAxis, EtaAxis, ZAxis}}}); + QAregistry.add( + {"Tracks/hPtPhiEtaZvtxEffBestRec", + "hPtPhiEtaZvtxEffRec", + {HistType::kTHnSparseF, {PtAxis, PhiAxis, EtaAxis, ZAxis}}}); + QAregistry.add({"Tracks/hPtEffBestFakeRec", + " ; p_{T} (GeV/c);", + {HistType::kTH1F, {PtAxis}}}); + } + + if (doprocessTrkEffBestCent) { + QAregistry.add({"Tracks/Centrality/hPtPhiEtaZvtxEffBestGen", + "hPtPhiEtaZvtxEffGen", + {HistType::kTHnSparseF, + {PtAxis, PhiAxis, EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hPtPhiEtaZvtxEffBestRec", + "hPtPhiEtaZvtxEffRec", + {HistType::kTHnSparseF, + {PtAxis, PhiAxis, EtaAxis, ZAxis, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hPtEffBestFakeRec", + " ; p_{T} (GeV/c);", + {HistType::kTH2F, {PtAxis, CentAxis}}}); + } + + if (doprocessMcQAInclusive) { + QAregistry.add({"Events/hRecPerGenColls", + "; #it{N}_{reco collisions} / #it{N}_{gen collisions};", + {HistType::kTH1F, {{200, 0., 2.}}}}); + QAregistry.add({"Tracks/hNmftTrks", + "; #it{N}_{mft tracks};", + {HistType::kTH1F, {{200, -0.5, 200.}}}}); + QAregistry.add({"Tracks/hFracAmbiguousMftTrks", + "; #it{N}_{ambiguous tracks} / #it{N}_{tracks};", + {HistType::kTH1F, {{100, 0., 1.}}}}); + } + + if (doprocessMcQACent) { + QAregistry.add( + {"Events/Centrality/hRecPerGenColls", + "; #it{N}_{reco collisions} / #it{N}_{gen collisions}; centrality", + {HistType::kTH2F, {{200, 0., 2.}, CentAxis}}}); + QAregistry.add({"Tracks/Centrality/hNmftTrks", + "; #it{N}_{mft tracks}; centrality", + {HistType::kTH2F, {{200, -0.5, 200.}, CentAxis}}}); + QAregistry.add( + {"Tracks/Centrality/hFracAmbiguousMftTrks", + "; #it{N}_{ambiguous tracks} / #it{N}_{tracks}; centrality", + {HistType::kTH2F, {{100, 0., 1.}, CentAxis}}}); + } + } + + /// Filters - collision + Filter filterCollCent = nabs(aod::cent::centFT0C) < cfgCutCent; + Filter filterCollZvtx = nabs(aod::collision::posZ) < cfgCutZvtx; + Filter filterMcCollZvtx = nabs(aod::mccollision::posZ) < cfgCutZvtx; + + /// Filters - tracks + Filter filtTrkEta = (aod::fwdtrack::eta < trkcuts.cfg_eta_max) && + (aod::fwdtrack::eta > trkcuts.cfg_eta_min); + Filter filtATrackID = (aod::fwdtrack::bestCollisionId >= 0); + Filter filtATrackDCA = + (nabs(aod::fwdtrack::bestDCAXY) < trkcuts.cfg_max_dcaxy); + + /// Filters - mc particles + Filter primaries = (aod::mcparticle::flags & + (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == + (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary; + + /// Joined tables + using FullBCs = soa::Join; + using CollBCs = + soa::Join; + using Colls = soa::Join; + using Coll = Colls::iterator; + using CollsCent = soa::Join; + using CollCent = CollsCent::iterator; + using CollsGenCent = soa::Join; + using CollGenCent = CollsGenCent::iterator; + using MFTTracksLabeled = soa::Join; + + /// Filtered tables + using filtColls = soa::Filtered>; + using filtColl = + soa::Filtered>::iterator; + using filtCollsCent = + soa::Filtered>; + using filtCollCent = soa::Filtered< + soa::Join>::iterator; + using CollsGenCentSmallG = + o2::soa::SmallGroups>; + using filtCollsGenCentSmallG = + soa::SmallGroups>; + using filtCollsGenCent = + soa::Filtered>; + using filtMcGenColls = soa::Filtered; + using filtMcGenColl = soa::Filtered::iterator; + using filtMftTracks = soa::Filtered; + using filtMcMftTracks = soa::Filtered; + using filtBestTracks = soa::Filtered; + using filtBestTracksJ = + soa::Filtered>; + using filtParticles = soa::Filtered; + + template + bool isTrackSelected(const T& track) + { + if (track.eta() < trkcuts.cfg_eta_min || track.eta() > trkcuts.cfg_eta_max) + return false; + if (trkcuts.cfg_require_ca && !track.isCA()) + return false; + if (track.nClusters() < trkcuts.cfg_min_ncluster_mft) + return false; + if (track.pt() < trkcuts.cfg_min_pt) + return false; + if (usePhiCut) { + float phi = track.phi(); + o2::math_utils::bringTo02Pi(phi); + if (phi < 0.f || 2.f * M_PI < phi) { + return false; + } + if ((phi < cfgPhiCut) || + ((phi > M_PI - cfgPhiCut) && (phi < M_PI + cfgPhiCut)) || + (phi > 2. * M_PI - cfgPhiCut) || + ((phi > ((M_PI / 2. - 0.1) * M_PI) - cfgPhiCut) && + (phi < ((M_PI / 2. - 0.1) * M_PI) + cfgPhiCut))) + return false; + } + return true; + } + + template + int countTracks(T const& tracks, float z, float c, float occ) + { + auto nTrk = 0; + if (tracks.size() > 0) { + for (auto& track : tracks) { + if (fillHis) { + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/Chi2Eta"), track.chi2(), + track.eta(), c); + QAregistry.fill(HIST("Tracks/Centrality/Chi2"), track.chi2(), c); + QAregistry.fill(HIST("Tracks/Centrality/NclustersEta"), + track.nClusters(), track.eta(), c); + } else { + QAregistry.fill(HIST("Tracks/Chi2Eta"), track.chi2(), track.eta()); + QAregistry.fill(HIST("Tracks/Chi2"), track.chi2()); + QAregistry.fill(HIST("Tracks/NclustersEta"), track.nClusters(), + track.eta()); + } + } + if (!isTrackSelected(track)) { + continue; + } + if (fillHis) { + float phi = track.phi(); + o2::math_utils::bringTo02Pi(phi); + if (phi < 0.f || 2.f * M_PI < phi) { + continue; + } + if constexpr (C::template contains()) { + registry.fill(HIST("Tracks/Centrality/EtaZvtx"), track.eta(), z, c); + registry.fill(HIST("Tracks/Centrality/PhiEta"), phi, track.eta(), + c); + QAregistry.fill(HIST("Tracks/Centrality/Occupancy"), z, c, + track.eta(), track.phi(), occ); + } else { + registry.fill(HIST("Tracks/EtaZvtx"), track.eta(), z); + registry.fill(HIST("Tracks/PhiEta"), phi, track.eta()); + } + } + ++nTrk; + } + } + return nTrk; + } + + template + int countBestTracks(T const& /*tracks*/, B const& besttracks, float z, + float c, float occ) + { + auto nATrk = 0; + if (besttracks.size() > 0) { + for (auto& atrack : besttracks) { + auto itrack = atrack.template mfttrack_as(); + if (!isTrackSelected(itrack)) { + continue; + } + if (fillHis) { + float phi = itrack.phi(); + o2::math_utils::bringTo02Pi(phi); + if (phi < 0.f || 2.f * M_PI < phi) { + continue; + } + if constexpr (C::template contains()) { + registry.fill(HIST("Tracks/Centrality/EtaZvtxBest"), itrack.eta(), + z, c); + registry.fill(HIST("Tracks/Centrality/PhiEtaBest"), phi, + itrack.eta(), c); + QAregistry.fill(HIST("Tracks/Centrality/OccupancyBest"), z, c, + itrack.eta(), itrack.phi(), occ); + QAregistry.fill(HIST("Tracks/Centrality/DCAXYPt"), itrack.pt(), + atrack.bestDCAXY(), c); + QAregistry.fill(HIST("Tracks/Centrality/DCAXY"), atrack.bestDCAXY(), + c); + QAregistry.fill(HIST("Tracks/Centrality/NclustersEtaBest"), + itrack.nClusters(), itrack.eta(), c); + if (itrack.collisionId() != atrack.bestCollisionId()) { + QAregistry.fill(HIST("Tracks/Centrality/ReTracksEtaZvtx"), + itrack.eta(), z, c); + QAregistry.fill(HIST("Tracks/Centrality/ReTracksPhiEta"), phi, + itrack.eta(), c); + } + QAregistry.fill(HIST("Tracks/Centrality/TrackAmbDegree"), + atrack.ambDegree(), c); + } else { + registry.fill(HIST("Tracks/EtaZvtxBest"), itrack.eta(), z); + registry.fill(HIST("Tracks/PhiEtaBest"), phi, itrack.eta()); + QAregistry.fill(HIST("Tracks/DCAXYPt"), itrack.pt(), + atrack.bestDCAXY()); + QAregistry.fill(HIST("Tracks/DCAXY"), atrack.bestDCAXY()); + QAregistry.fill(HIST("Tracks/NclustersEtaBest"), itrack.nClusters(), + itrack.eta()); + if (itrack.collisionId() != atrack.bestCollisionId()) { + QAregistry.fill(HIST("Tracks/ReTracksEtaZvtx"), itrack.eta(), z); + QAregistry.fill(HIST("Tracks/ReTracksPhiEta"), phi, itrack.eta()); + } + QAregistry.fill(HIST("Tracks/TrackAmbDegree"), atrack.ambDegree()); + } + } + ++nATrk; + } + } + return nATrk; + } + + template + int countPart(P const& particles) + { + auto nCharged = 0; + for (auto& particle : particles) { + if (!isChrgParticle(particle.pdgCode())) { + continue; + } + nCharged++; + } + return nCharged; + } + + template + bool isGoodEvent(C const& collision) + { + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 0); + } + if (!collision.sel8()) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 1); + } + if (!collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 2); + } + if (!collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 3); + } + if (std::abs(collision.posZ()) >= cfgCutZvtx) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 4); + } + if (requireNoCollInTimeRangeStd && + !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 5); + } + if (requireNoCollInTimeRangeNarrow && + !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 6); + } + if (minOccupancy > 0 && + collision.trackOccupancyInTimeRange() < minOccupancy) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 7); + } + if (maxOccupancy > 0 && + collision.trackOccupancyInTimeRange() > maxOccupancy) { + return false; + } + if constexpr (fillHis) { + registry.fill(HIST("hEvtSel"), 8); + } + return true; + } + + /// @brief Selection of charged particles + /// @return true: charged; false: not charged + bool isChrgParticle(int code) + { + auto p = pdg->GetParticle(code); + auto charge = 0.; + if (p != nullptr) { + charge = p->Charge(); + } + return std::abs(charge) >= 3.; + } + + template + void fillHist_MC(P const& particles, float cent, float zvtx, + bool const atLeastOne) + { + for (auto& particle : particles) { + if (!isChrgParticle(particle.pdgCode())) { + continue; + } + + float phi = particle.phi(); + o2::math_utils::bringTo02Pi(phi); + if (phi < 0.f || 2.f * M_PI < phi) { + continue; + } + if constexpr (isCent) { + registry.fill(HIST("Tracks/Centrality/EtaZvtxGen_t"), particle.eta(), + zvtx, cent); + registry.fill(HIST("Tracks/Centrality/PhiEtaGen_t"), phi, + particle.eta(), cent); + } else { + registry.fill(HIST("Tracks/EtaZvtxGen_t"), particle.eta(), zvtx); + registry.fill(HIST("Tracks/PhiEtaGen_t"), phi, particle.eta()); + } + + if (atLeastOne) { + float phi = particle.phi(); + o2::math_utils::bringTo02Pi(phi); + if (phi < 0.f || 2.f * M_PI < phi) { + continue; + } + if constexpr (isCent) { + registry.fill(HIST("Tracks/Centrality/EtaZvtxGen"), particle.eta(), + zvtx, cent); + registry.fill(HIST("Tracks/Centrality/PhiEtaGen"), phi, + particle.eta(), cent); + } else { + registry.fill(HIST("Tracks/EtaZvtxGen"), particle.eta(), zvtx); + registry.fill(HIST("Tracks/PhiEtaGen"), phi, particle.eta()); + } + } + } + } + + /// @brief process fnc. for general event statistics + void processTagging(FullBCs const& bcs, CollsCent const& collisions) + { + std::vector::iterator> cols; + for (auto& bc : bcs) { + if ((bc.selection_bit(aod::evsel::kIsBBT0A) && + bc.selection_bit(aod::evsel::kIsBBT0C)) != 0) { + registry.fill(HIST("hBcSel"), 0); + cols.clear(); + for (auto& collision : collisions) { + if (collision.has_foundBC()) { + if (collision.foundBCId() == bc.globalIndex()) { + cols.emplace_back(collision); + } + } else if (collision.bcId() == bc.globalIndex()) { + cols.emplace_back(collision); + } + } + LOGP(debug, "BC {} has {} collisions", bc.globalBC(), cols.size()); + if (!cols.empty()) { + registry.fill(HIST("hBcSel"), 1); + if (cols.size() > 1) { + registry.fill(HIST("hBcSel"), 2); + } + } + } + } + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processTagging, + "Collect event sample stats", true); + + template + void processData(typename C::iterator const& collision, + filtMftTracks const& tracks) + { + float c = -1; + if constexpr (C::template contains()) { + c = collision.centFT0C(); + registry.fill(HIST("Events/Centrality/Selection"), 1., c); + } else { + registry.fill(HIST("Events/Selection"), 1.); + } + if (!isGoodEvent(collision)) { + return; + } + auto z = collision.posZ(); + auto occ = collision.trackOccupancyInTimeRange(); + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/Selection"), 2., c); + QAregistry.fill(HIST("Events/Centrality/Occupancy"), z, c, occ); + QAregistry.fill(HIST("Events/Centrality/hcentFT0C"), c); + } else { + registry.fill(HIST("Events/Selection"), 2.); + } + + auto nTrk = countTracks( + tracks, z, c, occ); //!@note here we obtain eta-z and phi-eta + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/NtrkZvtx"), nTrk, z, c); + } else { + registry.fill(HIST("Events/NtrkZvtx"), nTrk, z); + } + } + + template + void processDatawBestTracks( + typename C::iterator const& collision, filtMftTracks const& tracks, + soa::SmallGroups const& besttracks) + { + float c = -1; + if constexpr (C::template contains()) { + c = collision.centFT0C(); + registry.fill(HIST("Events/Centrality/Selection"), 1., c); + } else { + registry.fill(HIST("Events/Selection"), 1.); + } + if (!isGoodEvent(collision)) { + return; + } + auto z = collision.posZ(); + auto occ = collision.trackOccupancyInTimeRange(); + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/Selection"), 2., c); + QAregistry.fill(HIST("Events/Centrality/OccupancyBest"), z, c, occ); + } else { + registry.fill(HIST("Events/Selection"), 2.); + } + + auto nBestTrks = + countBestTracks(tracks, besttracks, z, c, + occ); //!@note here we obtain eta-z and phi-eta + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/NtrkZvtxBest"), nBestTrks, z, c); + } else { + registry.fill(HIST("Events/NtrkZvtxBest"), nBestTrks, z); + } + } + + /// @brief process fnc. to run on DATA and REC MC w/o centrality selection + void processDataInclusive(filtColls::iterator const& collision, + filtMftTracks const& tracks) + { + processData(collision, tracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processDataInclusive, "Count tracks", + false); + + /// @brief process fnc. to run on DATA and REC MC w/ FT0C centrality selection + void processDataCent(filtCollsCent::iterator const& collision, + filtMftTracks const& tracks) + { + processData(collision, tracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processDataCent, + "Count tracks in FT0C bins", false); + + /// @brief process fnc. to run on DATA and REC MC based on BestCollisionsFwd + /// table w/o centrality selection + void processDatawBestTracksInclusive( + filtColls::iterator const& collision, filtMftTracks const& tracks, + soa::SmallGroups const& besttracks) + { + processDatawBestTracks(collision, tracks, besttracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processDatawBestTracksInclusive, + "Count tracks based on BestCollisionsFwd table", false); + + /// @brief process fnc. to run on DATA and REC MC based on BestCollisionsFwd + /// table w/ FT0C centrality selection + void processDatawBestTracksCent( + filtCollsCent::iterator const& collision, filtMftTracks const& tracks, + soa::SmallGroups const& besttracks) + { + processDatawBestTracks(collision, tracks, besttracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processDatawBestTracksCent, + "Count tracks in FT0C bins based on BestCollisionsFwd table", + false); + + Preslice perCol = o2::aod::fwdtrack::collisionId; + Partition mcSample = nabs(aod::mcparticle::eta) < 1.0f; + + /// @brief process template function to run on MC truth + /// @param cols subscribe to the collisions + /// @param parts subscribe to filtered MC particle table + template + void processMC( + typename MC::iterator const& mcCollision, + soa::SmallGroups> const& collisions, + filtParticles const& particles, filtMcMftTracks const& tracks) + { + float c_gen = -1; + bool atLeastOne = false; + int moreThanOne = 0; + for (auto& collision : collisions) { + float c_rec = -1; + if constexpr (C::template contains()) { + c_rec = collision.centFT0C(); + registry.fill(HIST("Events/Centrality/EvtEffGen"), 1., c_rec); + } else { + registry.fill(HIST("Events/EvtEffGen"), 1.); + } + + if (isGoodEvent(collision)) { + if constexpr (C::template contains()) { + if (!atLeastOne) { + c_gen = c_rec; + } + } + atLeastOne = true; + ++moreThanOne; + auto z = collision.posZ(); + + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/EvtEffGen"), 2., c_rec); + registry.fill(HIST("Events/Centrality/hRecCent"), c_rec); + registry.fill(HIST("Events/Centrality/hRecZvtxCent"), z, c_rec); + } else { + registry.fill(HIST("Events/EvtEffGen"), 2.); + } + + auto perCollisionSample = + tracks.sliceBy(perCol, collision.globalIndex()); + auto nTrkRec = + countTracks(perCollisionSample, z, c_rec, + collision.trackOccupancyInTimeRange()); + + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Events/Centrality/ZvtxDiff"), + collision.posZ() - mcCollision.posZ(), c_rec); + } else { + QAregistry.fill(HIST("Events/ZvtxDiff"), + collision.posZ() - mcCollision.posZ()); + } + + if (useZDiffCut) { + if (std::abs(collision.posZ() - mcCollision.posZ()) > maxZvtxDiff) { + continue; + } + } + + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/NtrkZvtxGen"), nTrkRec, + collision.posZ(), c_rec); + } else { + registry.fill(HIST("Events/NtrkZvtxGen"), nTrkRec, collision.posZ()); + } + } + } + + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/EvtEffGen"), 3., c_gen); + } else { + registry.fill(HIST("Events/EvtEffGen"), 3.); + } + + auto perCollMCsample = mcSample->sliceByCached( + aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); + auto Nchrg = countPart(perCollMCsample); + if (moreThanOne > 1) { + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Events/Centrality/SplitMult"), Nchrg, c_gen); + } else { + QAregistry.fill(HIST("Events/SplitMult"), Nchrg); + } + } + + auto zvtxMC = mcCollision.posZ(); + auto nCharged = countPart(particles); + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/NtrkZvtxGen_t"), nCharged, zvtxMC, + c_gen); + } else { + registry.fill(HIST("Events/NtrkZvtxGen_t"), nCharged, zvtxMC); + } + + fillHist_MC()>(particles, c_gen, + zvtxMC, atLeastOne); + + if (collisions.size() == 0) { + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Events/Centrality/NotFoundEventZvtx"), + mcCollision.posZ(), c_gen); + } else { + QAregistry.fill(HIST("Events/NotFoundEventZvtx"), mcCollision.posZ()); + } + } + } + + /// @brief process fnc. to run on MC w/o centrality selection + void processMCInclusive( + filtMcGenColls::iterator const& mccollision, + soa::SmallGroups> const& collisions, + filtParticles const& particles, filtMcMftTracks const& tracks) + { + processMC(mccollision, collisions, particles, + tracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processMCInclusive, + "Count MC particles", false); + + /// @brief process fnc. to run on MC w FT0C centrality selection + void processMCCent( + filtMcGenColls::iterator const& mccollision, + soa::SmallGroups> const& collisions, + filtParticles const& particles, filtMcMftTracks const& tracks) + { + processMC(mccollision, collisions, particles, + tracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processMCCent, + "Count MC particles in FT0C bins", false); + + PresliceUnsorted perColU = + aod::fwdtrack::bestCollisionId; + + /// @brief process template function to run on MC truth using + /// aod::BestCollisionsFwd tracks + template + void processMCwBestTracks( + typename MC::iterator const& mcCollision, + soa::SmallGroups> const& collisions, + filtParticles const& particles, filtMcMftTracks const& tracks, + filtBestTracks const& besttracks) + { + float c_gen = -1; + bool atLeastOne = false; + int moreThanOne = 0; + for (auto& collision : collisions) { + float c_rec = -1; + if constexpr (C::template contains()) { + c_rec = collision.centFT0C(); + registry.fill(HIST("Events/Centrality/EvtEffGen"), 1., c_rec); + } else { + registry.fill(HIST("Events/EvtEffGen"), 1.); + } + + if (isGoodEvent(collision)) { + if constexpr (C::template contains()) { + if (!atLeastOne) { + c_gen = c_rec; + } + } + atLeastOne = true; + ++moreThanOne; + auto z = collision.posZ(); + + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/EvtEffGen"), 2., c_rec); + } else { + registry.fill(HIST("Events/EvtEffGen"), 2.); + } + + auto perCollisionSample = + tracks.sliceBy(perCol, collision.globalIndex()); + auto perCollisionASample = + besttracks.sliceBy(perColU, collision.globalIndex()); + auto nTrkRec = countBestTracks( + perCollisionSample, perCollisionASample, z, c_rec, + collision.trackOccupancyInTimeRange()); + + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/NtrkZvtxGen"), nTrkRec, z, + c_rec); + } else { + registry.fill(HIST("Events/NtrkZvtxGen"), nTrkRec, z); + } + } + } + + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/EvtEffGen"), 3., c_gen); + } else { + registry.fill(HIST("Events/EvtEffGen"), 3.); + } + + auto zvtxMC = mcCollision.posZ(); + auto nCharged = countPart(particles); + if constexpr (C::template contains()) { + registry.fill(HIST("Events/Centrality/NtrkZvtxGen_t"), nCharged, zvtxMC, + c_gen); + } else { + registry.fill(HIST("Events/NtrkZvtxGen_t"), nCharged, zvtxMC); + } + + fillHist_MC()>(particles, c_gen, + zvtxMC, atLeastOne); + + if (collisions.size() == 0) { + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Events/Centrality/NotFoundEventZvtx"), + mcCollision.posZ(), c_gen); + } else { + QAregistry.fill(HIST("Events/NotFoundEventZvtx"), mcCollision.posZ()); + } + } + } + + /// @brief process fnc. to run on MC (inclusive, using aod::BestCollisionsFwd + /// tracks) + void processMCwBestTracksInclusive( + filtMcGenColls::iterator const& mccollision, + soa::SmallGroups> const& collisions, + filtParticles const& particles, filtMcMftTracks const& tracks, + // aod::BestCollisionsFwd const + // &besttracks + filtBestTracks const& besttracks) + { + processMCwBestTracks( + mccollision, collisions, particles, tracks, besttracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processMCwBestTracksInclusive, + "Count MC particles using aod::BestCollisionsFwd", false); + + /// @brief process fnc. to run on MC (FT0C centrality, using + /// aod::BestCollisionsFwd tracks) + void processMCwBestTracksCent( + filtMcGenColls::iterator const& mccollision, + soa::SmallGroups> const& collisions, + filtParticles const& particles, filtMcMftTracks const& tracks, + filtBestTracks const& besttracks) + { + processMCwBestTracks( + mccollision, collisions, particles, tracks, besttracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processMCwBestTracksCent, + "Count MC particles in FT0C bins using aod::BestCollisionsFwd", + false); + + using ParticlesI = soa::Join; + Partition primariesI = + ((aod::mcparticle::flags & + (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == + (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary); + + /// @brief process template function to calculate tracking efficiency (indexed + /// as particle-to-MFT-tracks) + template + void processTrkEffIdx( + typename soa::Filtered> const& collisions, + MC const& /*mccollisions*/, ParticlesI const& /*particles*/, + MFTTracksLabeled const& tracks) + { + for (auto& collision : collisions) { + if (!isGoodEvent(collision)) { + continue; + } + if (!collision.has_mcCollision()) { + continue; + } + + float c_rec = -1; + if constexpr (C::template contains()) { + c_rec = collision.centFT0C(); + } + + auto mcCollision = collision.mcCollision(); + auto particlesPerCol = primariesI->sliceByCached( + aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); + particlesPerCol.bindExternalIndices(&tracks); + + for (auto& particle : particlesPerCol) { + if (!isChrgParticle(particle.pdgCode())) { + continue; + } + // MC gen + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/hPtPhiEtaZvtxEffGen"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ(), c_rec); + } else { + QAregistry.fill(HIST("Tracks/hPtPhiEtaZvtxEffGen"), particle.pt(), + particle.phi(), particle.eta(), mcCollision.posZ()); + } + // MC rec + if (particle.has_mfttracks()) { + auto iscounted = false; + auto ncnt = 0; + auto relatedTracks = + particle.template mfttracks_as(); + for (auto& track : relatedTracks) { + if (!isTrackSelected(track)) { + continue; + } + ++ncnt; + if constexpr (C::template contains()) { + if (!iscounted) { // primaries + QAregistry.fill(HIST("Tracks/Centrality/hPtPhiEtaZvtxEffRec"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ(), c_rec); + iscounted = true; + } + if (ncnt > 1) { // duplicates + QAregistry.fill(HIST("Tracks/Centrality/hPhiEtaDuplicates"), + track.phi(), track.eta(), c_rec); + QAregistry.fill( + HIST("Tracks/Centrality/hPtPhiEtaZvtxEffDuplicates"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ(), c_rec); + } + } else { + if (!iscounted) { // primaries + QAregistry.fill(HIST("Tracks/hPtPhiEtaZvtxEffRec"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ()); + iscounted = true; + } + if (ncnt > 1) { // duplicates + QAregistry.fill(HIST("Tracks/hPhiEtaDuplicates"), track.phi(), + track.eta()); + QAregistry.fill(HIST("Tracks/hPtPhiEtaZvtxEffDuplicates"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ()); + } + } + } + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/NmftTrkPerPart"), ncnt, + c_rec); + } else { + QAregistry.fill(HIST("Tracks/NmftTrkPerPart"), ncnt); + } + if (relatedTracks.size() > 1) { + if constexpr (C::template contains()) { + QAregistry.fill( + HIST("Tracks/Centrality/hPtPhiEtaZvtxEffGenDuplicates"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ(), c_rec); + } else { + QAregistry.fill(HIST("Tracks/hPtPhiEtaZvtxEffGenDuplicates"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ()); + } + } + } + } + } + } + + /// @brief process function to calculate tracking efficiency (inclusive, + /// indexed) + void processTrkEffIdxInlusive( + soa::Filtered> const& collisions, + aod::McCollisions const& mccollisions, ParticlesI const& particles, + MFTTracksLabeled const& tracks) + { + processTrkEffIdx(collisions, mccollisions, + particles, tracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processTrkEffIdxInlusive, + "Process tracking efficiency (inclusive)", false); + + /// @brief process function to calculate tracking efficiency (FT0 bins, + /// indexed) + void processTrkEffIdxCent( + soa::Filtered> const& collisions, + aod::McCollisions const& mccollisions, ParticlesI const& particles, + MFTTracksLabeled const& tracks) + { + processTrkEffIdx(collisions, mccollisions, + particles, tracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processTrkEffIdxCent, + "Process tracking efficiency in FT0 bins", false); + + /// @brief process function to calculate tracking efficiency (indexed) based + /// on BestCollisionsFwd in FT0C bins + template + void processTrkEffBest( + typename soa::Filtered< + soa::Join>::iterator const& collision, + MC const& /*mccollisions*/, filtParticles const& particles, + filtMcMftTracks const& /*tracks*/, + soa::SmallGroups const& besttracks) + { + if (!isGoodEvent(collision)) { + return; + } + if (!collision.has_mcCollision()) { + return; + } + + float c_rec = -1; + if constexpr (C::template contains()) { + c_rec = collision.centFT0C(); + } + + auto mcCollision = collision.mcCollision(); + auto particlesPerCol = particles.sliceByCached( + aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); + for (auto& particle : particlesPerCol) { + if (!isChrgParticle(particle.pdgCode())) { + continue; + } + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/hPtPhiEtaZvtxEffBestGen"), + particle.pt(), particle.phi(), particle.eta(), + mcCollision.posZ(), c_rec); + } else { + QAregistry.fill(HIST("Tracks/hPtPhiEtaZvtxEffBestGen"), particle.pt(), + particle.phi(), particle.eta(), mcCollision.posZ()); + } + } + + for (auto const& track : besttracks) { + auto itrack = track.mfttrack_as(); + if (!isTrackSelected(itrack)) { + continue; + } + if (itrack.has_mcParticle()) { + auto particle = itrack.mcParticle_as(); + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/hPtPhiEtaZvtxEffBestRec"), + particle.pt(), itrack.phi(), itrack.eta(), + mcCollision.posZ(), c_rec); + } else { + QAregistry.fill(HIST("Tracks/hPtPhiEtaZvtxEffBestRec"), particle.pt(), + itrack.phi(), itrack.eta(), mcCollision.posZ()); + } + } else { + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/hPtEffBestFakeRec"), + itrack.pt(), c_rec); + } else { + QAregistry.fill(HIST("Tracks/hPtEffBestFakeRec"), itrack.pt()); + } + } + } + } + + /// @brief process function to calculate tracking efficiency (inclusive, based + /// on BestCollisionsFwd) + void processTrkEffBestInclusive( + soa::Filtered>::iterator const& collision, + aod::McCollisions const& mccollisions, filtParticles const& particles, + filtMcMftTracks const& tracks, + soa::SmallGroups const& besttracks) + { + processTrkEffBest(collision, mccollisions, + particles, tracks, besttracks); + } + + PROCESS_SWITCH( + PseudorapidityDensityMFT, processTrkEffBestInclusive, + "Process tracking efficiency (inclusive, based on BestCollisionsFwd)", + false); + + /// @brief process function to calculate tracking efficiency (in FT0 bins, + /// based on BestCollisionsFwd) + void processTrkEffBestCent( + soa::Filtered>:: + iterator const& collision, + aod::McCollisions const& mccollisions, filtParticles const& particles, + filtMcMftTracks const& tracks, + soa::SmallGroups const& besttracks) + { + processTrkEffBest( + collision, mccollisions, particles, tracks, besttracks); + } + + PROCESS_SWITCH( + PseudorapidityDensityMFT, processTrkEffBestCent, + "Process tracking efficiency (in FT0 bins, based on BestCollisionsFwd)", + false); + + Preslice filtTrkperCol = o2::aod::fwdtrack::collisionId; + + /// @brief process template function for MC QA checks + template + void processMcQA( + typename soa::SmallGroups> const& collisions, + filtMcGenColls const& mcCollisions, filtParticles const& /*particles*/, + MFTTracksLabeled const& tracks, aod::AmbiguousMFTTracks const& atracks) + { + for (const auto& collision : collisions) { + float c_rec = -1; + if constexpr (C::template contains()) { + c_rec = collision.centFT0C(); + QAregistry.fill(HIST("Events/Centrality/hRecPerGenColls"), + static_cast(collisions.size()) / mcCollisions.size(), c_rec); + } else { + QAregistry.fill(HIST("Events/hRecPerGenColls"), + static_cast(collisions.size()) / mcCollisions.size()); + } + + if (!isGoodEvent(collision)) { + return; + } + + auto trkPerColl = tracks.sliceBy(filtTrkperCol, collision.globalIndex()); + uint Ntracks{0u}, Natracks{0u}; + for (const auto& track : trkPerColl) { + Ntracks++; + for (const auto& atrack : atracks) { + if (atrack.mfttrackId() == track.globalIndex()) { + Natracks++; + break; + } + } + } + if constexpr (C::template contains()) { + QAregistry.fill(HIST("Tracks/Centrality/hNmftTrks"), Ntracks, c_rec); + QAregistry.fill(HIST("Tracks/Centrality/hFracAmbiguousMftTrks"), + static_cast(Natracks) / Ntracks, c_rec); + } else { + QAregistry.fill(HIST("Tracks/hNmftTrks"), Ntracks); + QAregistry.fill(HIST("Tracks/hFracAmbiguousMftTrks"), + static_cast(Natracks) / Ntracks); + } + } + } + + /// @brief process function for QA checks (inclusive) + void processMcQAInclusive( + soa::SmallGroups> const& collisions, + filtMcGenColls const& mcCollisions, filtParticles const& particles, + MFTTracksLabeled const& tracks, aod::AmbiguousMFTTracks const& atracks) + { + processMcQA(collisions, mcCollisions, particles, tracks, + atracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processMcQAInclusive, + "Process MC QA checks (inclusive)", false); + + /// @brief process function for QA checks (in FT0 bins) + void processMcQACent( + soa::SmallGroups> const& collisions, + filtMcGenColls const& mcCollisions, filtParticles const& particles, + MFTTracksLabeled const& tracks, aod::AmbiguousMFTTracks const& atracks) + { + processMcQA(collisions, mcCollisions, particles, tracks, + atracks); + } + + PROCESS_SWITCH(PseudorapidityDensityMFT, processMcQACent, + "Process MC QA checks (in FT0 bins)", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGUD/TableProducer/DGCandProducer.cxx b/PWGUD/TableProducer/DGCandProducer.cxx index 855b60b6e86..027cfd376ee 100644 --- a/PWGUD/TableProducer/DGCandProducer.cxx +++ b/PWGUD/TableProducer/DGCandProducer.cxx @@ -11,6 +11,7 @@ // // \brief Saves relevant information of DG candidates // \author Paul Buehler, paul.buehler@oeaw.ac.at + #include #include #include @@ -377,7 +378,8 @@ struct McDGCandProducer { void updateUDMcCollisions(TMcCollision const& mccol) { // save mccol - outputMcCollisions(mccol.bcId(), + auto bc = mccol.template bc_as(); + outputMcCollisions(bc.globalBC(), mccol.generatorsID(), mccol.posX(), mccol.posY(), diff --git a/PWGUD/TableProducer/UPCCandidateProducer.cxx b/PWGUD/TableProducer/UPCCandidateProducer.cxx index 6443f67fa45..5eba6e0c2ef 100644 --- a/PWGUD/TableProducer/UPCCandidateProducer.cxx +++ b/PWGUD/TableProducer/UPCCandidateProducer.cxx @@ -1610,7 +1610,7 @@ struct UpcCandProducer { if (nMFTs > fNFwdProngs) // too many tracks continue; std::vector trkCandIDs{}; - const auto& midTrackIDs = midIt->second; + const auto& midTrackIDs = midIt->second; // to retrieve corresponding MCH-MID tracks if (nMFTs == fNFwdProngs) { for (auto iMft : fwdTrackIDs) { auto trk = fwdTracks.iteratorAt(iMft); @@ -1897,13 +1897,35 @@ struct UpcCandProducer { (o2::aod::McFwdTrackLabels*)nullptr); } + void processForwardGlobalMC(ForwardTracks const& fwdTracks, + o2::aod::FwdTrkCls const& fwdTrkClusters, + o2::aod::AmbiguousFwdTracks const& ambFwdTracks, + BCsWithBcSels 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) + { + fDoMC = true; + skimMCInfo(mcCollisions, mcParticles, bcs); + createCandidatesFwdGlobal(fwdTracks, fwdTrkClusters, ambFwdTracks, + bcs, collisions, + ft0s, fdds, fv0as, zdcs, + &mcFwdTrackLabels); + fNewPartIDs.clear(); + } + PROCESS_SWITCH(UpcCandProducer, processSemiFwd, "Produce candidates in semiforward/forward region", false); PROCESS_SWITCH(UpcCandProducer, processCentral, "Produce candidates in central region", false); PROCESS_SWITCH(UpcCandProducer, processSemiFwdMC, "Produce candidates in semiforward/forward region with MC information", false); PROCESS_SWITCH(UpcCandProducer, processCentralMC, "Produce candidates in central region with MC information", false); PROCESS_SWITCH(UpcCandProducer, processForward, "Produce candidates in forward region", false); PROCESS_SWITCH(UpcCandProducer, processForwardGlobal, "Produce candidates in forward region with MFT", true); - PROCESS_SWITCH(UpcCandProducer, processForwardMC, "Produce caniddates in forward region with MC information", false); + PROCESS_SWITCH(UpcCandProducer, processForwardMC, "Produce candidates in forward region with MC information", false); + PROCESS_SWITCH(UpcCandProducer, processForwardGlobalMC, "Produce candidates in forward region with MFT and MC information", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/Tutorials/ML/applyMlSelection.cxx b/Tutorials/ML/applyMlSelection.cxx index bf2e69fc5ce..dcbfb0f80e9 100644 --- a/Tutorials/ML/applyMlSelection.cxx +++ b/Tutorials/ML/applyMlSelection.cxx @@ -39,7 +39,7 @@ struct applyMlSelection { Configurable> binsPtMl{"binsPtMl", std::vector{1., 36.}, "pT bin limits for ML application"}; Configurable> cutDirMl{"cutDirMl", std::vector{cuts_ml::CutSmaller, cuts_ml::CutNot, cuts_ml::CutNot}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsMl{"cutsMl", {defaultCutsMl[0], 1, 3, {"pT bin 0"}, {"score prompt", "score non-prompt", "score bkg"}}, "ML selections per pT bin"}; - Configurable nClassesMl{"nClassesMl", (int8_t)3, "Number of classes in ML model"}; + Configurable nClassesMl{"nClassesMl", 3, "Number of classes in ML model"}; // Model file names Configurable> onnxFileNames{"onnxFileNames", std::vector{"model_onnx.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; // Bonus: CCDB configuration (needed for ML application on the GRID) diff --git a/dependencies/O2PhysicsCompileFlags.cmake b/dependencies/O2PhysicsCompileFlags.cmake index 50967b17ea6..02312bdf601 100644 --- a/dependencies/O2PhysicsCompileFlags.cmake +++ b/dependencies/O2PhysicsCompileFlags.cmake @@ -81,11 +81,11 @@ IF (NOT CMAKE_BUILD_TYPE) ENDIF (NOT CMAKE_BUILD_TYPE) IF(ENABLE_CASSERT) #For the CI, we want to have assertions enabled - set(CMAKE_CXX_FLAGS_RELEASE "-O2") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") + set(CMAKE_CXX_FLAGS_RELEASE "-O2 -pipe") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -pipe") ELSE() - set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -pipe") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG -pipe") if (CMAKE_BUILD_TYPE STREQUAL "RELEASE" OR CMAKE_BUILD_TYPE STREQUAL "RELWITHDEBINFO") set(FAIR_MIN_SEVERITY "info") endif()