diff --git a/Analysis/Tasks/PWGLF/cascadefinder.cxx b/Analysis/Tasks/PWGLF/cascadefinder.cxx index 224e5ef253c0c..4ee368dc41d15 100644 --- a/Analysis/Tasks/PWGLF/cascadefinder.cxx +++ b/Analysis/Tasks/PWGLF/cascadefinder.cxx @@ -97,6 +97,7 @@ struct cascadeprefilter { Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; Configurable dcav0topv{"dcav0topv", .1, "DCA V0 To PV"}; Configurable cospaV0{"cospaV0", .98, "CosPA V0"}; + Configurable v0radius{"v0radius", 0.9, "v0radius"}; Configurable lambdamasswindow{"lambdamasswindow", .006, "Distance from Lambda mass"}; Configurable dcav0dau{"dcav0dau", .6, "DCA V0 Daughters"}; Configurable dcanegtopv{"dcanegtopv", .1, "DCA Neg To PV"}; @@ -143,6 +144,12 @@ struct cascadeprefilter { if (v0.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < dcav0topv) { continue; } + if (v0.dcaV0daughters() > dcav0dau) { + continue; + } + if (v0.v0radius() < v0radius) { + continue; + } if (fabs(v0.mLambda() - 1.116) < lambdamasswindow) { cascGoodLambdas(v0.globalIndex(), v0.collisionId()); diff --git a/Analysis/Tasks/PWGLF/cascadeproducer.cxx b/Analysis/Tasks/PWGLF/cascadeproducer.cxx index 4fdb3fff6251e..8cf1076b778a4 100644 --- a/Analysis/Tasks/PWGLF/cascadeproducer.cxx +++ b/Analysis/Tasks/PWGLF/cascadeproducer.cxx @@ -17,6 +17,14 @@ // Any analysis should loop over the "CascData" // table as that table contains all information // +// WARNING: adding filters to the producer IS NOT +// equivalent to re-running the finders. This will only +// ever produce *tighter* selection sections. It is your +// responsibility to check if, by setting a loose filter +// setting, you are going into a region in which no +// candidates exist because the original indices were generated +// using tigher selections. +// // Comments, questions, complaints, suggestions? // Please write to: // david.dobrigkeit.chinellato@cern.ch @@ -31,6 +39,8 @@ #include "ReconstructionDataFormats/Track.h" #include "Analysis/RecoDecay.h" #include "Analysis/trackUtilities.h" +#include "Analysis/TrackSelection.h" +#include "Analysis/TrackSelectionTables.h" #include "Analysis/StrangenessTables.h" #include @@ -51,6 +61,94 @@ using namespace o2::framework; using namespace o2::framework::expressions; using std::array; +namespace o2::aod +{ + +namespace cascgood +{ +DECLARE_SOA_INDEX_COLUMN_FULL(V0, v0, int, V0DataExt, "fV0Id"); +DECLARE_SOA_INDEX_COLUMN_FULL(Bachelor, bachelor, int, FullTracks, "fTracksID"); +DECLARE_SOA_INDEX_COLUMN(Collision, collision); +} // namespace cascgood +DECLARE_SOA_TABLE(CascGood, "AOD", "CASCGOOD", o2::soa::Index<>, + cascgood::V0Id, cascgood::BachelorId, + cascgood::CollisionId); +} // namespace o2::aod + +using FullTracksExt = soa::Join; + +//This prefilter creates a skimmed list of good V0s to re-reconstruct so that +//CPU is saved in case there are specific selections that are to be done +//Note: more configurables, more options to be added as needed +struct cascadeprefilterpairs { + Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; + Configurable dcav0topv{"dcav0topv", .1, "DCA V0 To PV"}; + Configurable cospaV0{"cospaV0", .98, "CosPA V0"}; + Configurable lambdamasswindow{"lambdamasswindow", .006, "Distance from Lambda mass"}; + Configurable dcav0dau{"dcav0dau", .6, "DCA V0 Daughters"}; + Configurable dcanegtopv{"dcanegtopv", .1, "DCA Neg To PV"}; + Configurable dcapostopv{"dcapostopv", .1, "DCA Pos To PV"}; + Configurable dcabachtopv{"dcabachtopv", .1, "DCA Bach To PV"}; + Configurable tpcrefit{"tpcrefit", 1, "demand TPC refit"}; + Configurable v0radius{"v0radius", 0.9, "v0radius"}; + + Produces cascgood; + void process(aod::Collision const& collision, aod::V0DataExt const& V0s, aod::Cascades const& Cascades, + soa::Join const& tracks) + { + for (auto& casc : Cascades) { + //Single-track properties filter + if (tpcrefit) { + if (!(casc.v0().posTrack().flags() & 0x40)) { + continue; //TPC refit + } + if (!(casc.v0().negTrack().flags() & 0x40)) { + continue; //TPC refit + } + if (!(casc.bachelor().flags() & 0x40)) { + continue; //TPC refit + } + } + if (casc.v0().posTrack().tpcNClsCrossedRows() < mincrossedrows) { + continue; + } + if (casc.v0().negTrack().tpcNClsCrossedRows() < mincrossedrows) { + continue; + } + if (casc.bachelor().tpcNClsCrossedRows() < mincrossedrows) { + continue; + } + if (casc.v0().posTrack_as().dcaXY() < dcapostopv) { + continue; + } + if (casc.v0().negTrack_as().dcaXY() < dcanegtopv) { + continue; + } + if (casc.bachelor_as().dcaXY() < dcabachtopv) { + continue; + } + + //V0 selections + if (fabs(casc.v0_as().mLambda() - 1.116) > lambdamasswindow && fabs(casc.v0_as().mAntiLambda() - 1.116) > lambdamasswindow) { + continue; + } + if (casc.v0_as().dcaV0daughters() > dcav0dau) { + continue; + } + if (casc.v0_as().v0radius() < v0radius) { + continue; + } + if (casc.v0_as().v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cospaV0) { + continue; + } + if (casc.v0_as().dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < dcav0topv) { + continue; + } + cascgood(casc.v0().globalIndex(), casc.bachelor().globalIndex(), casc.bachelor().collisionId()); + } + } +}; + /// Cascade builder task: rebuilds cascades struct cascadeproducer { Produces cascdata; @@ -62,21 +160,7 @@ struct cascadeproducer { Configurable d_bz{"d_bz", -5.0, "bz field"}; Configurable d_UseAbsDCA{"d_UseAbsDCA", kTRUE, "Use Abs DCAs"}; - /// Extracts dca in the XY plane - /// \return dcaXY - template - auto getdcaXY(const T& track, const U& coll) - { - //Calculate DCAs - auto sinAlpha = sin(track.alpha()); - auto cosAlpha = cos(track.alpha()); - auto globalX = track.x() * cosAlpha - track.y() * sinAlpha; - auto globalY = track.x() * sinAlpha + track.y() * cosAlpha; - return sqrt(pow((globalX - coll[0]), 2) + - pow((globalY - coll[1]), 2)); - } - - void process(aod::Collision const& collision, aod::V0s const& V0s, aod::Cascades const& Cascades, aod::FullTracks const& trackss) + void process(aod::Collision const& collision, aod::V0DataExt const& V0s, aod::CascGood const& Cascades, aod::FullTracks const& tracks) { //Define o2 fitter, 2-prong o2::vertexing::DCAFitterN<2> fitterV0, fitterCasc; @@ -173,15 +257,22 @@ struct cascadeproducer { pvecneg[0], pvecneg[1], pvecneg[2], pvecbach[0], pvecbach[1], pvecbach[2], fitterV0.getChi2AtPCACandidate(), fitterCasc.getChi2AtPCACandidate(), - getdcaXY(casc.v0().posTrack(), pVtx), - getdcaXY(casc.v0().negTrack(), pVtx), - getdcaXY(casc.bachelor(), pVtx)); + casc.v0().posTrack_as().dcaXY(), + casc.v0().negTrack_as().dcaXY(), + casc.bachelor_as().dcaXY()); } } }; +/// Extends the v0data table with expression columns +struct cascprodinitializer { + Spawns v0dataext; + void init(InitContext const&) {} +}; + WorkflowSpec defineDataProcessing(ConfigContext const&) { return WorkflowSpec{ + adaptAnalysisTask("lf-cascprodinitializer"), adaptAnalysisTask("lf-cascadeproducer")}; } diff --git a/Analysis/Tasks/PWGLF/lambdakzeroproducer.cxx b/Analysis/Tasks/PWGLF/lambdakzeroproducer.cxx index 349ac70069117..b3b330ff366dc 100644 --- a/Analysis/Tasks/PWGLF/lambdakzeroproducer.cxx +++ b/Analysis/Tasks/PWGLF/lambdakzeroproducer.cxx @@ -17,6 +17,14 @@ // Any analysis should loop over the "V0Data" // table as that table contains all information // +// WARNING: adding filters to the producer IS NOT +// equivalent to re-running the finders. This will only +// ever produce *tighter* selection sections. It is your +// responsibility to check if, by setting a loose filter +// setting, you are going into a region in which no +// candidates exist because the original indices were generated +// using tigher selections. +// // Comments, questions, complaints, suggestions? // Please write to: // david.dobrigkeit.chinellato@cern.ch