From 954ca4be1fa85580d060359ab119a1167a9a2948 Mon Sep 17 00:00:00 2001 From: ariedel-cern Date: Fri, 15 Jul 2022 15:35:48 +0200 Subject: [PATCH 1/6] Feat: add skeleton for Task multiparticle-correlations-ar in PWGCF/MultiparticleCorrelations --- .../Tasks/CMakeLists.txt | 5 + .../Tasks/multiparticle-correlations-ar.cxx | 388 ++++++++++++++++++ 2 files changed, 393 insertions(+) create mode 100644 PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx diff --git a/PWGCF/MultiparticleCorrelations/Tasks/CMakeLists.txt b/PWGCF/MultiparticleCorrelations/Tasks/CMakeLists.txt index 89e39cc12cd..397e25796c1 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/CMakeLists.txt +++ b/PWGCF/MultiparticleCorrelations/Tasks/CMakeLists.txt @@ -13,3 +13,8 @@ o2physics_add_dpl_workflow(multiparticle-correlations-ab SOURCES multiparticle-correlations-ab.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(multiparticle-correlations-ar + SOURCES multiparticle-correlations-ar.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx new file mode 100644 index 00000000000..b7d050efa71 --- /dev/null +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -0,0 +1,388 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file multiparticle-correlations-ar.cxx +/// \brief multiparticle-correlations-ar - Task belonging to Anton Riedel for computing multiparticle correlations +/// \author Anton Riedel, TU München, anton.riedel@tum.de + +#include +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +using namespace o2; +using namespace o2::framework; + +namespace MultiParticleCorrelationsARTaskGlobalConfig +{ +// setup for event variables +enum EventVariable { + kVX, + kVY, + kVZ, + kVABS, + kCEN, + kMULQ, + kMULW, + kMULNC, + kMULTPC, + kLAST_EventVariable +}; +static constexpr std::string_view EventVariableNames[kLAST_EventVariable] = {"VertexX", + "VertexY", + "VertexZ", + "VertexAbs", + "Centrality", + "MultiplicityQvector", + "MultiplicityWeights", + "MultiplicityNumContrib", + "MultiplicityTPC"}; +// setup for track variables +enum TrackVariable { + kPT, + kPHI, + kETA, + kCHARGE, + kDCAZ, + kDCAXY, + kTPCCLUSTERS, + kTPCCROSSEDROWS, + kTPCCHI2, + kITSCLUSTERS, + kLAST_TrackVariable +}; +static constexpr std::string_view TrackVariableNames[kLAST_TrackVariable] = {"Pt", + "Phi", + "Eta", + "Charge", + "DCAZ", + "DCAXY", + "TPCClusters", + "TPCCrossedRows", + "TPCChi2", + "ITSClusters"}; +// prefixes +static constexpr std::string_view ECrecoBefore = std::string_view("reco/EventControl/before/RB_"); +static constexpr std::string_view ECrecoAfter = std::string_view("reco/EventControl/after/RA_"); +static constexpr std::string_view ECsimBefore = std::string_view("sim/EventControl/before/SB_"); +static constexpr std::string_view ECsimAfter = std::string_view("sim/EventControl/after/SA_"); +static constexpr std::string_view TCrecoBefore = std::string_view("reco/TrackControl/before/RB_"); +static constexpr std::string_view TCrecoAfter = std::string_view("reco/TrackControl/after/RA_"); +static constexpr std::string_view TCsimBefore = std::string_view("sim/TrackControl/before/SB_"); +static constexpr std::string_view TCsimAfter = std::string_view("sim/TrackControl/after/SA_"); + +std::string info = std::string(": Hist bins, Hist lower edge, Hist upper edge, lower cut, upper cut, cut ON(1)/OFF(-1)"); + +}; // namespace MultiParticleCorrelationsARTaskGlobalConfig + +namespace AR = MultiParticleCorrelationsARTaskGlobalConfig; + +struct MultiParticleCorrelationsARTask { + + // configurables + // for event variables + Configurable> cfgVX = {std::string(AR::EventVariableNames[AR::kVX]), + {400., -2., 2., -1., 1., 1.}, + std::string("Vertex X") + AR::info}; + Configurable> cfgVY = {std::string(AR::EventVariableNames[AR::kVY]), + {400., -2., 2., -1., 1., 1.}, + std::string("Vertex Y") + AR::info}; + Configurable> cfgVZ = {std::string(AR::EventVariableNames[AR::kVZ]), + {2400., -12., 12., -10., 10., 1.}, + std::string("Vertex Z") + AR::info}; + Configurable> cfgVABS = {std::string(AR::EventVariableNames[AR::kVABS]), + {150., 0., 15, 1.e-6, 15., 1.}, + std::string("Vertex distance from origin") + AR::info}; + Configurable> cfgCEN = {std::string(AR::EventVariableNames[AR::kCEN]), + {120., 0., 120., 0., 80., 1.}, + std::string("Centrality") + AR::info}; + Configurable> cfgMULQ = {std::string(AR::EventVariableNames[AR::kMULQ]), + {3000., 0., 3000., 10., 3000., 1.}, + std::string("Multiplicity (QVector)") + AR::info}; + Configurable> cfgMULW = {std::string(AR::EventVariableNames[AR::kMULW]), + {3000., 0., 3000., 10., 3000., 1.}, + std::string("Multiplicity (Weights)") + AR::info}; + Configurable> cfgMULNC = {std::string(AR::EventVariableNames[AR::kMULNC]), + {3000., 0., 3000., 10., 3000., 1.}, + std::string("Multiplicity (NumContrib)") + AR::info}; + Configurable> cfgMULTPC = {std::string(AR::EventVariableNames[AR::kMULTPC]), + {3000., 0., 3000., 12., 3000., 1.}, + std::string("Multiplicity (TPC)") + AR::info}; + std::vector>> cfgEvent = {cfgVX, cfgVY, cfgVZ, cfgVABS, cfgCEN, cfgMULQ, cfgMULW, cfgMULNC, cfgMULTPC}; + + // for track variables + Configurable> cfgPT = {std::string(AR::TrackVariableNames[AR::kPT]), + {600., 0., 6., 0.2, 5., 1.}, + std::string("pt") + AR::info}; + Configurable> cfgPHI = {std::string(AR::TrackVariableNames[AR::kPHI]), + {360., 0., 2. * M_PI, 0., 2. * M_PI, 1.}, + std::string("phi") + AR::info}; + Configurable> cfgETA = {std::string(AR::TrackVariableNames[AR::kETA]), + {1000., -1., 1., -0.8, 0.8, 1.}, + std::string("eta") + AR::info}; + Configurable> cfgCHARGE = {std::string(AR::TrackVariableNames[AR::kCHARGE]), + {5., -2.5, 2.5, -1.5, 1.5, 1.}, + std::string("charge") + AR::info}; + Configurable> cfgDCAZ = {std::string(AR::TrackVariableNames[AR::kDCAZ]), + {100., -4., 4., -3.2, 3.2, 1.}, + std::string("DCA in Z") + AR::info}; + Configurable> cfgDCAXY = {std::string(AR::TrackVariableNames[AR::kDCAXY]), + {100., -3., 3., -2.4, 2.4, 1.}, + std::string("DCA in XY") + AR::info}; + Configurable> cfgTPCCLUSTERS = {std::string(AR::TrackVariableNames[AR::kTPCCLUSTERS]), + {160., 0., 160., 80., 161., 1.}, + std::string("TPC clusters") + AR::info}; + Configurable> cfgTPCCROSSEDROWS = {std::string(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), + {160., 0., 160., 80., 161., 1.}, + std::string("TPC crossed rows") + AR::info}; + Configurable> cfgTPCCHI2 = {std::string(AR::TrackVariableNames[AR::kTPCCHI2]), + {500., 0., 5., 0.4, 4., 1.}, + std::string("TPC chi2") + AR::info}; + Configurable> cfgITSCLUSTERS = {std::string(AR::TrackVariableNames[AR::kITSCLUSTERS]), + {6., 0., 6., 0, 7., 1.}, + std::string("ITS clusters") + AR::info}; + std::vector>> cfgTrack = {cfgPT, cfgPHI, cfgETA, cfgCHARGE, cfgDCAZ, cfgDCAXY, cfgTPCCLUSTERS, cfgTPCCROSSEDROWS, cfgTPCCHI2, cfgITSCLUSTERS}; + + // declare histogram registry + HistogramRegistry registry{"MultiParticleCorrelationsARTask", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + + void init(InitContext&) + { + + // add control histograms for event observables to registry + for (auto cfg : cfgEvent) { + registry.add((std::string(AR::ECrecoBefore) + cfg.name).c_str(), "", HistType::kTH1D, {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); + registry.addClone((std::string(AR::ECrecoBefore) + cfg.name).c_str(), (std::string(AR::ECrecoAfter) + cfg.name).c_str()); + registry.addClone((std::string(AR::ECrecoBefore) + cfg.name).c_str(), (std::string(AR::ECsimBefore) + cfg.name).c_str()); + registry.addClone((std::string(AR::ECrecoBefore) + cfg.name).c_str(), (std::string(AR::ECsimAfter) + cfg.name).c_str()); + } + + // add control histograms for track observables to registry + for (auto cfg : cfgTrack) { + registry.add((std::string(AR::TCrecoBefore) + cfg.name).c_str(), "", HistType::kTH1D, {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); + registry.addClone((std::string(AR::TCrecoBefore) + cfg.name).c_str(), (std::string(AR::TCrecoAfter) + cfg.name).c_str()); + registry.addClone((std::string(AR::TCrecoBefore) + cfg.name).c_str(), (std::string(AR::TCsimBefore) + cfg.name).c_str()); + registry.addClone((std::string(AR::TCrecoBefore) + cfg.name).c_str(), (std::string(AR::TCsimAfter) + cfg.name).c_str()); + } + } + + template + void FillEventControlHistBC(CollisionInstance const& collision, HistogramRegistry& registry) + { + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVX]), collision.posX()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVY]), collision.posY()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVZ]), collision.posZ()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVABS]), std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2))); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kCEN]), collision.centRun2V0M()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULQ]), collision.size()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULW]), collision.size()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULNC]), collision.numContrib()); + registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULTPC]), collision.multTPC()); + } + template + void FillEventControlHistAC(CollisionInstance const& collision, HistogramRegistry& registry) + { + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVX]), collision.posX()); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVY]), collision.posY()); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVZ]), collision.posZ()); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVABS]), std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2))); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kCEN]), collision.centRun2V0M()); + // registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULQ]), collision.size()); not here + // registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULW]), collision.size()); not here + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULNC]), collision.numContrib()); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULTPC]), collision.multTPC()); + } + + template + bool SurviveCollisionCut(CollisionInstance const& collision) + { + bool SurviveCut = true; + + // cut vx + if (cfgEvent.at(AR::kVX).value.at(5) > 0 && + (collision.posX() < cfgEvent.at(AR::kVX).value.at(3) || collision.posX() > cfgEvent.at(AR::kVX).value.at(4))) { + SurviveCut = false; + } + // cut vy + if (cfgEvent.at(AR::kVY).value.at(5) > 0 && + (collision.posY() < cfgEvent.at(AR::kVY).value.at(3) || collision.posY() > cfgEvent.at(AR::kVY).value.at(4))) { + SurviveCut = false; + } + // cut vz + if (cfgEvent.at(AR::kVZ).value.at(5) > 0 && + (collision.posZ() < cfgEvent.at(AR::kVZ).value.at(3) || collision.posZ() > cfgEvent.at(AR::kVZ).value.at(4))) { + SurviveCut = false; + } + // cut vabs + if (cfgEvent.at(AR::kVABS).value.at(5) > 0 && + (std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2)) < cfgEvent.at(AR::kVABS).value.at(3) || std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2)) > cfgEvent.at(AR::kVABS).value.at(4))) { + SurviveCut = false; + } + // cut centrality + if (cfgEvent.at(AR::kCEN).value.at(5) > 0 && + (collision.centRun2V0M() < cfgEvent.at(AR::kCEN).value.at(3) || collision.centRun2V0M() > cfgEvent.at(AR::kCEN).value.at(4))) { + SurviveCut = false; + } + // cut multiplicity (qvector) + if (cfgEvent.at(AR::kMULQ).value.at(5) > 0 && + (collision.size() < cfgEvent.at(AR::kMULQ).value.at(3) || collision.size() > cfgEvent.at(AR::kMULQ).value.at(4))) { + SurviveCut = false; + } + // cut multiplicity (weights) + if (cfgEvent.at(AR::kMULW).value.at(5) > 0 && + (collision.size() < cfgEvent.at(AR::kMULW).value.at(3) || collision.size() > cfgEvent.at(AR::kMULW).value.at(4))) { + SurviveCut = false; + } + // cut multiplicity (numContrib) + if (cfgEvent.at(AR::kMULNC).value.at(5) > 0 && + (collision.numContrib() < cfgEvent.at(AR::kMULNC).value.at(3) || collision.numContrib() > cfgEvent.at(AR::kMULNC).value.at(4))) { + SurviveCut = false; + } + // cut multiplicity (tpc) + if (cfgEvent.at(AR::kMULTPC).value.at(5) > 0 && + (collision.multTPC() < cfgEvent.at(AR::kMULTPC).value.at(3) || collision.multTPC() > cfgEvent.at(AR::kMULTPC).value.at(4))) { + SurviveCut = false; + } + + return SurviveCut; + } + + template + void FillTrackControlHistBC(TrackInstance const& track, HistogramRegistry& registry) + { + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kPT]), track.pt()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kPHI]), track.phi()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kETA]), track.eta()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kCHARGE]), track.sign()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kDCAZ]), track.dcaZ()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kDCAXY]), track.dcaXY()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kTPCCLUSTERS]), track.tpcNClsFound()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), track.tpcNClsCrossedRows()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kTPCCHI2]), track.tpcChi2NCl()); + registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kITSCLUSTERS]), track.itsNCls()); + } + template + void FillTrackControlHistAC(TrackInstance const& track, HistogramRegistry& registry) + { + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kPT]), track.pt()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kPHI]), track.phi()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kETA]), track.eta()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kCHARGE]), track.sign()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kDCAZ]), track.dcaZ()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kDCAXY]), track.dcaXY()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kTPCCLUSTERS]), track.tpcNClsFound()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), track.tpcNClsCrossedRows()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kTPCCHI2]), track.tpcChi2NCl()); + registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kITSCLUSTERS]), track.itsNCls()); + } + template + bool SurviveTrackCut(TrackInstance const& track) + { + bool SurviveCut = true; + + // cut pt + if (cfgTrack.at(AR::kPT).value.at(5) > 0 && + (track.pt() < cfgTrack.at(AR::kPT).value.at(3) || track.pt() > cfgTrack.at(AR::kPT).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kETA).value.at(5) > 0 && + (track.eta() < cfgTrack.at(AR::kETA).value.at(3) || track.eta() > cfgTrack.at(AR::kETA).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kPHI).value.at(5) > 0 && + (track.phi() < cfgTrack.at(AR::kPHI).value.at(3) || track.phi() > cfgTrack.at(AR::kPHI).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kCHARGE).value.at(5) > 0 && + (track.sign() < cfgTrack.at(AR::kCHARGE).value.at(3) || track.sign() > cfgTrack.at(AR::kCHARGE).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kDCAZ).value.at(5) > 0 && + (track.dcaZ() < cfgTrack.at(AR::kDCAZ).value.at(3) || track.dcaZ() > cfgTrack.at(AR::kDCAZ).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kDCAXY).value.at(5) > 0 && + (track.dcaXY() < cfgTrack.at(AR::kDCAXY).value.at(3) || track.dcaXY() > cfgTrack.at(AR::kDCAXY).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kTPCCLUSTERS).value.at(5) > 0 && + (track.tpcNClsFound() < cfgTrack.at(AR::kTPCCLUSTERS).value.at(3) || track.tpcNClsFound() > cfgTrack.at(AR::kTPCCLUSTERS).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kTPCCROSSEDROWS).value.at(5) > 0 && + (track.tpcNClsCrossedRows() < cfgTrack.at(AR::kTPCCROSSEDROWS).value.at(3) || track.tpcNClsCrossedRows() > cfgTrack.at(AR::kTPCCROSSEDROWS).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kTPCCHI2).value.at(5) > 0 && + (track.tpcChi2NCl() < cfgTrack.at(AR::kTPCCHI2).value.at(3) || track.tpcChi2NCl() > cfgTrack.at(AR::kTPCCHI2).value.at(4))) { + SurviveCut = false; + } + if (cfgTrack.at(AR::kITSCLUSTERS).value.at(5) > 0 && + (track.itsNCls() < cfgTrack.at(AR::kITSCLUSTERS).value.at(3) || track.itsNCls() > cfgTrack.at(AR::kITSCLUSTERS).value.at(4))) { + SurviveCut = false; + } + + return SurviveCut; + } + + using CollisionsInstanceIterator = soa::Join::iterator; + using TracksInstance = soa::Join; + using TracksInstanceIterator = TracksInstance::iterator; + + void process(CollisionsInstanceIterator const& collision, TracksInstance const& tracks) + { + + // print collision index + LOGF(info, "Collision Index : %d/%d", collision.index(), collision.size()); + + // fill event control histograms before cutting on the collision + FillEventControlHistBC(collision, registry); + + // cut event + if (!SurviveCollisionCut(collision)) { + LOGF(info, "Cut Collision %d -> Break", collision.index()); + return; + } + + // fill event control histograms after cutting on the collision + FillEventControlHistAC(collision, registry); + + LOGF(info, "Number of Tracks: %d", tracks.size()); + UInt_t NumberOfTracks = 0; + // loop over all tracks in the event + for (auto const& track : tracks) { + + // fill track control histograms before track cut + FillTrackControlHistBC(track, registry); + + // cut track + if (!SurviveTrackCut(track)) { + // LOGF(info, "Cut Track %d -> Continue", track.index()); + continue; + } + + // fill track control histograms after surviving track cut + FillTrackControlHistAC(track, registry); + + NumberOfTracks++; + } + LOGF(info, "Surviving Tracks: %d ", NumberOfTracks); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULQ]), NumberOfTracks); + registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULW]), NumberOfTracks); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} From 8b8ef58ac7f255656ba653d1d7cae1f6ce59bb3f Mon Sep 17 00:00:00 2001 From: ariedel-cern Date: Tue, 19 Jul 2022 08:37:54 +0200 Subject: [PATCH 2/6] fix: template helper function for filling control histograms --- .../Tasks/multiparticle-correlations-ar.cxx | 186 ++++++++++-------- 1 file changed, 106 insertions(+), 80 deletions(-) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx index b7d050efa71..2ed79ad7862 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -13,7 +13,9 @@ /// \brief multiparticle-correlations-ar - Task belonging to Anton Riedel for computing multiparticle correlations /// \author Anton Riedel, TU München, anton.riedel@tum.de -#include +#include "fairlogger/Logger.h" +#include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Common/DataModel/Centrality.h" @@ -25,6 +27,30 @@ using namespace o2::framework; namespace MultiParticleCorrelationsARTaskGlobalConfig { +// useful enums +enum BA { + kBEFORE, + kAFTER, + kLAST_BA +}; +static constexpr std::string_view BeforeAfter[kLAST_BA] = {"before/", "after/"}; + +enum RS { + kRECO, + kSIM, + kLAST_RS +}; +static constexpr std::string_view RecoSim[kLAST_RS] = {"reco/", "sim/"}; +// enum HistConfig { +// kBIN, +// kLEDGE, +// kUEDGE, +// kLCUT, +// kHCUT, +// kOCUT, +// kLAST_HistConfig +// }; + // setup for event variables enum EventVariable { kVX, @@ -71,18 +97,9 @@ static constexpr std::string_view TrackVariableNames[kLAST_TrackVariable] = {"Pt "TPCCrossedRows", "TPCChi2", "ITSClusters"}; -// prefixes -static constexpr std::string_view ECrecoBefore = std::string_view("reco/EventControl/before/RB_"); -static constexpr std::string_view ECrecoAfter = std::string_view("reco/EventControl/after/RA_"); -static constexpr std::string_view ECsimBefore = std::string_view("sim/EventControl/before/SB_"); -static constexpr std::string_view ECsimAfter = std::string_view("sim/EventControl/after/SA_"); -static constexpr std::string_view TCrecoBefore = std::string_view("reco/TrackControl/before/RB_"); -static constexpr std::string_view TCrecoAfter = std::string_view("reco/TrackControl/after/RA_"); -static constexpr std::string_view TCsimBefore = std::string_view("sim/TrackControl/before/SB_"); -static constexpr std::string_view TCsimAfter = std::string_view("sim/TrackControl/after/SA_"); +// info string for configurables std::string info = std::string(": Hist bins, Hist lower edge, Hist upper edge, lower cut, upper cut, cut ON(1)/OFF(-1)"); - }; // namespace MultiParticleCorrelationsARTaskGlobalConfig namespace AR = MultiParticleCorrelationsARTaskGlobalConfig; @@ -118,6 +135,7 @@ struct MultiParticleCorrelationsARTask { Configurable> cfgMULTPC = {std::string(AR::EventVariableNames[AR::kMULTPC]), {3000., 0., 3000., 12., 3000., 1.}, std::string("Multiplicity (TPC)") + AR::info}; + // write all event configurables into a vector std::vector>> cfgEvent = {cfgVX, cfgVY, cfgVZ, cfgVABS, cfgCEN, cfgMULQ, cfgMULW, cfgMULNC, cfgMULTPC}; // for track variables @@ -151,6 +169,7 @@ struct MultiParticleCorrelationsARTask { Configurable> cfgITSCLUSTERS = {std::string(AR::TrackVariableNames[AR::kITSCLUSTERS]), {6., 0., 6., 0, 7., 1.}, std::string("ITS clusters") + AR::info}; + // write all track configurables into a vector std::vector>> cfgTrack = {cfgPT, cfgPHI, cfgETA, cfgCHARGE, cfgDCAZ, cfgDCAXY, cfgTPCCLUSTERS, cfgTPCCROSSEDROWS, cfgTPCCHI2, cfgITSCLUSTERS}; // declare histogram registry @@ -159,48 +178,56 @@ struct MultiParticleCorrelationsARTask { void init(InitContext&) { - // add control histograms for event observables to registry - for (auto cfg : cfgEvent) { - registry.add((std::string(AR::ECrecoBefore) + cfg.name).c_str(), "", HistType::kTH1D, {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); - registry.addClone((std::string(AR::ECrecoBefore) + cfg.name).c_str(), (std::string(AR::ECrecoAfter) + cfg.name).c_str()); - registry.addClone((std::string(AR::ECrecoBefore) + cfg.name).c_str(), (std::string(AR::ECsimBefore) + cfg.name).c_str()); - registry.addClone((std::string(AR::ECrecoBefore) + cfg.name).c_str(), (std::string(AR::ECsimAfter) + cfg.name).c_str()); - } - - // add control histograms for track observables to registry - for (auto cfg : cfgTrack) { - registry.add((std::string(AR::TCrecoBefore) + cfg.name).c_str(), "", HistType::kTH1D, {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); - registry.addClone((std::string(AR::TCrecoBefore) + cfg.name).c_str(), (std::string(AR::TCrecoAfter) + cfg.name).c_str()); - registry.addClone((std::string(AR::TCrecoBefore) + cfg.name).c_str(), (std::string(AR::TCsimBefore) + cfg.name).c_str()); - registry.addClone((std::string(AR::TCrecoBefore) + cfg.name).c_str(), (std::string(AR::TCsimAfter) + cfg.name).c_str()); + // add control histograms for event/track observables to registry + for (int rs = 0; rs < AR::kLAST_RS; rs++) { + for (int ba = 0; ba < AR::kLAST_BA; ba++) { + + // iterate over event configurables + for (auto cfg : cfgEvent) { + registry.add((std::string(AR::RecoSim[rs]) + std::string("EventControl/") + std::string(AR::BeforeAfter[ba]) + cfg.name).c_str(), + "", + HistType::kTH1D, + {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); + } + // iterate over event configurables + for (auto cfg : cfgTrack) { + registry.add((std::string(AR::RecoSim[rs]) + std::string("TrackControl/") + std::string(AR::BeforeAfter[ba]) + cfg.name).c_str(), + "", + HistType::kTH1D, + {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); + } + } } } - template - void FillEventControlHistBC(CollisionInstance const& collision, HistogramRegistry& registry) + template + void FillEventControlHist(CollisionInstance const& collision, HistogramRegistry& registry) { - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVX]), collision.posX()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVY]), collision.posY()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVZ]), collision.posZ()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kVABS]), std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2))); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kCEN]), collision.centRun2V0M()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULQ]), collision.size()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULW]), collision.size()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULNC]), collision.numContrib()); - registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULTPC]), collision.multTPC()); + // registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kPT]), + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVX]), + collision.posX()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVY]), + collision.posY()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVZ]), + collision.posZ()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVABS]), + std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2))); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kCEN]), + collision.centRun2V0M()); + // registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULQ]), collision.size()); fill separately + // registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULW]), collision.size()); fill separately + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULNC]), + collision.numContrib()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULTPC]), + collision.multTPC()); } - template - void FillEventControlHistAC(CollisionInstance const& collision, HistogramRegistry& registry) + template + void FillEventControlHistMul(HistogramRegistry& registry, double mulQvector, double mulWeights) { - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVX]), collision.posX()); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVY]), collision.posY()); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVZ]), collision.posZ()); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kVABS]), std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2))); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kCEN]), collision.centRun2V0M()); - // registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULQ]), collision.size()); not here - // registry.fill(HIST(AR::ECrecoBefore) + HIST(AR::EventVariableNames[AR::kMULW]), collision.size()); not here - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULNC]), collision.numContrib()); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULTPC]), collision.multTPC()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULQ]), + mulQvector); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULW]), + mulWeights); } template @@ -257,33 +284,29 @@ struct MultiParticleCorrelationsARTask { return SurviveCut; } - template - void FillTrackControlHistBC(TrackInstance const& track, HistogramRegistry& registry) - { - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kPT]), track.pt()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kPHI]), track.phi()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kETA]), track.eta()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kCHARGE]), track.sign()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kDCAZ]), track.dcaZ()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kDCAXY]), track.dcaXY()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kTPCCLUSTERS]), track.tpcNClsFound()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), track.tpcNClsCrossedRows()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kTPCCHI2]), track.tpcChi2NCl()); - registry.fill(HIST(AR::TCrecoBefore) + HIST(AR::TrackVariableNames[AR::kITSCLUSTERS]), track.itsNCls()); - } - template - void FillTrackControlHistAC(TrackInstance const& track, HistogramRegistry& registry) + template + void FillTrackControlHist(TrackInstance const& track, HistogramRegistry& registry) { - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kPT]), track.pt()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kPHI]), track.phi()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kETA]), track.eta()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kCHARGE]), track.sign()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kDCAZ]), track.dcaZ()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kDCAXY]), track.dcaXY()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kTPCCLUSTERS]), track.tpcNClsFound()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), track.tpcNClsCrossedRows()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kTPCCHI2]), track.tpcChi2NCl()); - registry.fill(HIST(AR::TCrecoAfter) + HIST(AR::TrackVariableNames[AR::kITSCLUSTERS]), track.itsNCls()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kPT]), + track.pt()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kPHI]), + track.phi()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kETA]), + track.eta()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kCHARGE]), + track.sign()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kDCAZ]), + track.dcaZ()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kDCAXY]), + track.dcaXY()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kTPCCLUSTERS]), + track.tpcNClsFound()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), + track.tpcNClsCrossedRows()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kTPCCHI2]), + track.tpcChi2NCl()); + registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kITSCLUSTERS]), + track.itsNCls()); } template bool SurviveTrackCut(TrackInstance const& track) @@ -346,7 +369,10 @@ struct MultiParticleCorrelationsARTask { LOGF(info, "Collision Index : %d/%d", collision.index(), collision.size()); // fill event control histograms before cutting on the collision - FillEventControlHistBC(collision, registry); + FillEventControlHist(collision, registry); + FillEventControlHistMul(registry, collision.size(), collision.size()); + + // fill multiplicity for qvector and weights separately // cut event if (!SurviveCollisionCut(collision)) { @@ -355,7 +381,7 @@ struct MultiParticleCorrelationsARTask { } // fill event control histograms after cutting on the collision - FillEventControlHistAC(collision, registry); + FillEventControlHist(collision, registry); LOGF(info, "Number of Tracks: %d", tracks.size()); UInt_t NumberOfTracks = 0; @@ -363,22 +389,22 @@ struct MultiParticleCorrelationsARTask { for (auto const& track : tracks) { // fill track control histograms before track cut - FillTrackControlHistBC(track, registry); + FillTrackControlHist(track, registry); // cut track - if (!SurviveTrackCut(track)) { + if (!SurviveTrackCut(track)) { // LOGF(info, "Cut Track %d -> Continue", track.index()); continue; } // fill track control histograms after surviving track cut - FillTrackControlHistAC(track, registry); + FillTrackControlHist(track, registry); NumberOfTracks++; } + + FillEventControlHistMul(registry, NumberOfTracks, NumberOfTracks); LOGF(info, "Surviving Tracks: %d ", NumberOfTracks); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULQ]), NumberOfTracks); - registry.fill(HIST(AR::ECrecoAfter) + HIST(AR::EventVariableNames[AR::kMULW]), NumberOfTracks); } }; From 18c43df868b25ea24fa59f6daff640161b1e166f Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Wed, 3 Aug 2022 08:00:04 +0200 Subject: [PATCH 3/6] Feat: implement comments from previous PR - template functions to reuse them (i.e. reco and sim) - implement cuts in form of filters for more performance --- .../Tasks/multiparticle-correlations-ar.cxx | 415 ++++++++---------- 1 file changed, 193 insertions(+), 222 deletions(-) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx index 2ed79ad7862..eaa7187b3c3 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -14,20 +14,24 @@ /// \author Anton Riedel, TU München, anton.riedel@tum.de #include "fairlogger/Logger.h" +#include #include #include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" +#include "Framework/Expressions.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" using namespace o2; using namespace o2::framework; +using namespace o2::framework::expressions; +// Define useful constant and enums in a seperate name space namespace MultiParticleCorrelationsARTaskGlobalConfig { -// useful enums +// for before and after applying cuts enum BA { kBEFORE, kAFTER, @@ -35,21 +39,22 @@ enum BA { }; static constexpr std::string_view BeforeAfter[kLAST_BA] = {"before/", "after/"}; +// for reconstructed and simulated data enum RS { kRECO, kSIM, kLAST_RS }; static constexpr std::string_view RecoSim[kLAST_RS] = {"reco/", "sim/"}; -// enum HistConfig { -// kBIN, -// kLEDGE, -// kUEDGE, -// kLCUT, -// kHCUT, -// kOCUT, -// kLAST_HistConfig -// }; +enum HistConfig { + kBIN, // number of bins + kLEDGE, // lower edge of the histogram + kUEDGE, // upper edge of the histogram + kLCUT, // lower cut + kUCUT, // upper cut + kOCUT, // option whether to apply cut at all + kLAST_HistConfig +}; // setup for event variables enum EventVariable { @@ -100,80 +105,141 @@ static constexpr std::string_view TrackVariableNames[kLAST_TrackVariable] = {"Pt // info string for configurables std::string info = std::string(": Hist bins, Hist lower edge, Hist upper edge, lower cut, upper cut, cut ON(1)/OFF(-1)"); + +inline float abs(float vx, float vy, float vz) +{ + return std::sqrt(vx * vx + vy * vy * vz * vz); +} }; // namespace MultiParticleCorrelationsARTaskGlobalConfig +// use an alias for the namespace namespace AR = MultiParticleCorrelationsARTaskGlobalConfig; struct MultiParticleCorrelationsARTask { - // configurables + // configurables and cuts (where possible) // for event variables - Configurable> cfgVX = {std::string(AR::EventVariableNames[AR::kVX]), - {400., -2., 2., -1., 1., 1.}, - std::string("Vertex X") + AR::info}; - Configurable> cfgVY = {std::string(AR::EventVariableNames[AR::kVY]), - {400., -2., 2., -1., 1., 1.}, - std::string("Vertex Y") + AR::info}; - Configurable> cfgVZ = {std::string(AR::EventVariableNames[AR::kVZ]), - {2400., -12., 12., -10., 10., 1.}, - std::string("Vertex Z") + AR::info}; - Configurable> cfgVABS = {std::string(AR::EventVariableNames[AR::kVABS]), - {150., 0., 15, 1.e-6, 15., 1.}, - std::string("Vertex distance from origin") + AR::info}; - Configurable> cfgCEN = {std::string(AR::EventVariableNames[AR::kCEN]), - {120., 0., 120., 0., 80., 1.}, - std::string("Centrality") + AR::info}; - Configurable> cfgMULQ = {std::string(AR::EventVariableNames[AR::kMULQ]), + Configurable> cfgVX = {std::string(AR::EventVariableNames[AR::kVX]), + {400., -2., 2., -1., 1., 1.}, + std::string("Vertex X") + AR::info}; + Filter filterVX = aod::collision::posX > cfgVX.value.at(AR::kLCUT) && + aod::collision::posX 0.; + Configurable> cfgVY = {std::string(AR::EventVariableNames[AR::kVY]), + {400., -2., 2., -1., 1., 1.}, + std::string("Vertex Y") + AR::info}; + Filter filterVY = aod::collision::posY > cfgVY.value.at(AR::kLCUT) && + aod::collision::posY 0.; + Configurable> cfgVZ = {std::string(AR::EventVariableNames[AR::kVZ]), + {2400., -12., 12., -10., 10., 1.}, + std::string("Vertex Z") + AR::info}; + Filter filterVZ = aod::collision::posZ > cfgVZ.value.at(AR::kLCUT) && + aod::collision::posZ 0.; + Configurable> cfgVABS = {std::string(AR::EventVariableNames[AR::kVABS]), + {150., 0., 15, 1.e-6, 15., 1.}, + std::string("Vertex distance from origin") + AR::info}; + Configurable> cfgCEN = {std::string(AR::EventVariableNames[AR::kCEN]), + {120., 0., 120., 0., 80., 1.}, + std::string("Centrality") + AR::info}; + Filter filterCEN = aod::cent::centRun2V0M > cfgCEN.value.at(AR::kLCUT) && + aod::cent::centRun2V0M 0.; + Configurable> cfgMULQ = {std::string(AR::EventVariableNames[AR::kMULQ]), + {3000., 0., 3000., 10., 3000., 1.}, + std::string("Multiplicity (QVector)") + AR::info}; + Configurable> cfgMULW = {std::string(AR::EventVariableNames[AR::kMULW]), + {3000., 0., 3000., 10., 3000., 1.}, + std::string("Multiplicity (Weights)") + AR::info}; + Configurable> cfgMULNC = {std::string(AR::EventVariableNames[AR::kMULNC]), {3000., 0., 3000., 10., 3000., 1.}, - std::string("Multiplicity (QVector)") + AR::info}; - Configurable> cfgMULW = {std::string(AR::EventVariableNames[AR::kMULW]), - {3000., 0., 3000., 10., 3000., 1.}, - std::string("Multiplicity (Weights)") + AR::info}; - Configurable> cfgMULNC = {std::string(AR::EventVariableNames[AR::kMULNC]), - {3000., 0., 3000., 10., 3000., 1.}, - std::string("Multiplicity (NumContrib)") + AR::info}; - Configurable> cfgMULTPC = {std::string(AR::EventVariableNames[AR::kMULTPC]), - {3000., 0., 3000., 12., 3000., 1.}, - std::string("Multiplicity (TPC)") + AR::info}; - // write all event configurables into a vector - std::vector>> cfgEvent = {cfgVX, cfgVY, cfgVZ, cfgVABS, cfgCEN, cfgMULQ, cfgMULW, cfgMULNC, cfgMULTPC}; + std::string("Multiplicity (NumContrib)") + AR::info}; + Filter filterMULNC = aod::collision::numContrib > static_cast(cfgMULNC.value.at(AR::kLCUT)) && + aod::collision::numContrib(cfgMULNC.value.at(AR::kUCUT)) && + cfgMULNC.value.at(AR::kOCUT)> 0.; + Configurable> cfgMULTPC = {std::string(AR::EventVariableNames[AR::kMULTPC]), + {3000., 0., 3000., 12., 3000., 1.}, + std::string("Multiplicity (TPC)") + AR::info}; + Filter filterMULTPC = aod::collision::numContrib > static_cast(cfgMULTPC.value.at(AR::kLCUT)) && + aod::collision::numContrib(cfgMULTPC.value.at(AR::kUCUT)) && + cfgMULTPC.value.at(AR::kOCUT)> 0.; - // for track variables - Configurable> cfgPT = {std::string(AR::TrackVariableNames[AR::kPT]), - {600., 0., 6., 0.2, 5., 1.}, - std::string("pt") + AR::info}; - Configurable> cfgPHI = {std::string(AR::TrackVariableNames[AR::kPHI]), - {360., 0., 2. * M_PI, 0., 2. * M_PI, 1.}, - std::string("phi") + AR::info}; - Configurable> cfgETA = {std::string(AR::TrackVariableNames[AR::kETA]), - {1000., -1., 1., -0.8, 0.8, 1.}, - std::string("eta") + AR::info}; - Configurable> cfgCHARGE = {std::string(AR::TrackVariableNames[AR::kCHARGE]), - {5., -2.5, 2.5, -1.5, 1.5, 1.}, - std::string("charge") + AR::info}; - Configurable> cfgDCAZ = {std::string(AR::TrackVariableNames[AR::kDCAZ]), - {100., -4., 4., -3.2, 3.2, 1.}, - std::string("DCA in Z") + AR::info}; - Configurable> cfgDCAXY = {std::string(AR::TrackVariableNames[AR::kDCAXY]), - {100., -3., 3., -2.4, 2.4, 1.}, - std::string("DCA in XY") + AR::info}; - Configurable> cfgTPCCLUSTERS = {std::string(AR::TrackVariableNames[AR::kTPCCLUSTERS]), - {160., 0., 160., 80., 161., 1.}, - std::string("TPC clusters") + AR::info}; - Configurable> cfgTPCCROSSEDROWS = {std::string(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), - {160., 0., 160., 80., 161., 1.}, - std::string("TPC crossed rows") + AR::info}; - Configurable> cfgTPCCHI2 = {std::string(AR::TrackVariableNames[AR::kTPCCHI2]), - {500., 0., 5., 0.4, 4., 1.}, - std::string("TPC chi2") + AR::info}; - Configurable> cfgITSCLUSTERS = {std::string(AR::TrackVariableNames[AR::kITSCLUSTERS]), - {6., 0., 6., 0, 7., 1.}, - std::string("ITS clusters") + AR::info}; + // write all event configurables into a vector + std::vector>> cfgEvent = {cfgVX, + cfgVY, + cfgVZ, + cfgVABS, + cfgCEN, + cfgMULQ, + cfgMULW, + cfgMULNC, + cfgMULTPC}; + + // for track variables and cuts (where possible) + Configurable> cfgPT = {std::string(AR::TrackVariableNames[AR::kPT]), + {600., 0., 6., 0.2, 5., 1.}, + std::string("pt") + AR::info}; + Filter filterPT = aod::track::pt > cfgPT.value.at(AR::kLCUT) && + aod::track::pt 0.; + Configurable> cfgPHI = {std::string(AR::TrackVariableNames[AR::kPHI]), + {360., 0., 2. * M_PI, 0., 2. * M_PI, 1.}, + std::string("phi") + AR::info}; + Filter filterPHI = aod::track::phi > cfgPHI.value.at(AR::kLCUT) && + aod::track::phi 0.; + Configurable> cfgETA = {std::string(AR::TrackVariableNames[AR::kETA]), + {1000., -1., 1., -0.8, 0.8, 1.}, + std::string("eta") + AR::info}; + Filter filterETA = aod::track::eta > cfgETA.value.at(AR::kLCUT) && + aod::track::eta 0.; + Configurable> cfgCHARGE = {std::string(AR::TrackVariableNames[AR::kCHARGE]), + {5., -2.5, 2.5, -1.5, 1.5, 1.}, + std::string("charge") + AR::info}; + Configurable> cfgDCAZ = {std::string(AR::TrackVariableNames[AR::kDCAZ]), + {100., -4., 4., -3.2, 3.2, 1.}, + std::string("DCA in Z") + AR::info}; + Filter filterDCAZ = aod::track::dcaZ > cfgDCAZ.value.at(AR::kLCUT) && + aod::track::dcaZ 0.; + Configurable> cfgDCAXY = {std::string(AR::TrackVariableNames[AR::kDCAXY]), + {100., -3., 3., -2.4, 2.4, 1.}, + std::string("DCA in XY") + AR::info}; + Filter filterDCAXY = aod::track::dcaXY > cfgDCAXY.value.at(AR::kLCUT) && + aod::track::dcaXY 0.; + Configurable> cfgTPCCLUSTERS = {std::string(AR::TrackVariableNames[AR::kTPCCLUSTERS]), + {160., 0., 160., 80., 161., 1.}, + std::string("TPC clusters") + AR::info}; + Configurable> cfgTPCCROSSEDROWS = {std::string(AR::TrackVariableNames[AR::kTPCCROSSEDROWS]), + {160., 0., 160., 80., 161., 1.}, + std::string("TPC crossed rows") + AR::info}; + Configurable> cfgTPCCHI2 = {std::string(AR::TrackVariableNames[AR::kTPCCHI2]), + {500., 0., 5., 0.4, 4., 1.}, + std::string("TPC chi2") + AR::info}; + Configurable> cfgITSCLUSTERS = {std::string(AR::TrackVariableNames[AR::kITSCLUSTERS]), + {6., 0., 6., 0, 7., 1.}, + std::string("ITS clusters") + AR::info}; // write all track configurables into a vector - std::vector>> cfgTrack = {cfgPT, cfgPHI, cfgETA, cfgCHARGE, cfgDCAZ, cfgDCAXY, cfgTPCCLUSTERS, cfgTPCCROSSEDROWS, cfgTPCCHI2, cfgITSCLUSTERS}; + std::vector>> cfgTrack = {cfgPT, + cfgPHI, + cfgETA, + cfgCHARGE, + cfgDCAZ, + cfgDCAXY, + cfgTPCCLUSTERS, + cfgTPCCROSSEDROWS, + cfgTPCCHI2, + cfgITSCLUSTERS}; // declare histogram registry - HistogramRegistry registry{"MultiParticleCorrelationsARTask", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + HistogramRegistry registry{"MultiParticleCorrelationsARTask", + {}, + OutputObjHandlingPolicy::AnalysisObject, + false, + false}; void init(InitContext&) { @@ -184,26 +250,38 @@ struct MultiParticleCorrelationsARTask { // iterate over event configurables for (auto cfg : cfgEvent) { - registry.add((std::string(AR::RecoSim[rs]) + std::string("EventControl/") + std::string(AR::BeforeAfter[ba]) + cfg.name).c_str(), + registry.add((std::string(AR::RecoSim[rs]) + + std::string("EventControl/") + + std::string(AR::BeforeAfter[ba]) + + cfg.name) + .c_str(), "", HistType::kTH1D, - {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); + {{static_cast(cfg.value.at(AR::kBIN)), + cfg.value.at(AR::kLEDGE), + cfg.value.at(AR::kUEDGE)}}); } - // iterate over event configurables + // iterate over track configurables for (auto cfg : cfgTrack) { - registry.add((std::string(AR::RecoSim[rs]) + std::string("TrackControl/") + std::string(AR::BeforeAfter[ba]) + cfg.name).c_str(), + registry.add((std::string(AR::RecoSim[rs]) + + std::string("TrackControl/") + + std::string(AR::BeforeAfter[ba]) + + cfg.name) + .c_str(), "", HistType::kTH1D, - {{static_cast(cfg.value.at(0)), cfg.value.at(1), cfg.value.at(2)}}); + {{static_cast(cfg.value.at(AR::kBIN)), + cfg.value.at(AR::kLEDGE), + cfg.value.at(AR::kUEDGE)}}); } } } } - template - void FillEventControlHist(CollisionInstance const& collision, HistogramRegistry& registry) + // function for filling control histograms of event variables + template + void FillEventControlHist(CollisionObject const& collision, HistogramRegistry& registry) { - // registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kPT]), registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVX]), collision.posX()); registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVY]), @@ -230,62 +308,9 @@ struct MultiParticleCorrelationsARTask { mulWeights); } - template - bool SurviveCollisionCut(CollisionInstance const& collision) - { - bool SurviveCut = true; - - // cut vx - if (cfgEvent.at(AR::kVX).value.at(5) > 0 && - (collision.posX() < cfgEvent.at(AR::kVX).value.at(3) || collision.posX() > cfgEvent.at(AR::kVX).value.at(4))) { - SurviveCut = false; - } - // cut vy - if (cfgEvent.at(AR::kVY).value.at(5) > 0 && - (collision.posY() < cfgEvent.at(AR::kVY).value.at(3) || collision.posY() > cfgEvent.at(AR::kVY).value.at(4))) { - SurviveCut = false; - } - // cut vz - if (cfgEvent.at(AR::kVZ).value.at(5) > 0 && - (collision.posZ() < cfgEvent.at(AR::kVZ).value.at(3) || collision.posZ() > cfgEvent.at(AR::kVZ).value.at(4))) { - SurviveCut = false; - } - // cut vabs - if (cfgEvent.at(AR::kVABS).value.at(5) > 0 && - (std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2)) < cfgEvent.at(AR::kVABS).value.at(3) || std::sqrt(std::pow(collision.posX(), 2) + std::pow(collision.posY(), 2) + std::pow(collision.posZ(), 2)) > cfgEvent.at(AR::kVABS).value.at(4))) { - SurviveCut = false; - } - // cut centrality - if (cfgEvent.at(AR::kCEN).value.at(5) > 0 && - (collision.centRun2V0M() < cfgEvent.at(AR::kCEN).value.at(3) || collision.centRun2V0M() > cfgEvent.at(AR::kCEN).value.at(4))) { - SurviveCut = false; - } - // cut multiplicity (qvector) - if (cfgEvent.at(AR::kMULQ).value.at(5) > 0 && - (collision.size() < cfgEvent.at(AR::kMULQ).value.at(3) || collision.size() > cfgEvent.at(AR::kMULQ).value.at(4))) { - SurviveCut = false; - } - // cut multiplicity (weights) - if (cfgEvent.at(AR::kMULW).value.at(5) > 0 && - (collision.size() < cfgEvent.at(AR::kMULW).value.at(3) || collision.size() > cfgEvent.at(AR::kMULW).value.at(4))) { - SurviveCut = false; - } - // cut multiplicity (numContrib) - if (cfgEvent.at(AR::kMULNC).value.at(5) > 0 && - (collision.numContrib() < cfgEvent.at(AR::kMULNC).value.at(3) || collision.numContrib() > cfgEvent.at(AR::kMULNC).value.at(4))) { - SurviveCut = false; - } - // cut multiplicity (tpc) - if (cfgEvent.at(AR::kMULTPC).value.at(5) > 0 && - (collision.multTPC() < cfgEvent.at(AR::kMULTPC).value.at(3) || collision.multTPC() > cfgEvent.at(AR::kMULTPC).value.at(4))) { - SurviveCut = false; - } - - return SurviveCut; - } - - template - void FillTrackControlHist(TrackInstance const& track, HistogramRegistry& registry) + // function for fill control histograms of track variables + template + void FillTrackControlHist(TrackObject const& track, HistogramRegistry& registry) { registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kPT]), track.pt()); @@ -308,104 +333,50 @@ struct MultiParticleCorrelationsARTask { registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kITSCLUSTERS]), track.itsNCls()); } - template - bool SurviveTrackCut(TrackInstance const& track) - { - bool SurviveCut = true; - // cut pt - if (cfgTrack.at(AR::kPT).value.at(5) > 0 && - (track.pt() < cfgTrack.at(AR::kPT).value.at(3) || track.pt() > cfgTrack.at(AR::kPT).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kETA).value.at(5) > 0 && - (track.eta() < cfgTrack.at(AR::kETA).value.at(3) || track.eta() > cfgTrack.at(AR::kETA).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kPHI).value.at(5) > 0 && - (track.phi() < cfgTrack.at(AR::kPHI).value.at(3) || track.phi() > cfgTrack.at(AR::kPHI).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kCHARGE).value.at(5) > 0 && - (track.sign() < cfgTrack.at(AR::kCHARGE).value.at(3) || track.sign() > cfgTrack.at(AR::kCHARGE).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kDCAZ).value.at(5) > 0 && - (track.dcaZ() < cfgTrack.at(AR::kDCAZ).value.at(3) || track.dcaZ() > cfgTrack.at(AR::kDCAZ).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kDCAXY).value.at(5) > 0 && - (track.dcaXY() < cfgTrack.at(AR::kDCAXY).value.at(3) || track.dcaXY() > cfgTrack.at(AR::kDCAXY).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kTPCCLUSTERS).value.at(5) > 0 && - (track.tpcNClsFound() < cfgTrack.at(AR::kTPCCLUSTERS).value.at(3) || track.tpcNClsFound() > cfgTrack.at(AR::kTPCCLUSTERS).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kTPCCROSSEDROWS).value.at(5) > 0 && - (track.tpcNClsCrossedRows() < cfgTrack.at(AR::kTPCCROSSEDROWS).value.at(3) || track.tpcNClsCrossedRows() > cfgTrack.at(AR::kTPCCROSSEDROWS).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kTPCCHI2).value.at(5) > 0 && - (track.tpcChi2NCl() < cfgTrack.at(AR::kTPCCHI2).value.at(3) || track.tpcChi2NCl() > cfgTrack.at(AR::kTPCCHI2).value.at(4))) { - SurviveCut = false; - } - if (cfgTrack.at(AR::kITSCLUSTERS).value.at(5) > 0 && - (track.itsNCls() < cfgTrack.at(AR::kITSCLUSTERS).value.at(3) || track.itsNCls() > cfgTrack.at(AR::kITSCLUSTERS).value.at(4))) { - SurviveCut = false; - } - - return SurviveCut; - } - - using CollisionsInstanceIterator = soa::Join::iterator; - using TracksInstance = soa::Join; - using TracksInstanceIterator = TracksInstance::iterator; - - void process(CollisionsInstanceIterator const& collision, TracksInstance const& tracks) + // templated function for processing data + template + void ProcessReconstructed(CollisionObject const& collision, TrackObject const& tracks) { - - // print collision index - LOGF(info, "Collision Index : %d/%d", collision.index(), collision.size()); - // fill event control histograms before cutting on the collision - FillEventControlHist(collision, registry); - FillEventControlHistMul(registry, collision.size(), collision.size()); - + FillEventControlHist(collision, registry); // fill multiplicity for qvector and weights separately + FillEventControlHistMul(registry, collision.size(), collision.size()); - // cut event - if (!SurviveCollisionCut(collision)) { - LOGF(info, "Cut Collision %d -> Break", collision.index()); - return; - } - - // fill event control histograms after cutting on the collision - FillEventControlHist(collision, registry); - - LOGF(info, "Number of Tracks: %d", tracks.size()); - UInt_t NumberOfTracks = 0; // loop over all tracks in the event for (auto const& track : tracks) { - // fill track control histograms before track cut - FillTrackControlHist(track, registry); + FillTrackControlHist(track, registry); + } + } - // cut track - if (!SurviveTrackCut(track)) { - // LOGF(info, "Cut Track %d -> Continue", track.index()); - continue; - } + using CollisionsInstance = soa::Join; + using TracksInstance = soa::Join; - // fill track control histograms after surviving track cut - FillTrackControlHist(track, registry); + using CollisionsInstanceIterator = CollisionsInstance::iterator; + // using TracksInstanceIterator = TracksInstance::iterator; - NumberOfTracks++; - } + // process reconstructed data before applying cuts + void ProcessReconstructedBeforeCut(CollisionsInstanceIterator const& collision, TracksInstance const& tracks) + { + LOGF(info, "Process reconstructed data before applying cuts"); + ProcessReconstructed(collision, tracks); + }; + PROCESS_SWITCH(MultiParticleCorrelationsARTask, ProcessReconstructedBeforeCut, "Process Reco before Cuts", true); - FillEventControlHistMul(registry, NumberOfTracks, NumberOfTracks); - LOGF(info, "Surviving Tracks: %d ", NumberOfTracks); - } + using FilteredCollisionsInstance = soa::Filtered; + using FilteredTracksInstance = soa::Filtered; + + using FilteredCollisionsInstanceIterator = FilteredCollisionsInstance::iterator; + // using FilteredTracksInstanceIterator = FilteredTracksInstance::iterator; + + // process reconstructed data after applying cuts + void ProcessReconstructedAfterCut(FilteredCollisionsInstanceIterator const& collision, FilteredTracksInstance const& tracks) + { + LOGF(info, "Process reconstructed data after applying cuts"); + ProcessReconstructed(collision, tracks); + }; + PROCESS_SWITCH(MultiParticleCorrelationsARTask, ProcessReconstructedAfterCut, "Process Reco after Cuts", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From 6d440933cf07d562d9e9315dfb69dd1a1bc0918b Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Fri, 5 Aug 2022 14:31:41 +0200 Subject: [PATCH 4/6] Fix: filter events inside the process function instead of using filters --- .../Tasks/multiparticle-correlations-ar.cxx | 196 +++++++++++------- 1 file changed, 121 insertions(+), 75 deletions(-) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx index eaa7187b3c3..d31858d552c 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/Expressions.h" @@ -28,8 +29,8 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -// Define useful constant and enums in a seperate name space -namespace MultiParticleCorrelationsARTaskGlobalConfig +// Define useful constants and enums in a separate name space +namespace MultiParticleCorrelationsARTaskGlobalVariables { // for before and after applying cuts enum BA { @@ -46,6 +47,8 @@ enum RS { kLAST_RS }; static constexpr std::string_view RecoSim[kLAST_RS] = {"reco/", "sim/"}; + +// for configuring control histograms enum HistConfig { kBIN, // number of bins kLEDGE, // lower edge of the histogram @@ -56,7 +59,7 @@ enum HistConfig { kLAST_HistConfig }; -// setup for event variables +// event variables enum EventVariable { kVX, kVY, @@ -78,7 +81,7 @@ static constexpr std::string_view EventVariableNames[kLAST_EventVariable] = {"Ve "MultiplicityWeights", "MultiplicityNumContrib", "MultiplicityTPC"}; -// setup for track variables +// track variables enum TrackVariable { kPT, kPHI, @@ -103,49 +106,52 @@ static constexpr std::string_view TrackVariableNames[kLAST_TrackVariable] = {"Pt "TPCChi2", "ITSClusters"}; -// info string for configurables +// common info string for all configurables std::string info = std::string(": Hist bins, Hist lower edge, Hist upper edge, lower cut, upper cut, cut ON(1)/OFF(-1)"); +// function for computing the absolute distance of the primary vertex form the origin inline float abs(float vx, float vy, float vz) { return std::sqrt(vx * vx + vy * vy * vz * vz); } -}; // namespace MultiParticleCorrelationsARTaskGlobalConfig -// use an alias for the namespace -namespace AR = MultiParticleCorrelationsARTaskGlobalConfig; +// generice function for checking if the value of a variable passes a cut +inline bool SurviveCut(std::vector ConfigValue, float Value) +{ + bool flag = true; + // check if the cut is configured to be use in the first place + if (ConfigValue.at(kOCUT) > 0.) { + // check if the value of the variable is not lower than the lower bound and + // not not larger than the upper bound + if (!(Value > ConfigValue.at(kLCUT) && Value < ConfigValue.at(kUCUT))) { + flag = false; + } + } + return flag; +} +}; // namespace MultiParticleCorrelationsARTaskGlobalVariables + +// use an alias for our namespace +namespace AR = MultiParticleCorrelationsARTaskGlobalVariables; struct MultiParticleCorrelationsARTask { - // configurables and cuts (where possible) - // for event variables + // event configurables and cuts Configurable> cfgVX = {std::string(AR::EventVariableNames[AR::kVX]), {400., -2., 2., -1., 1., 1.}, std::string("Vertex X") + AR::info}; - Filter filterVX = aod::collision::posX > cfgVX.value.at(AR::kLCUT) && - aod::collision::posX 0.; Configurable> cfgVY = {std::string(AR::EventVariableNames[AR::kVY]), {400., -2., 2., -1., 1., 1.}, std::string("Vertex Y") + AR::info}; - Filter filterVY = aod::collision::posY > cfgVY.value.at(AR::kLCUT) && - aod::collision::posY 0.; Configurable> cfgVZ = {std::string(AR::EventVariableNames[AR::kVZ]), {2400., -12., 12., -10., 10., 1.}, std::string("Vertex Z") + AR::info}; - Filter filterVZ = aod::collision::posZ > cfgVZ.value.at(AR::kLCUT) && - aod::collision::posZ 0.; Configurable> cfgVABS = {std::string(AR::EventVariableNames[AR::kVABS]), {150., 0., 15, 1.e-6, 15., 1.}, std::string("Vertex distance from origin") + AR::info}; Configurable> cfgCEN = {std::string(AR::EventVariableNames[AR::kCEN]), {120., 0., 120., 0., 80., 1.}, std::string("Centrality") + AR::info}; - Filter filterCEN = aod::cent::centRun2V0M > cfgCEN.value.at(AR::kLCUT) && - aod::cent::centRun2V0M 0.; Configurable> cfgMULQ = {std::string(AR::EventVariableNames[AR::kMULQ]), {3000., 0., 3000., 10., 3000., 1.}, std::string("Multiplicity (QVector)") + AR::info}; @@ -155,16 +161,9 @@ struct MultiParticleCorrelationsARTask { Configurable> cfgMULNC = {std::string(AR::EventVariableNames[AR::kMULNC]), {3000., 0., 3000., 10., 3000., 1.}, std::string("Multiplicity (NumContrib)") + AR::info}; - Filter filterMULNC = aod::collision::numContrib > static_cast(cfgMULNC.value.at(AR::kLCUT)) && - aod::collision::numContrib(cfgMULNC.value.at(AR::kUCUT)) && - cfgMULNC.value.at(AR::kOCUT)> 0.; Configurable> cfgMULTPC = {std::string(AR::EventVariableNames[AR::kMULTPC]), {3000., 0., 3000., 12., 3000., 1.}, std::string("Multiplicity (TPC)") + AR::info}; - Filter filterMULTPC = aod::collision::numContrib > static_cast(cfgMULTPC.value.at(AR::kLCUT)) && - aod::collision::numContrib(cfgMULTPC.value.at(AR::kUCUT)) && - cfgMULTPC.value.at(AR::kOCUT)> 0.; - // write all event configurables into a vector std::vector>> cfgEvent = {cfgVX, cfgVY, @@ -176,40 +175,25 @@ struct MultiParticleCorrelationsARTask { cfgMULNC, cfgMULTPC}; - // for track variables and cuts (where possible) + // track configurables and cuts Configurable> cfgPT = {std::string(AR::TrackVariableNames[AR::kPT]), {600., 0., 6., 0.2, 5., 1.}, std::string("pt") + AR::info}; - Filter filterPT = aod::track::pt > cfgPT.value.at(AR::kLCUT) && - aod::track::pt 0.; Configurable> cfgPHI = {std::string(AR::TrackVariableNames[AR::kPHI]), {360., 0., 2. * M_PI, 0., 2. * M_PI, 1.}, std::string("phi") + AR::info}; - Filter filterPHI = aod::track::phi > cfgPHI.value.at(AR::kLCUT) && - aod::track::phi 0.; Configurable> cfgETA = {std::string(AR::TrackVariableNames[AR::kETA]), {1000., -1., 1., -0.8, 0.8, 1.}, std::string("eta") + AR::info}; - Filter filterETA = aod::track::eta > cfgETA.value.at(AR::kLCUT) && - aod::track::eta 0.; Configurable> cfgCHARGE = {std::string(AR::TrackVariableNames[AR::kCHARGE]), {5., -2.5, 2.5, -1.5, 1.5, 1.}, std::string("charge") + AR::info}; Configurable> cfgDCAZ = {std::string(AR::TrackVariableNames[AR::kDCAZ]), {100., -4., 4., -3.2, 3.2, 1.}, std::string("DCA in Z") + AR::info}; - Filter filterDCAZ = aod::track::dcaZ > cfgDCAZ.value.at(AR::kLCUT) && - aod::track::dcaZ 0.; Configurable> cfgDCAXY = {std::string(AR::TrackVariableNames[AR::kDCAXY]), {100., -3., 3., -2.4, 2.4, 1.}, std::string("DCA in XY") + AR::info}; - Filter filterDCAXY = aod::track::dcaXY > cfgDCAXY.value.at(AR::kLCUT) && - aod::track::dcaXY 0.; Configurable> cfgTPCCLUSTERS = {std::string(AR::TrackVariableNames[AR::kTPCCLUSTERS]), {160., 0., 160., 80., 161., 1.}, std::string("TPC clusters") + AR::info}; @@ -278,7 +262,9 @@ struct MultiParticleCorrelationsARTask { } } - // function for filling control histograms of event variables + // function for filling event control histograms + // exclude MultiplicityQ, i.e. number of tracks in the QVector, and + // MultiplicityW, i.e. the weighted number of tracks in the QVector, and fill them separably template void FillEventControlHist(CollisionObject const& collision, HistogramRegistry& registry) { @@ -299,6 +285,9 @@ struct MultiParticleCorrelationsARTask { registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULTPC]), collision.multTPC()); } + + // function for filling event control histograms for Multiplicity{Q,W}, + // since they have to be computed separately template void FillEventControlHistMul(HistogramRegistry& registry, double mulQvector, double mulWeights) { @@ -308,7 +297,7 @@ struct MultiParticleCorrelationsARTask { mulWeights); } - // function for fill control histograms of track variables + // function for filling track control histograms template void FillTrackControlHist(TrackObject const& track, HistogramRegistry& registry) { @@ -334,20 +323,69 @@ struct MultiParticleCorrelationsARTask { track.itsNCls()); } - // templated function for processing data - template - void ProcessReconstructed(CollisionObject const& collision, TrackObject const& tracks) + // function for checking if collision survives event cuts + template + bool SurviveEventCuts(CollisionObject collision, TrackObject tracks, float* reducedMultiplicityQ, float* reducedMultiplicityW) { - // fill event control histograms before cutting on the collision - FillEventControlHist(collision, registry); - // fill multiplicity for qvector and weights separately - FillEventControlHistMul(registry, collision.size(), collision.size()); + bool flag = true; - // loop over all tracks in the event - for (auto const& track : tracks) { - // fill track control histograms before track cut - FillTrackControlHist(track, registry); + // Check if event survives event cuts, where we can get the values for the variables immediately + if (!AR::SurviveCut(cfgVX.value, collision.posX()) || + !AR::SurviveCut(cfgVY.value, collision.posY()) || + !AR::SurviveCut(cfgVZ.value, collision.posZ()) || + !AR::SurviveCut(cfgVABS.value, AR::abs(collision.posX(), collision.posY(), collision.posZ())) || + !AR::SurviveCut(cfgCEN.value, collision.centRun2V0M()) || + !AR::SurviveCut(cfgMULNC.value, collision.numContrib()) || + !AR::SurviveCut(cfgMULTPC.value, collision.multTPC())) { + flag = false; + } + + int MultiplicityQ = 0.; + float MultiplicityW = 0.; + + // only compute Multiplicity{Q,W} if the other checks pass, i.e. our flag is still set to true + if (flag) { + for (auto& track : tracks) { + if (SurviveTrackCuts(track) == true) { + MultiplicityQ += 1.; + MultiplicityW += 1.; + } + } + } + + // update the values for Multiplicity{Q,W}, whose references are passed to this function + *reducedMultiplicityQ = MultiplicityQ; + *reducedMultiplicityW = MultiplicityW; + + // at last, check if event also passes this cut + if (!AR::SurviveCut(cfgMULQ.value, MultiplicityQ) || + !AR::SurviveCut(cfgMULW.value, MultiplicityW)) { + flag = false; } + + return flag; + } + + // function for checking if track survices trach cuts + template + bool SurviveTrackCuts(TrackObject track) + { + bool flag = true; + + if (!AR::SurviveCut(cfgPT.value, track.pt()) || + !AR::SurviveCut(cfgPHI.value, track.phi()) || + !AR::SurviveCut(cfgETA.value, track.eta()) || + !AR::SurviveCut(cfgCHARGE.value, track.sign()) || + !AR::SurviveCut(cfgDCAZ.value, track.dcaZ()) || + !AR::SurviveCut(cfgDCAXY.value, track.dcaXY()) || + !AR::SurviveCut(cfgTPCCLUSTERS.value, track.tpcNClsFound()) || + !AR::SurviveCut(cfgTPCCROSSEDROWS.value, track.tpcNClsCrossedRows()) || + !AR::SurviveCut(cfgTPCCHI2.value, track.tpcChi2NCl()) || + !AR::SurviveCut(cfgITSCLUSTERS.value, track.itsNCls())) { + flag = false; + } + + return flag; } using CollisionsInstance = soa::Join; @@ -356,27 +394,35 @@ struct MultiParticleCorrelationsARTask { using CollisionsInstanceIterator = CollisionsInstance::iterator; // using TracksInstanceIterator = TracksInstance::iterator; - // process reconstructed data before applying cuts - void ProcessReconstructedBeforeCut(CollisionsInstanceIterator const& collision, TracksInstance const& tracks) + void process(CollisionsInstanceIterator const& collision, TracksInstance const& tracks) { - LOGF(info, "Process reconstructed data before applying cuts"); - ProcessReconstructed(collision, tracks); - }; - PROCESS_SWITCH(MultiParticleCorrelationsARTask, ProcessReconstructedBeforeCut, "Process Reco before Cuts", true); + LOGF(info, "Process reconstructed event: %d", collision.index()); - using FilteredCollisionsInstance = soa::Filtered; - using FilteredTracksInstance = soa::Filtered; + FillEventControlHist(collision, registry); + FillEventControlHistMul(registry, collision.size(), collision.size()); - using FilteredCollisionsInstanceIterator = FilteredCollisionsInstance::iterator; - // using FilteredTracksInstanceIterator = FilteredTracksInstance::iterator; + float reducedMultiplicityQ = 0; + float reducedMultiplicityW = 0; - // process reconstructed data after applying cuts - void ProcessReconstructedAfterCut(FilteredCollisionsInstanceIterator const& collision, FilteredTracksInstance const& tracks) - { - LOGF(info, "Process reconstructed data after applying cuts"); - ProcessReconstructed(collision, tracks); - }; - PROCESS_SWITCH(MultiParticleCorrelationsARTask, ProcessReconstructedAfterCut, "Process Reco after Cuts", true); + if (!SurviveEventCuts(collision, tracks, &reducedMultiplicityQ, &reducedMultiplicityW)) { + LOGF(info, "Event was CUT"); + return; + } + + FillEventControlHist(collision, registry); + FillEventControlHistMul(registry, reducedMultiplicityQ, reducedMultiplicityW); + + // loop over all tracks in the event + for (auto const& track : tracks) { + // fill track control histograms before track cut + FillTrackControlHist(track, registry); + if (!SurviveTrackCuts(track)) { + continue; + } + // fill track control histograms after cut + FillTrackControlHist(track, registry); + } + } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) From d725ab26a47f30647d981febdc2eddb387dcd1ee Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Mon, 8 Aug 2022 11:23:42 +0200 Subject: [PATCH 5/6] Feat: add support for calculation Q-vectors --- .../Tasks/multiparticle-correlations-ar.cxx | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx index d31858d552c..ecd0892e399 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include "TComplex.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/Expressions.h" @@ -109,6 +112,9 @@ static constexpr std::string_view TrackVariableNames[kLAST_TrackVariable] = {"Pt // common info string for all configurables std::string info = std::string(": Hist bins, Hist lower edge, Hist upper edge, lower cut, upper cut, cut ON(1)/OFF(-1)"); +const int MaxHarmonic = 10; +const int MaxPower = 10; + // function for computing the absolute distance of the primary vertex form the origin inline float abs(float vx, float vy, float vz) { @@ -225,6 +231,13 @@ struct MultiParticleCorrelationsARTask { false, false}; + // declare 2d array for qvectors + std::array, AR::MaxPower> QVectors; + + // declare objects for computing qvectors + std::vector Angles; + std::vector Weights; + void init(InitContext&) { @@ -325,7 +338,7 @@ struct MultiParticleCorrelationsARTask { // function for checking if collision survives event cuts template - bool SurviveEventCuts(CollisionObject collision, TrackObject tracks, float* reducedMultiplicityQ, float* reducedMultiplicityW) + bool SurviveEventCuts(CollisionObject collision, TrackObject tracks) { bool flag = true; @@ -353,10 +366,6 @@ struct MultiParticleCorrelationsARTask { } } - // update the values for Multiplicity{Q,W}, whose references are passed to this function - *reducedMultiplicityQ = MultiplicityQ; - *reducedMultiplicityW = MultiplicityW; - // at last, check if event also passes this cut if (!AR::SurviveCut(cfgMULQ.value, MultiplicityQ) || !AR::SurviveCut(cfgMULW.value, MultiplicityW)) { @@ -388,6 +397,33 @@ struct MultiParticleCorrelationsARTask { return flag; } + // Calculate all Q-vectors + void CalculateQvectors() + { + // Make sure all Q-vectors are initially zero + for (int h = 0; h < AR::MaxHarmonic; h++) { + for (int p = 0; p < AR::MaxPower; p++) { + QVectors[h][p] = TComplex(0., 0.); + } + } + + // Calculate Q-vectors for available angles and weights + double dPhi = 0.; + double wPhi = 1.; // particle weight + double wPhiToPowerP = 1.; // particle weight raised to power p + for (std::size_t i = 0; i < Angles.size(); i++) { + dPhi = Angles.at(i); + wPhi = Weights.at(i); + for (int h = 0; h < AR::MaxHarmonic; h++) { + for (int p = 0; p < AR::MaxPower; p++) { + wPhiToPowerP = TMath::Power(wPhi, p); + QVectors[h][p] += TComplex(wPhiToPowerP * TMath::Cos(h * dPhi), + wPhiToPowerP * TMath::Sin(h * dPhi)); + } + } + } + } + using CollisionsInstance = soa::Join; using TracksInstance = soa::Join; @@ -396,21 +432,22 @@ struct MultiParticleCorrelationsARTask { void process(CollisionsInstanceIterator const& collision, TracksInstance const& tracks) { + + // clear angles and weights + Angles.clear(); + Weights.clear(); + LOGF(info, "Process reconstructed event: %d", collision.index()); FillEventControlHist(collision, registry); FillEventControlHistMul(registry, collision.size(), collision.size()); - float reducedMultiplicityQ = 0; - float reducedMultiplicityW = 0; - - if (!SurviveEventCuts(collision, tracks, &reducedMultiplicityQ, &reducedMultiplicityW)) { + if (!SurviveEventCuts(collision, tracks)) { LOGF(info, "Event was CUT"); return; } FillEventControlHist(collision, registry); - FillEventControlHistMul(registry, reducedMultiplicityQ, reducedMultiplicityW); // loop over all tracks in the event for (auto const& track : tracks) { @@ -421,7 +458,16 @@ struct MultiParticleCorrelationsARTask { } // fill track control histograms after cut FillTrackControlHist(track, registry); + + // fill angles into vector for processing + Angles.push_back(track.phi()); + Weights.push_back(1.); } + + FillEventControlHistMul(registry, Angles.size(), std::accumulate(Weights.begin(), Weights.end(), 0.)); + + // calculate qvectors from filled angles and weights + CalculateQvectors(); } }; From 2a2e285e093fd964b53e720e6d5ccd6762808674 Mon Sep 17 00:00:00 2001 From: Anton Riedel Date: Tue, 9 Aug 2022 16:24:19 +0200 Subject: [PATCH 6/6] Fix: Implement comments from PR - rename Enums for better readability - Change Survive{Event,Track}Cuts to remove unnecessary flag --- .../Tasks/multiparticle-correlations-ar.cxx | 74 ++++++++----------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx index ecd0892e399..06f103cd1e5 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ar.cxx @@ -36,7 +36,7 @@ using namespace o2::framework::expressions; namespace MultiParticleCorrelationsARTaskGlobalVariables { // for before and after applying cuts -enum BA { +enum BeforeAfterEnum { kBEFORE, kAFTER, kLAST_BA @@ -44,7 +44,7 @@ enum BA { static constexpr std::string_view BeforeAfter[kLAST_BA] = {"before/", "after/"}; // for reconstructed and simulated data -enum RS { +enum RecoSimEnum { kRECO, kSIM, kLAST_RS @@ -278,7 +278,7 @@ struct MultiParticleCorrelationsARTask { // function for filling event control histograms // exclude MultiplicityQ, i.e. number of tracks in the QVector, and // MultiplicityW, i.e. the weighted number of tracks in the QVector, and fill them separably - template + template void FillEventControlHist(CollisionObject const& collision, HistogramRegistry& registry) { registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kVX]), @@ -301,7 +301,7 @@ struct MultiParticleCorrelationsARTask { // function for filling event control histograms for Multiplicity{Q,W}, // since they have to be computed separately - template + template void FillEventControlHistMul(HistogramRegistry& registry, double mulQvector, double mulWeights) { registry.fill(HIST(AR::RecoSim[rs]) + HIST("EventControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::EventVariableNames[AR::kMULQ]), @@ -311,7 +311,7 @@ struct MultiParticleCorrelationsARTask { } // function for filling track control histograms - template + template void FillTrackControlHist(TrackObject const& track, HistogramRegistry& registry) { registry.fill(HIST(AR::RecoSim[rs]) + HIST("TrackControl/") + HIST(AR::BeforeAfter[ba]) + HIST(AR::TrackVariableNames[AR::kPT]), @@ -340,61 +340,49 @@ struct MultiParticleCorrelationsARTask { template bool SurviveEventCuts(CollisionObject collision, TrackObject tracks) { - bool flag = true; // Check if event survives event cuts, where we can get the values for the variables immediately - if (!AR::SurviveCut(cfgVX.value, collision.posX()) || - !AR::SurviveCut(cfgVY.value, collision.posY()) || - !AR::SurviveCut(cfgVZ.value, collision.posZ()) || - !AR::SurviveCut(cfgVABS.value, AR::abs(collision.posX(), collision.posY(), collision.posZ())) || - !AR::SurviveCut(cfgCEN.value, collision.centRun2V0M()) || - !AR::SurviveCut(cfgMULNC.value, collision.numContrib()) || - !AR::SurviveCut(cfgMULTPC.value, collision.multTPC())) { - flag = false; + if (!(AR::SurviveCut(cfgVX.value, collision.posX()) && + AR::SurviveCut(cfgVY.value, collision.posY()) && + AR::SurviveCut(cfgVZ.value, collision.posZ()) && + AR::SurviveCut(cfgVABS.value, AR::abs(collision.posX(), collision.posY(), collision.posZ())) && + AR::SurviveCut(cfgCEN.value, collision.centRun2V0M()) && + AR::SurviveCut(cfgMULNC.value, collision.numContrib()) && + AR::SurviveCut(cfgMULTPC.value, collision.multTPC()))) { + return false; } int MultiplicityQ = 0.; float MultiplicityW = 0.; // only compute Multiplicity{Q,W} if the other checks pass, i.e. our flag is still set to true - if (flag) { - for (auto& track : tracks) { - if (SurviveTrackCuts(track) == true) { - MultiplicityQ += 1.; - MultiplicityW += 1.; - } + for (auto& track : tracks) { + if (SurviveTrackCuts(track) == true) { + MultiplicityQ += 1.; + MultiplicityW += 1.; } } - // at last, check if event also passes this cut - if (!AR::SurviveCut(cfgMULQ.value, MultiplicityQ) || - !AR::SurviveCut(cfgMULW.value, MultiplicityW)) { - flag = false; - } - - return flag; + // at last, check if event also passes multiplicity cuts + return AR::SurviveCut(cfgMULQ.value, MultiplicityQ) && AR::SurviveCut(cfgMULW.value, MultiplicityW); } // function for checking if track survices trach cuts template bool SurviveTrackCuts(TrackObject track) { - bool flag = true; - - if (!AR::SurviveCut(cfgPT.value, track.pt()) || - !AR::SurviveCut(cfgPHI.value, track.phi()) || - !AR::SurviveCut(cfgETA.value, track.eta()) || - !AR::SurviveCut(cfgCHARGE.value, track.sign()) || - !AR::SurviveCut(cfgDCAZ.value, track.dcaZ()) || - !AR::SurviveCut(cfgDCAXY.value, track.dcaXY()) || - !AR::SurviveCut(cfgTPCCLUSTERS.value, track.tpcNClsFound()) || - !AR::SurviveCut(cfgTPCCROSSEDROWS.value, track.tpcNClsCrossedRows()) || - !AR::SurviveCut(cfgTPCCHI2.value, track.tpcChi2NCl()) || - !AR::SurviveCut(cfgITSCLUSTERS.value, track.itsNCls())) { - flag = false; - } - - return flag; + // if all SurviveCut return true, the function will return true + // if at least one fails, it will return false + return AR::SurviveCut(cfgPT.value, track.pt()) && + AR::SurviveCut(cfgPHI.value, track.phi()) && + AR::SurviveCut(cfgETA.value, track.eta()) && + AR::SurviveCut(cfgCHARGE.value, track.sign()) && + AR::SurviveCut(cfgDCAZ.value, track.dcaZ()) && + AR::SurviveCut(cfgDCAXY.value, track.dcaXY()) && + AR::SurviveCut(cfgTPCCLUSTERS.value, track.tpcNClsFound()) && + AR::SurviveCut(cfgTPCCROSSEDROWS.value, track.tpcNClsCrossedRows()) && + AR::SurviveCut(cfgTPCCHI2.value, track.tpcChi2NCl()) && + AR::SurviveCut(cfgITSCLUSTERS.value, track.itsNCls()); } // Calculate all Q-vectors