diff --git a/Common/DataModel/CMakeLists.txt b/Common/DataModel/CMakeLists.txt
index 312e9c15225..f4428d908c0 100644
--- a/Common/DataModel/CMakeLists.txt
+++ b/Common/DataModel/CMakeLists.txt
@@ -20,4 +20,5 @@ o2physics_add_header_only_library(DataModel
                                           TrackSelectionTables.h
                                           McCollisionExtra.h
                                           Qvectors.h
+                                          MatchMFTFT0.h
                                           MftmchMatchingML.h)
diff --git a/Common/DataModel/MatchMFTFT0.h b/Common/DataModel/MatchMFTFT0.h
new file mode 100644
index 00000000000..21ee19b696f
--- /dev/null
+++ b/Common/DataModel/MatchMFTFT0.h
@@ -0,0 +1,34 @@
+// 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   MatchMFTFT0.h
+// \author Sarah Herrmann <sarah.herrmann@cern.ch>
+//
+// \brief  Declaration of tables useful for the matching of MFT tracks to FT0-C signals
+// \date   03/09/24
+
+#include "Framework/AnalysisDataModel.h"
+
+namespace o2::aod
+{
+namespace indices
+{                                          // For bctoft0c
+DECLARE_SOA_ARRAY_INDEX_COLUMN(FT0, ft0s); // has_ft0s works now, without it doesn't
+DECLARE_SOA_ARRAY_INDEX_COLUMN(BC, bcs);   // has_bcs works now, without it doesn't
+} // namespace indices
+namespace ambii
+{ // for MA2T
+DECLARE_SOA_INDEX_COLUMN(MFTTrack, track);
+} // namespace ambii
+DECLARE_SOA_TABLE(MatchedToFT0, "AOD", "MAFT", indices::BCId, indices::FT0Ids);
+
+DECLARE_SOA_TABLE(BCofMFT, "AOD", "BCOFMFT", ambii::MFTTrackId, indices::BCIds);
+} // namespace o2::aod
diff --git a/Common/DataModel/Multiplicity.h b/Common/DataModel/Multiplicity.h
index 03c4888440d..19ef25b0591 100644
--- a/Common/DataModel/Multiplicity.h
+++ b/Common/DataModel/Multiplicity.h
@@ -107,6 +107,7 @@ DECLARE_SOA_TABLE(PVMults, "AOD", "PVMULT", //! Multiplicity from the PV contrib
                   mult::IsInelGt1<mult::MultNTracksPVeta1>);
 using BarrelMults = soa::Join<TrackletMults, TPCMults, PVMults>;
 using Mults = soa::Join<BarrelMults, FV0Mults, FT0Mults, FDDMults, ZDCMults>;
+using FT0Mult = FT0Mults::iterator;
 using Mult = Mults::iterator;
 
 DECLARE_SOA_TABLE(MultsExtra, "AOD", "MULTEXTRA", //!
@@ -129,7 +130,9 @@ DECLARE_SOA_TABLE(MultsGlobal, "AOD", "MULTGLOBAL", //! counters that use Track
 DECLARE_SOA_TABLE(MultSelections, "AOD", "MULTSELECTIONS", //!
                   evsel::Selection);                       // for derived data / QA studies
 using MultExtra = MultsExtra::iterator;
-DECLARE_SOA_TABLE(MultsExtraMC, "AOD", "MULTEXTRAMC", //! Table for the MC information
+
+// mc collisions table - indexed to Mult
+DECLARE_SOA_TABLE(MultMCExtras, "AOD", "MULTMCEXTRA", //! Table for the MC information
                   mult::MultMCFT0A,
                   mult::MultMCFT0C,
                   mult::MultMCNParticlesEta05,
@@ -139,7 +142,17 @@ DECLARE_SOA_TABLE(MultsExtraMC, "AOD", "MULTEXTRAMC", //! Table for the MC infor
                   mult::IsInelGt0<mult::MultMCNParticlesEta10>,
                   mult::IsInelGt1<mult::MultMCNParticlesEta10>,
                   o2::soa::Marker<1>);
-using MultExtraMC = MultsExtraMC::iterator;
+using MultMCExtra = MultMCExtras::iterator;
+using MultsExtraMC = MultMCExtras; // for backwards compatibility with previous naming scheme
+
+// crosslinks
+namespace mult
+{
+DECLARE_SOA_INDEX_COLUMN(MultMCExtra, multMCExtra);
+}
+
+DECLARE_SOA_TABLE(MC2Mults, "AOD", "MC2MULTS", //! Relate BC -> mult
+                  o2::soa::Index<>, mult::MultMCExtraId);
 
 namespace multZeq
 {
@@ -218,14 +231,14 @@ DECLARE_SOA_INDEX_COLUMN(MultBC, multBC);
 }
 namespace multBC
 {
-DECLARE_SOA_INDEX_COLUMN(Mult, mult);
+DECLARE_SOA_INDEX_COLUMN(FT0Mult, ft0Mult);
 }
 
 // for QA purposes
 DECLARE_SOA_TABLE(Mults2BC, "AOD", "MULTS2BC", //! Relate mult -> BC
                   o2::soa::Index<>, mult::MultBCId);
 DECLARE_SOA_TABLE(BC2Mults, "AOD", "BC2MULTS", //! Relate BC -> mult
-                  o2::soa::Index<>, multBC::MultId);
+                  o2::soa::Index<>, multBC::FT0MultId);
 
 } // namespace o2::aod
 
diff --git a/Common/TableProducer/CMakeLists.txt b/Common/TableProducer/CMakeLists.txt
index 7cd53628f18..399ba4b4fa6 100644
--- a/Common/TableProducer/CMakeLists.txt
+++ b/Common/TableProducer/CMakeLists.txt
@@ -112,3 +112,10 @@ o2physics_add_dpl_workflow(mftmchmatchingml
                                           O2::CCDB O2Physics::MLCore
                                           O2::ReconstructionDataFormats
                     COMPONENT_NAME Analysis)
+
+o2physics_add_dpl_workflow(match-mft-ft0
+                    SOURCES match-mft-ft0.cxx
+                    PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
+                                          O2::ReconstructionDataFormats
+                                          O2::DetectorsBase O2::DetectorsCommonDataFormats
+                    COMPONENT_NAME Analysis)
diff --git a/Common/TableProducer/match-mft-ft0.cxx b/Common/TableProducer/match-mft-ft0.cxx
new file mode 100644
index 00000000000..268548255cd
--- /dev/null
+++ b/Common/TableProducer/match-mft-ft0.cxx
@@ -0,0 +1,554 @@
+// 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   match-mft-ft0.cxx
+// \author Sarah Herrmann <sarah.herrmann@cern.ch>
+//
+// \brief This code loops over every MFT tracks (except orphan tracks) and propagates
+//        them to the FT0-C, matching the signals in some BC to reduce track ambiguity
+//        It produces a table containing for each MFT track a list of BCs with an FT0C match
+//        called aod::BCofMFT
+// \date 03/09/24
+
+#include "Framework/runDataProcessing.h"
+#include "Framework/AnalysisTask.h"
+
+#include "MathUtils/Utils.h"
+#include "CommonConstants/LHCConstants.h"
+#include "Common/Core/trackUtilities.h"         //for getTrackPar()
+#include "ReconstructionDataFormats/TrackFwd.h" //for propagate
+// https://github.com/AliceO2Group/AliceO2/blob/dev/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackFwd.h
+#include "CommonConstants/LHCConstants.h"
+#include "Math/MatrixFunctions.h"
+#include "Math/SMatrix.h"
+
+#include "CCDB/BasicCCDBManager.h"
+#include "CCDB/CcdbApi.h"
+
+#include "DataFormatsParameters/GRPMagField.h"
+#include "DetectorsBase/GeometryManager.h"
+#include "Field/MagneticField.h"
+#include "TGeoGlobalMagField.h"
+
+#include "DataFormatsParameters/GRPMagField.h"
+#include "DetectorsBase/GeometryManager.h"
+#include "DetectorsBase/Propagator.h"
+
+#include "Common/DataModel/MatchMFTFT0.h"
+
+using SMatrix55 = ROOT::Math::SMatrix<double, 5, 5, ROOT::Math::MatRepSym<double, 5>>;
+using SMatrix5 = ROOT::Math::SVector<Double_t, 5>;
+
+using namespace o2;
+using namespace o2::framework;
+
+// Creating a table BC to FT0 and filling it
+struct bctoft0c {
+  Produces<aod::MatchedToFT0> mf;
+  struct {
+    std::vector<int> ft0ids;
+  } filler;
+  void process(aod::BCs::iterator const& bc, soa::SmallGroups<aod::FT0s> const& ft0s)
+  {
+    filler.ft0ids.clear();
+    for (auto const& ft0 : ft0s) {
+      filler.ft0ids.emplace_back(ft0.globalIndex());
+    }
+    mf(bc.globalIndex(), filler.ft0ids);
+  }
+};
+
+using ExtBCs = soa::Join<aod::BCs, aod::Timestamps, aod::MatchedToFT0>;
+
+template <typename T>
+T getCompatibleBCs(aod::AmbiguousMFTTrack const& atrack, aod::Collision const& collOrig, T const& bcs, int deltaBC)
+{
+  // this method is unused for now, MFTtracks with no collisions (orphan tracks) are not considered for the matching with FT0C
+  auto compBCs = atrack.bc_as<T>(); // BC + info on FT0
+  auto bcIter = compBCs.begin();    // first element of compBC
+  uint64_t firstBC = bcIter.globalBC();
+
+  bcIter.moveToEnd();                  // does it move to the end or the next one after the end ?
+  --bcIter;                            // to avoid a seg fault
+  uint64_t lastBC = bcIter.globalBC(); // gives the last COMPATIBLE BC in compBCs
+
+  auto bcIt = collOrig.bc_as<T>();
+
+  int64_t minBCId = bcIt.globalIndex();
+  auto minGlobalBC = bcIt.globalBC();
+
+  if (bcIt.globalBC() < firstBC + deltaBC) {
+    while (bcIt != bcs.end() && bcIt.globalBC() < firstBC + deltaBC) {
+      minBCId = bcIt.globalIndex();
+      minGlobalBC = bcIt.globalBC();
+
+      ++bcIt;
+    }
+    if (bcIt == bcs.end()) {
+      --bcIt;
+      minBCId = bcIt.globalIndex();
+      minGlobalBC = bcIt.globalBC();
+    }
+  } else {
+    // here bcIt.globalBC() >= firstBC + deltaBC
+
+    while (bcIt != bcs.begin() && bcIt.globalBC() > firstBC + deltaBC) {
+      minBCId = bcIt.globalIndex();
+      minGlobalBC = bcIt.globalBC();
+
+      --bcIt;
+    }
+  }
+
+  int64_t maxBCId = bcIt.globalIndex();
+  auto maxGlobalBC = bcIt.globalBC();
+
+  while (bcIt != bcs.end() && bcIt.globalBC() < lastBC + deltaBC) {
+    maxBCId = bcIt.globalIndex();
+    maxGlobalBC = bcIt.globalBC();
+
+    ++bcIt;
+  }
+
+  if (bcIt != bcs.end() && maxBCId >= minBCId) {
+    T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, (uint64_t)minBCId};
+    bcs.copyIndexBindings(slice);
+    return slice;
+  } else {
+    T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId)}, (uint64_t)minBCId};
+    bcs.copyIndexBindings(slice);
+    return slice;
+  }
+}
+
+template <typename T>
+T getCompatibleBCs(aod::MFTTracks::iterator const& track, aod::Collision const& collOrig, T const& bcs, int deltaBC)
+{
+
+  // define firstBC and lastBC (globalBC of beginning and end of the range, when no shift is applied)
+
+  auto bcIt = collOrig.bc_as<T>();
+  // auto timstp = bcIt.timestamp();
+
+  int64_t firstBC = bcIt.globalBC() + (track.trackTime() - track.trackTimeRes()) / o2::constants::lhc::LHCBunchSpacingNS;
+  int64_t lastBC = firstBC + 2 * track.trackTimeRes() / o2::constants::lhc::LHCBunchSpacingNS + 1; // to have a delta = 198 BC
+
+  // printf(">>>>>>>>>>>>>>>>>>>>>>>>>>> last-first %lld\n", lastBC-firstBC);
+
+  // int collTimeResInBC = collOrig.collisionTimeRes()/o2::constants::lhc::LHCBunchSpacingNS;
+
+  // int64_t collFirstBC = bcIt.globalBC() + (collOrig.collisionTime() - collOrig.collisionTimeRes())/o2::constants::lhc::LHCBunchSpacingNS;
+  // int64_t collLastBC = collFirstBC + 2*collOrig.collisionTimeRes()/o2::constants::lhc::LHCBunchSpacingNS +1;
+
+  int64_t minBCId = bcIt.globalIndex();
+  uint64_t minGlobalBC = bcIt.globalBC();
+
+  if ((int64_t)bcIt.globalBC() < firstBC + deltaBC) {
+    while (bcIt != bcs.end() && (int64_t)bcIt.globalBC() < firstBC + deltaBC) {
+      minBCId = bcIt.globalIndex();
+      minGlobalBC = bcIt.globalBC();
+
+      ++bcIt;
+    }
+    if (bcIt == bcs.end()) {
+      --bcIt;
+      // allows to avoid bcIt==bcs.end() in the following
+    }
+    // minGlobalBC needs to be >= to firstBC+deltaBC
+    minBCId = bcIt.globalIndex();
+    minGlobalBC = bcIt.globalBC();
+
+  } else {
+    // here bcIt.globalBC() >= firstBC + deltaBC
+
+    while (bcIt != bcs.begin() && (int64_t)bcIt.globalBC() >= (int64_t)firstBC + deltaBC) {
+      minBCId = bcIt.globalIndex();
+      minGlobalBC = bcIt.globalBC();
+      --bcIt;
+    }
+    if (bcIt == bcs.begin() && (int64_t)bcIt.globalBC() >= (int64_t)firstBC + deltaBC) {
+      minBCId = bcIt.globalIndex();
+      minGlobalBC = bcIt.globalBC();
+    }
+    ++bcIt; // retrieve the pointer which gave minBCId and minGlobalBC
+    if (bcIt == bcs.end()) {
+      --bcIt; // go back if we got to the end of the list
+    }
+  }
+
+  int64_t maxBCId = bcIt.globalIndex();
+  uint64_t maxGlobalBC = bcIt.globalBC();
+
+  if ((int64_t)bcIt.globalBC() > (int64_t)lastBC + deltaBC) {
+    // the previous minimum is actually bigger than the right boundary
+
+    if (bcIt != bcs.begin()) {
+      --bcIt;                                                    // let's check the previous element in the BC list
+      if ((int64_t)bcIt.globalBC() < (int64_t)firstBC + deltaBC) // if this previous element is smaller than the left boundary
+      {
+        // means that the slice of compatible BCs is empty
+
+        T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0};
+        // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE
+        return slice; // returns an empty slice
+      }
+    }
+  }
+
+  if ((int64_t)bcIt.globalBC() < (int64_t)firstBC + deltaBC) {
+    // the previous minimum is actually smaller than the right boundary
+    ++bcIt;
+
+    if (bcIt != bcs.end() && ((int64_t)bcIt.globalBC() > (int64_t)lastBC + deltaBC)) {
+      // check the following element
+
+      T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0};
+      // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE
+      return slice; // returns an empty slice
+    }
+  }
+
+  while (bcIt != bcs.end() && (int64_t)bcIt.globalBC() <= (int64_t)lastBC + deltaBC) {
+    maxBCId = bcIt.globalIndex();
+    maxGlobalBC = bcIt.globalBC();
+
+    ++bcIt;
+  }
+
+  if (maxBCId < minBCId) {
+    if (bcIt == bcs.end()) {
+      printf("at the end of the bcs iterator %d\n", 1);
+    }
+    T slice{{bcs.asArrowTable()->Slice(0, 0)}, (uint64_t)0};
+    // bcs.copyIndexBindings(slice); REMOVED IT BECAUSE I DON'T KNOW WHAT IT DOES HERE
+    return slice; // returns an empty slice
+  }
+
+  T slice{{bcs.asArrowTable()->Slice(minBCId, maxBCId - minBCId + 1)}, (uint64_t)minBCId};
+  bcs.copyIndexBindings(slice);
+  return slice;
+}
+
+struct matchmftft0 {
+  Produces<aod::BCofMFT> BcMft;
+  struct {
+    std::vector<int> BCids;
+  } filler;
+
+  Service<o2::ccdb::BasicCCDBManager> ccdb;
+
+  int runNumber = -1;
+  float Bz = 0;                                         // Magnetic field for MFT
+  static constexpr double centerMFT[3] = {0, 0, -61.4}; // Field at center of MFT
+  int count = 0;
+  o2::parameters::GRPMagField* grpmag = nullptr;
+
+  Configurable<bool> strictBCSel{"strictBCSel", false, "force the BC of the match to have FT0A&C signals"};
+  Configurable<int> shiftBC{"shiftBC", 0, "shift in BC wrt normal"}; // should be kept at zero except if the time-alignment MFT-FT0C must be redone
+
+  Configurable<std::string> ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
+  Configurable<std::string> geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"};
+  Configurable<std::string> grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};
+
+  std::vector<std::vector<float>> channelCoord = {{103.2, 17.8, -813.1}, {76.9, 17.8, -815.9}, {103.1, 44.2, -812.1}, {76.8, 44.2, -814.9}, {103.2, 78.7, -810}, {76.8, 79, -812.9}, {103.2, 105, -807.1}, {76.8, 105.3, -810}, {43.2, 78.8, -815}, {43.2, 105.1, -812.1}, {16.8, 78.9, -815.9}, {16.8, 105.2, -813}, {-16.8, 105.2, -813}, {-16.8, 78.9, -815.9}, {-43.2, 105.1, -812.1}, {-43.2, 78.8, -815}, {-76.8, 105.3, -810}, {-76.8, 79, -812.9}, {-103.2, 105, -807.1}, {-103.2, 78.7, -810}, {-76.8, 44.2, -814.9}, {-103.1, 44.2, -812.1}, {-76.9, 17.8, -815.9}, {-103.2, 17.8, -813.1}, {-103.2, -17.8, -813.1}, {-76.9, -17.8, -815.9}, {-103.1, -44.2, -812.1}, {-76.8, -44.2, -814.9}, {-103.2, -78.7, -810}, {-76.8, -79, -812.9}, {-103.2, -105, -807.1}, {-76.8, -105.3, -810}, {-43.2, -78.8, -815}, {-43.2, -105.1, -812.1}, {-16.8, -78.9, -815.9}, {-16.8, -105.2, -813}, {16.8, -105.2, -813}, {16.8, -78.9, -815.9}, {43.2, -105.1, -812.1}, {43.2, -78.8, -815}, {76.8, -105.3, -810}, {76.8, -79, -812.9}, {103.2, -105, -807.1}, {103.2, -78.7, -810}, {76.8, -44.2, -814.9}, {103.1, -44.2, -812.1}, {76.9, -17.8, -815.9}, {103.2, -17.8, -813.1}, {163, 18.7, -804.1}, {137, 18.9, -808.9}, {163, 45.2, -803.1}, {137, 45.3, -807.9}, {163, 78.6, -800.1}, {137, 79.1, -804.9}, {163, 104.9, -797.2}, {137, 105.4, -801.9}, {103.4, 138, -802}, {102.9, 164, -797.2}, {77.1, 138, -804.9}, {76.6, 164, -800}, {43.3, 139, -807}, {43.2, 165, -802.1}, {16.9, 139, -807.9}, {16.7, 165, -803}, {-16.7, 165, -803}, {-16.9, 139, -807.9}, {-43.2, 165, -802.1}, {-43.3, 139, -807}, {-76.6, 164, -800}, {-77.1, 138, -804.9}, {-102.9, 164, -797.2}, {-103.4, 138, -802}, {-137, 105.4, -801.9}, {-163, 104.9, -797.2}, {-137, 79.1, -804.9}, {-163, 78.6, -800.1}, {-137, 45.3, -807.9}, {-163, 45.2, -803.1}, {-137, 18.9, -808.9}, {-163, 18.7, -804.1}, {-163, -18.7, -804.1}, {-137, -18.9, -808.9}, {-163, -45.2, -803.1}, {-137, -45.3, -807.9}, {-163, -78.6, -800.1}, {-137, -79.1, -804.9}, {-163, -104.9, -797.2}, {-137, -105.4, -801.9}, {-103.4, -138, -802}, {-102.9, -164, -797.2}, {-77.1, -138, -804.9}, {-76.6, -164, -800}, {-43.3, -139, -807}, {-43.2, -165, -802.1}, {-16.9, -139, -807.9}, {-16.7, -165, -803}, {16.7, -165, -803}, {16.9, -139, -807.9}, {43.2, -165, -802.1}, {43.3, -139, -807}, {76.6, -164, -800}, {77.1, -138, -804.9}, {102.9, -164, -797.2}, {103.4, -138, -802}, {137, -105.4, -801.9}, {163, -104.9, -797.2}, {137, -79.1, -804.9}, {163, -78.6, -800.1}, {137, -45.3, -807.9}, {163, -45.2, -803.1}, {137, -18.9, -808.9}, {163, -18.7, -804.1}};
+
+  HistogramRegistry registry{
+    "registry",
+    {{"UnMatchedTracksXY", "; #it{x} (cm); #it{y} (cm);", {HistType::kTH2F, {{701, -35.05, 35.05}, {701, -35.05, 35.05}}}},
+     {"MatchedTracksXY", "; #it{x} (cm); #it{y} (cm);", {HistType::kTH2F, {{701, -35.05, 35.05}, {701, -35.05, 35.05}}}},
+     {"AllTracksXY", "; #it{x} (cm); #it{y} (cm);", {HistType::kTH2F, {{701, -35.05, 35.05}, {701, -35.05, 35.05}}}},
+     {"DistChannelToProp", "; D (cm); #count", {HistType::kTH1D, {{101, 0, 100}}}},
+     {"NchannelsPerBC", "; N_{channelC}; #count", {HistType::kTH1D, {{101, 0, 100}}}},
+     {"NgoodBCperTrack", "; N_{goodBC}; #count", {HistType::kTH1D, {{11, 0, 10}}}},
+     {"NgoodBCperTrackINDIV", "; N_{goodBC}; #count", {HistType::kTH1D, {{11, 0, 10}}}},
+     {"NCompBCwFT0C", "; N_{compBC}; #count", {HistType::kTH1D, {{21, -0.5, 20.5}}}},
+     {"NCompBCwFT0s", "; N_{compBC}; #count", {HistType::kTH1D, {{21, -0.5, 20.5}}}},
+     {"DiffInBCINDIV", "; indivBC-firstBC (globalBC); #count", {HistType::kTH1I, {{199, 0, 199}}}},
+     {"DiffInBC", "; goodBC-firstBC (globalBC); #count", {HistType::kTH1I, {{199, 0, 199}}}}}};
+
+  void init(InitContext const&)
+  {
+    ccdb->setURL(ccdburl);
+    ccdb->setCaching(true);
+    ccdb->setLocalObjectValidityChecking();
+  }
+
+  void initCCDB(ExtBCs::iterator const& bc)
+  {
+
+    if (runNumber == bc.runNumber()) {
+      return;
+    }
+    grpmag = ccdb->getForTimeStamp<o2::parameters::GRPMagField>(grpmagPath, bc.timestamp());
+    LOG(info) << "Setting magnetic field to current " << grpmag->getL3Current()
+              << " A for run " << bc.runNumber()
+              << " from its GRPMagField CCDB object";
+    o2::base::Propagator::initFieldFromGRP(grpmag); // for some reason this is necessary for the next next line
+    runNumber = bc.runNumber();
+
+    o2::field::MagneticField* field = static_cast<o2::field::MagneticField*>(TGeoGlobalMagField::Instance()->GetField());
+
+    Bz = field->getBz(centerMFT); // gives error if the propagator is not initFielded
+    LOG(info) << "The field at the center of the MFT is Bz = " << Bz;
+  }
+
+  bool isInFT0Acc(double x, double y)
+  {
+    // returns true if the propagated x and y positions are in an active zone of the FT0-C, false if they in a dead zone
+
+    if ((abs(x) < 6.365) && (abs(y) < 6.555)) {
+      // track outside the FT0-C acceptance (in the central hole)
+      return false;
+    }
+
+    if (((x > -12.75) && (x < -11.85)) || ((x > -6.55) && (x < -5.75)) || ((x > -0.35) && (x < 0.45)) || ((x > 5.75) && (x < 6.55)) || ((x > 11.85) && (x < 12.75))) {
+      // track outside the FT0-C acceptance (in the vertical line holes)
+      return false;
+    }
+
+    if (((y > -12.95) && (y < -11.95)) || ((y > -6.65) && (y < -5.85)) || ((y > -0.55) && (y < 0.45)) || ((y > 5.75) && (y < 6.65)) || ((y > 11.95) && (y < 12.85))) {
+      // track outside the FT0-C acceptance (in the horizontal line holes)
+      return false;
+    }
+
+    return true;
+  }
+
+  void processMFT(aod::MFTTracks const& mfttracks,
+                  aod::Collisions const&, ExtBCs const& bcs,
+                  aod::FT0s const&)
+  {
+    initCCDB(bcs.begin());
+
+    int i = 0; // counts the number of channels having non-zero amplitude
+    // for a particular BC
+    double D = 0.0; // distance between (xe,ye,ze) and (xc,yc,zc)
+    double minD;
+    double globalMinD;
+
+    for (auto& track : mfttracks) {
+      filler.BCids.clear();
+      globalMinD = 999.;          // minimum D for all BC
+      ExtBCs::iterator closestBC; // compatible BC with the D the smallest
+      // beware: there could be several BC with the same smallest D
+      // not a very useful variable
+
+      if (!track.has_collision()) {
+        BcMft(track.globalIndex(), filler.BCids); // empty
+        continue;
+      }
+      auto collOrig = track.collision();
+
+      auto bcSlice = getCompatibleBCs(track, collOrig, bcs, shiftBC);
+
+      // firstBC= global BC of the beginning of the ROF (shifted by shiftBC)
+      int64_t firstBC = collOrig.bc_as<ExtBCs>().globalBC() + (track.trackTime() - track.trackTimeRes()) / o2::constants::lhc::LHCBunchSpacingNS + shiftBC;
+
+      bool rofHasBoth = false; // ROF with both FT0C and FT0A signal in the same BC
+
+      std::vector<double> v1; // Temporary null vector for the computation of the covariance matrix
+      SMatrix55 tcovs(v1.begin(), v1.end());
+      SMatrix5 tpars(track.x(), track.y(), track.phi(), track.tgl(), track.signed1Pt());
+
+      o2::track::TrackParCovFwd trackPar{track.z(), tpars, tcovs, track.chi2()};
+
+      // we propagate the MFT track to the mean z position of FT0-C
+      // getTrackPar() doesn't work because mft tracks don't have alpha
+      trackPar.propagateToZhelix(-82.6, Bz); // z in cm
+
+      if (!isInFT0Acc(trackPar.getX(), trackPar.getY())) {
+        // track outside the FT0-C acceptance
+        BcMft(track.globalIndex(), filler.BCids); // empty
+        continue;
+      }
+
+      std::vector<ExtBCs::iterator> goodBC; // contains the BCs matched with the current MFT track
+      int nCompBCwft0C = 0;
+      int nCompBCwft0s = 0; // Number of compatible BCs with FT0A AND C signals
+
+      bool hasft0A = false;
+      bool hasft0C = false;
+      for (auto& bc : bcSlice) {
+        hasft0C = false;
+        hasft0A = false;
+        // printf("----------bcId %lld\n", bc.globalIndex());
+        if (!bc.has_ft0s()) {
+          continue;
+        }
+
+        auto ft0s = bc.ft0s();
+        i = 0; // reinitialise
+        D = 0.0;
+        minD = 999.9;
+        for (auto const& ft0 : ft0s) {
+          // printf("---------ft0.bcId %d\n", ft0.bcId());
+          if (ft0.channelA().size() > 0) {
+            // BC with signals in FT0A
+            hasft0A = true;
+          }
+
+          if (ft0.channelC().size() > 0) {
+            hasft0C = true;
+          }
+          for (auto channelId : ft0.channelC()) {
+
+            std::vector<float> Xc = channelCoord[channelId]; //(xc,yc,zc) coordinates
+            // D in cm
+            D = sqrt(pow(Xc[0] * 0.1 - trackPar.getX(), 2) + pow(Xc[1] * 0.1 - trackPar.getY(), 2) + pow(Xc[2] * 0.1 - 1.87 - trackPar.getZ(), 2));
+            // printf("----channelId %u, D %f, n %d\n", channelId, D, n);//should be between 96 and 207
+            if (D < minD) {
+              minD = D;
+            }
+
+            registry.fill(HIST("DistChannelToProp"), D);
+          }
+
+          i += ft0.channelC().size();
+        }
+
+        registry.fill(HIST("NchannelsPerBC"), i);
+        if (hasft0C) {
+          nCompBCwft0C++; // number of compatible BCs that have ft0-C signal
+        }
+
+        //----------------------- BC selection here ------------------------
+        // if strictBCSel true we are only considering BC with signals from both FT0A and FT0C
+        if (!(hasft0A && hasft0C) && strictBCSel) {
+          continue;
+          // we go to the next BC
+        }
+        nCompBCwft0s++;
+        if (hasft0A && hasft0C) {
+          rofHasBoth = true;
+        }
+
+        //----------------------- end of BC selection ------------------------
+
+        if (minD < 2) // 20 mm
+        {
+          goodBC.push_back(bc); // goodBC is a vector of bc
+          filler.BCids.emplace_back(bc.globalIndex());
+        }
+        if (minD < globalMinD) {
+          globalMinD = minD;
+          closestBC = bc;
+        }
+      }
+
+      if (!rofHasBoth) {
+        // there isn't a coincidence of FT0A and C inside the considered MFT ROF
+        // MFT track is probably noise, we don't select it
+        filler.BCids.clear();
+        BcMft(track.globalIndex(), filler.BCids); // empty
+        continue;
+      }
+      registry.fill(HIST("NgoodBCperTrack"), goodBC.size());
+      if (goodBC.size() == 0) {
+        registry.fill(HIST("UnMatchedTracksXY"), trackPar.getX(), trackPar.getY());
+      }
+      if (goodBC.size() > 0) {
+        registry.fill(HIST("MatchedTracksXY"), trackPar.getX(), trackPar.getY());
+        int64_t diff = goodBC[0].globalBC() - firstBC;
+        registry.fill(HIST("DiffInBC"), diff);
+      }
+      registry.fill(HIST("AllTracksXY"), trackPar.getX(), trackPar.getY());
+      registry.fill(HIST("NCompBCwFT0C"), nCompBCwft0C);
+      registry.fill(HIST("NCompBCwFT0s"), nCompBCwft0s);
+
+      if (nCompBCwft0s == 1) {
+        registry.fill(HIST("NgoodBCperTrackINDIV"), goodBC.size());
+
+        // position of the goodBC in the ROF for isolated colliding BCs
+        if (goodBC.size() > 0) {
+          int64_t diff = goodBC[0].globalBC() - firstBC;
+          registry.fill(HIST("DiffInBCINDIV"), diff);
+        }
+      }
+
+      BcMft(track.globalIndex(), filler.BCids);
+    } // loop of mfttracks
+  }
+  PROCESS_SWITCH(matchmftft0, processMFT, "Process MFT tracks with collisions", true);
+};
+
+struct checkmatchinmc {
+  // checks if the matching works as expected in MC
+  // only doprocessMFTMCcheck==true if you are analysing MC
+
+  HistogramRegistry registryMC{
+    "registryMC",
+    {}};
+
+  void init(InitContext const&)
+  {
+    if (doprocessMFTMCcheck) {
+      registryMC.add({"TrackIsMatched", "; isMFTTrackMatched; #count", {HistType::kTH1I, {{2, 0, 2}}}});
+      registryMC.add({"DiffInBCTrue", "; goodBC-trueBC (globalBC); #count", {HistType::kTH1I, {{800, -400, 400}}}});
+      registryMC.add({"TrueBCAmongMatched", "; isTrueBCAmongMatchedOnes; #count", {HistType::kTH1D, {{2, 0, 2}}}});
+    }
+  }
+
+  using MFTTracksLabeledWithFT0 = soa::Join<o2::aod::MFTTracks, aod::McMFTTrackLabels, aod::BCofMFT>;
+
+  void processMFTMCcheck(MFTTracksLabeledWithFT0 const& mfttracks,
+                         aod::McCollisions const&, ExtBCs const&, aod::McParticles const&)
+  {
+
+    for (auto& mfttrack : mfttracks) {
+
+      if (!mfttrack.has_bcs()) // mft tracks having a match in FT0-C
+      {
+        registryMC.fill(HIST("TrackIsMatched"), 0);
+        continue;
+      }
+
+      registryMC.fill(HIST("TrackIsMatched"), 1); // around 50% of all MFT tracks are matched with FT0-C in data
+      // around 90% of MFT tracks falling in the active FT0-C regions are matched
+      if (!mfttrack.has_mcParticle()) {
+        continue;
+      }
+
+      o2::aod::McParticle particle = mfttrack.mcParticle();
+      int64_t trueMFTBC = particle.mcCollision().bc_as<ExtBCs>().globalBC();
+      ;
+      bool isTrueBCAmongMatchedOnes = false;
+
+      for (auto& bc : mfttrack.bcs_as<ExtBCs>()) {      //
+        int64_t bcDiffTrue = bc.globalBC() - trueMFTBC; // difference between the muon's BC and the MFT track's BC
+        registryMC.fill(HIST("DiffInBCTrue"), bcDiffTrue);
+        if (bcDiffTrue == 0) {
+          isTrueBCAmongMatchedOnes = true;
+        }
+      }
+      if (isTrueBCAmongMatchedOnes) {
+        registryMC.fill(HIST("TrueBCAmongMatched"), 1);
+      } else {
+        registryMC.fill(HIST("TrueBCAmongMatched"), 0);
+      }
+    }
+  }
+  PROCESS_SWITCH(checkmatchinmc, processMFTMCcheck, "Process MFT tracks and check matching with MC information", false);
+
+  void processDummy(aod::Collisions const&)
+  {
+    // do nothing
+  }
+  PROCESS_SWITCH(checkmatchinmc, processDummy, "Do nothing if not MC", true);
+};
+
+WorkflowSpec
+  defineDataProcessing(ConfigContext const& cfgc)
+{
+  WorkflowSpec workflow{adaptAnalysisTask<bctoft0c>(cfgc),
+                        adaptAnalysisTask<matchmftft0>(cfgc),
+                        adaptAnalysisTask<checkmatchinmc>(cfgc)};
+  return workflow;
+}
diff --git a/Common/TableProducer/multiplicityTable.cxx b/Common/TableProducer/multiplicityTable.cxx
index f2e2c217def..8991c38cd10 100644
--- a/Common/TableProducer/multiplicityTable.cxx
+++ b/Common/TableProducer/multiplicityTable.cxx
@@ -43,7 +43,7 @@ static constexpr int kFV0MultZeqs = 9;
 static constexpr int kFT0MultZeqs = 10;
 static constexpr int kFDDMultZeqs = 11;
 static constexpr int kPVMultZeqs = 12;
-static constexpr int kMultsExtraMC = 13;
+static constexpr int kMultMCExtras = 13;
 static constexpr int nTables = 14;
 
 // Checking that the Zeq tables are after the normal ones
@@ -66,7 +66,7 @@ static const std::vector<std::string> tableNames{"FV0Mults",       // 0
                                                  "FT0MultZeqs",    // 10
                                                  "FDDMultZeqs",    // 11
                                                  "PVMultZeqs",     // 12
-                                                 "MultsExtraMC"};  // 13
+                                                 "MultMCExtras"};  // 13
 static const std::vector<std::string> parameterNames{"Enable"};
 static const int defaultParameters[nTables][nParameters]{{-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}};
 
@@ -85,7 +85,8 @@ struct MultiplicityTable {
   Produces<aod::FT0MultZeqs> tableFT0Zeqs;      // 10
   Produces<aod::FDDMultZeqs> tableFDDZeqs;      // 11
   Produces<aod::PVMultZeqs> tablePVZeqs;        // 12
-  Produces<aod::MultsExtraMC> tableExtraMc;     // 13
+  Produces<aod::MultMCExtras> tableExtraMc;     // 13
+  Produces<aod::MC2Mults> tableExtraMc2Mults;
   Produces<aod::MultsGlobal> multsGlobal;       // Not accounted for, produced based on process function processGlobalTrackingCounters
 
   // For vertex-Z corrections in calibration
@@ -163,10 +164,11 @@ struct MultiplicityTable {
       }
     }
     // Handle the custom cases.
-    if (tEnabled[kMultsExtraMC]) {
-      if (enabledTables->get(tableNames[kMultsExtraMC].c_str(), "Enable") == -1) {
+    if (tEnabled[kMultMCExtras]) {
+      if (enabledTables->get(tableNames[kMultMCExtras].c_str(), "Enable") == -1) {
         doprocessMC.value = true;
-        LOG(info) << "Enabling MC processing due to " << tableNames[kMultsExtraMC] << " table being enabled.";
+        doprocessMC2Mults.value = true;
+        LOG(info) << "Enabling MC processing due to " << tableNames[kMultMCExtras] << " table being enabled.";
       }
     }
 
@@ -335,7 +337,7 @@ struct MultiplicityTable {
         case kPVMultZeqs: // Equalized multiplicity for PV
           tablePVZeqs.reserve(collisions.size());
           break;
-        case kMultsExtraMC: // MC extra information (nothing to do in the data)
+        case kMultMCExtras: // MC extra information (nothing to do in the data)
           break;
         default:
           LOG(fatal) << "Unknown table requested: " << i;
@@ -609,7 +611,7 @@ struct MultiplicityTable {
             }
             tablePVZeqs(multZeqNContribs);
           } break;
-          case kMultsExtraMC: // MC only (nothing to do)
+          case kMultMCExtras: // MC only (nothing to do)
           {
           } break;
           default: // Default
@@ -665,6 +667,11 @@ struct MultiplicityTable {
     tableExtraMc(multFT0A, multFT0C, multBarrelEta05, multBarrelEta08, multBarrelEta10, mcCollision.posZ());
   }
 
+  void processMC2Mults(soa::Join<aod::McCollisionLabels, aod::Collisions>::iterator const& collision)
+  {
+    tableExtraMc2Mults(collision.mcCollisionId()); // interlink
+  }
+
   Configurable<float> min_pt_globaltrack{"min_pt_globaltrack", 0.15, "min. pT for global tracks"};
   Configurable<float> max_pt_globaltrack{"max_pt_globaltrack", 1e+10, "max. pT for global tracks"};
   Configurable<int> min_ncluster_its_globaltrack{"min_ncluster_its_globaltrack", 5, "min. number of ITS clusters for global tracks"};
@@ -715,6 +722,7 @@ struct MultiplicityTable {
   PROCESS_SWITCH(MultiplicityTable, processRun3, "Produce Run 3 multiplicity tables", true);
   PROCESS_SWITCH(MultiplicityTable, processGlobalTrackingCounters, "Produce Run 3 global counters", false);
   PROCESS_SWITCH(MultiplicityTable, processMC, "Produce MC multiplicity tables", false);
+  PROCESS_SWITCH(MultiplicityTable, processMC2Mults, "Produce MC -> Mult map", false);
 };
 
 WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
diff --git a/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx b/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx
index df9e474b4fb..fe928c0ddc3 100644
--- a/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx
+++ b/DPG/Tasks/AOTTrack/PID/TOF/qaPIDTOFBeta.cxx
@@ -49,6 +49,7 @@ struct tofPidBetaQa {
   ConfigurableAxis trackLengthBins{"trackLengthBins", {100, 0, 1000.f}, "Binning in track length plot"};
   Configurable<bool> requireGoodMatchTracks{"requireGoodMatchTracks", false, "Require good match tracks"};
   Configurable<float> mMaxTOFChi2{"maxTOFChi2", 3.f, "Maximum TOF Chi2"};
+  Configurable<float> mEtaWindow{"etaWindow", 0.8f, "Window in eta for tracks"};
 
   void init(o2::framework::InitContext&)
   {
@@ -206,6 +207,7 @@ struct tofPidBetaQa {
                        ((trackSelection.node() == 3) && requireGlobalTrackWoDCAInFilter()) ||
                        ((trackSelection.node() == 4) && requireQualityTracksInFilter()) ||
                        ((trackSelection.node() == 5) && requireInAcceptanceTracksInFilter());
+  Filter etaFilter = (nabs(o2::aod::track::eta) < mEtaWindow);
 
   using CollisionCandidate = soa::Filtered<soa::Join<aod::Collisions, aod::EvSels>>::iterator;
   using TrackCandidates = soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection,
diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h
index 6d48650c2ba..c08c131ab99 100644
--- a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h
+++ b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h
@@ -74,7 +74,6 @@ class FemtoUniverse3DContainer
   /// \param mTAxis axis object for the mT axis
   /// \param use3dplots Flag to fill 3D plots
   /// \param isiden Identical or non-identical particle pair
-  /// \param islcms LCMS or PRF
   template <typename T>
   void init_base(std::string folderName, std::string femtoObs1D, std::string femtoObsKout, std::string femtoObsKside, std::string femtoObsKlong, T femtoObsAxis1D, T femtoObsAxisOut, T femtoObsAxisSide, T femtoObsAxisLong, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, bool use3dplots, bool isiden)
   {
@@ -214,13 +213,13 @@ class FemtoUniverse3DContainer
   /// \param isiden Choosing identical or non-identical pairs
   /// \param islcm Choosing LCMS or PRF
   template <bool isMC, typename T>
-  void setPair(T const& part1, T const& part2, const int mult, bool use3dplots, bool isiden, bool islcms)
+  void setPair(T const& part1, T const& part2, const int mult, bool use3dplots, bool isiden)
   {
     std::vector<double> f3d;
     const float kT = FemtoUniverseMath::getkT(part1, mMassOne, part2, mMassTwo);
     const float mT = FemtoUniverseMath::getmT(part1, mMassOne, part2, mMassTwo);
 
-    f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo, isiden, islcms);
+    f3d = FemtoUniverseMath::newpairfunc(part1, mMassOne, part2, mMassTwo, isiden);
 
     const float femtoObs1D = f3d[0];
     const float femtoObsKout = f3d[1];
diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h
index cd992906c89..95c0165b26d 100644
--- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h
+++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h
@@ -149,9 +149,8 @@ class FemtoUniverseMath
   /// \param part2 Particle 2
   /// \param mass2 Mass of particle 2
   /// \param isiden Identical or non-identical particle pair
-  /// \param islcms LCMS or PRF
   template <typename T>
-  static std::vector<double> getpairmom3d(const T& part1, const float mass1, const T& part2, const float mass2, bool isiden, bool islcms)
+  static std::vector<double> newpairfunc(const T& part1, const float mass1, const T& part2, const float mass2, bool isiden)
   {
     const double E1 = sqrt(pow(part1.px(), 2) + pow(part1.py(), 2) + pow(part1.pz(), 2) + pow(mass1, 2));
     const double E2 = sqrt(pow(part2.px(), 2) + pow(part2.py(), 2) + pow(part2.pz(), 2) + pow(mass2, 2));
@@ -165,80 +164,62 @@ class FemtoUniverseMath
     const double tPx = trackSum.px();
     const double tPy = trackSum.py();
     const double tPz = trackSum.pz();
-    const double tPE = trackSum.E();
+    const double tE = trackSum.E();
 
-    const double tPt = trackSum.pt();
-    const double tMt = trackSum.mt();
-    const double tPinv = std::sqrt((tMt * tMt) - (tPt * tPt));
+    double tPt = (tPx * tPx + tPy * tPy);
+    double tMt = (tE * tE - tPz * tPz);
+    double tM = sqrt(tMt - tPt);
+    tMt = sqrt(tMt);
+    tPt = sqrt(tPt);
 
-    float nullmass = 0.0;
-    const double m1 = std::max(nullmass, mass1);
-    const double m2 = std::max(nullmass, mass2);
-
-    const double tQinvL = std::pow((E1 - E2), 2) - std::pow((part1.px() - part2.px()), 2) -
-                          std::pow((part1.py() - part2.py()), 2) - std::pow((part1.pz() - part2.pz()), 2);
-
-    double tQ = (m1 - m2) / tPinv;
-    tQ = ::sqrt(tQ * tQ - tQinvL);
-
-    const double fKStarCalc = tQ / 2.0;
-    vect.push_back(fKStarCalc);
+    double fDKOutLCMS, fDKSideLCMS, fDKLongLCMS;
+    double fDKOut, fDKSide, fDKLong, fDE;
+    double px1LCMS, py1LCMS, pz1LCMS;
+    double px2LCMS, py2LCMS, pz2LCMS;
+    double kstar;
 
     // Boost to LCMS
 
-    const double beta = tPz / tPE;
-    const double gamma = tPE / tMt;
+    const double beta = tPz / tE;
+    const double gamma = tE / tMt;
 
-    const double px1L = (part1.px() * tPx + part1.py() * tPy) / tPt;
-    const double py1L = (-part1.px() * tPy + part1.py() * tPx) / tPt;
-    const double pz1L = gamma * (part1.pz() - beta * E1);
-    const double pE1L = gamma * (E1 - beta * part1.pz());
+    fDKOut = (part1.px() * tPx + part1.py() * tPy) / tPt;
+    fDKSide = (-part1.px() * tPy + part1.py() * tPx) / tPt;
+    fDKLong = gamma * (part1.pz() - beta * E1);
+    fDE = gamma * (E1 - beta * part1.pz());
 
-    const double px2L = (part2.px() * tPx + part2.py() * tPy) / tPt;
-    const double py2L = (-part2.px() * tPy + part2.py() * tPx) / tPt;
-    const double pz2L = gamma * (part2.pz() - beta * E2);
-    const double pE2L = gamma * (E2 - beta * part2.pz());
+    px1LCMS = fDKOut;
+    py1LCMS = fDKSide;
+    pz1LCMS = fDKLong;
+    // pE1LCMS = fDE;
 
-    double fDKOutLCMS;
-    double fDKSideLCMS;
-    double fDKLongLCMS;
+    px2LCMS = (part2.px() * tPx + part2.py() * tPy) / tPt;
+    py2LCMS = (part2.py() * tPx - part2.px() * tPy) / tPt;
+    pz2LCMS = gamma * (part2.pz() - beta * E2);
+    // pE2LCMS = gamma * (E2 - beta * part2.pz());
 
-    double fDKOutPRF;
-    double fDKSidePRF;
-    double fDKLongPRF;
-
-    if (!isiden) {
-      fDKOutLCMS = px1L;
-      fDKSideLCMS = py1L;
-      fDKLongLCMS = pz1L;
-    } else {
-      fDKOutLCMS = px1L - px2L;
-      fDKSideLCMS = py1L - py2L;
-      fDKLongLCMS = pz1L - pz2L;
-    }
+    fDKOutLCMS = px1LCMS - px2LCMS;
+    fDKSideLCMS = py1LCMS - py2LCMS;
+    fDKLongLCMS = pz1LCMS - pz2LCMS;
 
     // Boost to PRF
+
     const double betaOut = tPt / tMt;
-    const double gammaOut = tMt / tPinv;
+    const double gammaOut = tMt / tM;
 
-    if (!isiden) {
-      fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * pE1L);
-      fDKSidePRF = fDKSideLCMS;
-      fDKLongPRF = fDKLongLCMS;
-    } else {
-      fDKOutPRF = gammaOut * (fDKOutLCMS - betaOut * (pE1L - pE2L));
-      fDKSidePRF = fDKSideLCMS;
-      fDKLongPRF = fDKLongLCMS;
-    }
+    fDKOut = gammaOut * (fDKOut - betaOut * fDE);
+    kstar = sqrt(fDKOut * fDKOut + fDKSide * fDKSide + fDKLong * fDKLong);
 
-    if (islcms) {
+    if (isiden) {
+      vect.push_back(2.0 * (kstar));
       vect.push_back(fDKOutLCMS);
       vect.push_back(fDKSideLCMS);
       vect.push_back(fDKLongLCMS);
     } else {
-      vect.push_back(fDKOutPRF);
-      vect.push_back(fDKSidePRF);
-      vect.push_back(fDKLongPRF);
+      vect.push_back(kstar);
+      vect.push_back(fDKOut);
+      vect.push_back(fDKSide);
+      vect.push_back(fDKLong);
     }
     return vect;
   }
diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h
index c6978f7c6eb..1be3d76085e 100644
--- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h
+++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h
@@ -184,7 +184,7 @@ class PairSHCentMultKt
   /// \param ktval kT value
   template <typename T>
   void fill_mult_NumDen(T const& part1, T const& part2, uint8_t ChosenEventType,
-                        int maxl, int multval, float ktval)
+                        int maxl, int multval, float ktval, bool isiden)
   {
     int multbinval;
     int absmultval = multval;
@@ -201,7 +201,7 @@ class PairSHCentMultKt
       return;
     }
     // std::cout<<"multbinval "<<multbinval<<std::endl;
-    fill_kT_NumDen(part1, part2, ChosenEventType, maxl, multbinval, ktval);
+    fill_kT_NumDen(part1, part2, ChosenEventType, maxl, multbinval, ktval, isiden);
   }
 
   /// Templated function to access different kT directory and call AddEventPair
@@ -213,7 +213,7 @@ class PairSHCentMultKt
   /// \param ktval kT value
   template <typename T>
   void fill_kT_NumDen(T const& part1, T const& part2, uint8_t ChosenEventType,
-                      int maxl, int multval, float ktval)
+                      int maxl, int multval, float ktval, bool isiden)
   {
     int ktbinval = -1;
     if ((ktval >= KtBins[0]) && (ktval < KtBins[1])) {
@@ -227,7 +227,7 @@ class PairSHCentMultKt
     } else {
       return;
     }
-    AddEventPair(part1, part2, ChosenEventType, maxl, multval, ktbinval);
+    AddEventPair(part1, part2, ChosenEventType, maxl, multval, ktbinval, isiden);
   }
 
   /// Set the PDG codes of the two particles involved
@@ -262,14 +262,14 @@ class PairSHCentMultKt
   /// \param ktval kT value
   template <typename T>
   void AddEventPair(T const& part1, T const& part2, uint8_t ChosenEventType,
-                    int /*maxl*/, int multval, int ktval)
+                    int /*maxl*/, int multval, int ktval, bool isiden)
   {
     int fMultBin = multval;
     int fKtBin = ktval;
     std::vector<std::complex<double>> fYlmBuffer(fMaxJM);
     std::vector<double> f3d;
-    f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo,
-                                          true, true);
+    f3d = FemtoUniverseMath::newpairfunc(part1, mMassOne, part2, mMassTwo,
+                                         isiden);
 
     const float qout = f3d[1];
     const float qside = f3d[2];
diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h
index 0838ce5e5b3..4bc96996408 100644
--- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h
+++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h
@@ -159,20 +159,17 @@ class FemtoUniverseSHContainer
   /// \param ChosenEventType same or mixed event
   /// \param maxl Maximum valie of L component of the spherical harmonics
   template <bool isMC, typename T>
-  void AddEventPair(T const& part1, T const& part2, uint8_t ChosenEventType, int /*maxl*/)
+  void AddEventPair(T const& part1, T const& part2, uint8_t ChosenEventType, int /*maxl*/, bool isiden)
   {
-    // int fMaxL = 2;
-    // int fMaxJM = (2+1)*(2+1);
     std::vector<std::complex<double>> fYlmBuffer(fMaxJM);
     std::vector<double> f3d;
-    f3d = FemtoUniverseMath::getpairmom3d(part1, mMassOne, part2, mMassTwo, true, true);
+    f3d = FemtoUniverseMath::newpairfunc(part1, mMassOne, part2, mMassTwo, isiden);
 
-    // const float qstar = f3d[0];
+    const float kv = f3d[0];
     const float qout = f3d[1];
     const float qside = f3d[2];
     const float qlong = f3d[3];
 
-    double kv = sqrt(qout * qout + qside * qside + qlong * qlong);
     int nqbin = fbinctn->GetXaxis()->FindFixBin(kv) - 1;
 
     FemtoUniverseSpherHarMath Ylm;
diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx
index ed5ff3c56f1..d5b7c010acc 100644
--- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx
+++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx
@@ -476,9 +476,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended {
         float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2);
 
         if (!cfgProcessMultBins) {
-          sameEventCont.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+          sameEventCont.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
         } else {
-          std::vector<double> k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS);
+          std::vector<double> k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden);
           sameEventMultCont.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
         }
       }
@@ -515,16 +515,16 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended {
 
             if (rand > 0.5) {
               if (!cfgProcessMultBins) {
-                sameEventContPP.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+                sameEventContPP.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
               } else {
-                k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS);
+                k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden);
                 sameEventMultContPP.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
               }
             } else {
               if (!cfgProcessMultBins) {
-                sameEventContPP.setPair<isMC>(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+                sameEventContPP.setPair<isMC>(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
               } else {
-                k3d = FemtoUniverseMath::getpairmom3d(p2, mass2, p1, mass1, ConfIsIden, ConfIsLCMS);
+                k3d = FemtoUniverseMath::newpairfunc(p2, mass2, p1, mass1, ConfIsIden);
                 sameEventMultContPP.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
               }
             }
@@ -538,16 +538,16 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended {
 
             if (rand > 0.5) {
               if (!cfgProcessMultBins) {
-                sameEventContMM.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+                sameEventContMM.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
               } else {
-                k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS);
+                k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden);
                 sameEventMultContMM.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
               }
             } else {
               if (!cfgProcessMultBins) {
-                sameEventContMM.setPair<isMC>(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+                sameEventContMM.setPair<isMC>(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
               } else {
-                k3d = FemtoUniverseMath::getpairmom3d(p2, mass2, p1, mass1, ConfIsIden, ConfIsLCMS);
+                k3d = FemtoUniverseMath::newpairfunc(p2, mass2, p1, mass1, ConfIsIden);
                 sameEventMultContMM.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
               }
             }
@@ -650,9 +650,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended {
         case 1: {
           float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2);
           if (!cfgProcessMultBins) {
-            mixedEventCont.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+            mixedEventCont.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
           } else {
-            std::vector<double> k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS);
+            std::vector<double> k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden);
             mixedEventMultCont.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
           }
           break;
@@ -660,9 +660,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended {
         case 2: {
           float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass1);
           if (!cfgProcessMultBins) {
-            mixedEventContPP.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+            mixedEventContPP.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
           } else {
-            std::vector<double> k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS);
+            std::vector<double> k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden);
             mixedEventMultContPP.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
           }
           break;
@@ -671,9 +671,9 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended {
         case 3: {
           float kT = FemtoUniverseMath::getkT(p1, mass2, p2, mass2);
           if (!cfgProcessMultBins) {
-            mixedEventContMM.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS);
+            mixedEventContMM.setPair<isMC>(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden);
           } else {
-            std::vector<double> k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS);
+            std::vector<double> k3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden);
             mixedEventMultContMM.fill_3D<float>(k3d[1], k3d[2], k3d[3], multCol, kT);
           }
           break;
diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx
index 8758c68d4a8..8dc39769732 100644
--- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx
+++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx
@@ -475,7 +475,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended {
           continue;
         }
         float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2);
-        sameEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT);
+        sameEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden);
       }
     } else {
       for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsOne))) {
@@ -507,9 +507,9 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended {
           case 2: {
             rand = randgen->Rndm();
             if (rand > 0.5) {
-              sameEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT);
+              sameEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden);
             } else if (rand <= 0.5) {
-              sameEventMultContPP.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT);
+              sameEventMultContPP.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden);
             }
             break;
           }
@@ -517,9 +517,9 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended {
           case 3: {
             rand = randgen->Rndm();
             if (rand > 0.5) {
-              sameEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT);
+              sameEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden);
             } else if (rand <= 0.5) {
-              sameEventMultContMM.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT);
+              sameEventMultContMM.fill_mult_NumDen(p2, p1, femtoUniverseSHContainer::EventType::same, 2, multCol, kT, ConfIsIden);
             }
             break;
           }
@@ -606,15 +606,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended {
       float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2);
       switch (ContType) {
         case 1: {
-          mixedEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT);
+          mixedEventMultCont.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT, ConfIsIden);
           break;
         }
         case 2: {
-          mixedEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT);
+          mixedEventMultContPP.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT, ConfIsIden);
           break;
         }
         case 3: {
-          mixedEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT);
+          mixedEventMultContMM.fill_mult_NumDen(p1, p2, femtoUniverseSHContainer::EventType::mixed, 2, multCol, kT, ConfIsIden);
           break;
         }
         default:
diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx
index 0b25a3660d8..064f26b1938 100644
--- a/PWGDQ/Core/CutsLibrary.cxx
+++ b/PWGDQ/Core/CutsLibrary.cxx
@@ -370,6 +370,18 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName)
     return cut;
   }
 
+  if (!nameStr.compare("pidElectron_ionut")) {
+    cut->AddCut(GetAnalysisCut("pidcalib_ele"));
+    cut->AddCut(GetAnalysisCut("jpsiStandardKine3"));
+    return cut;
+  }
+
+  if (!nameStr.compare("pidPion_ionut")) {
+    cut->AddCut(GetAnalysisCut("pidcalib_pion"));
+    cut->AddCut(GetAnalysisCut("jpsiStandardKine3"));
+    return cut;
+  }
+
   if (!nameStr.compare("jpsiO2MCdebugCuts13_Corr")) {
     cut->AddCut(GetAnalysisCut("jpsiStandardKine"));
     cut->AddCut(GetAnalysisCut("electronStandardQualityTPCOnly")); // no cut on ITS clusters
@@ -877,6 +889,24 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName)
     return cut;
   }
 
+  for (int iCut = 0; iCut < 7; iCut++) {
+    if (!nameStr.compare(Form("jpsiEleSel%d_ionut", iCut))) {
+      cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut"));
+      cut->AddCut(GetAnalysisCut("dcaCut1_ionut"));
+      cut->AddCut(GetAnalysisCut("trackQuality_ionut"));
+      cut->AddCut(GetAnalysisCut(Form("pidJpsiEle%d_ionut", iCut)));
+      return cut;
+    }
+
+    if (!nameStr.compare(Form("jpsiEleSelTight%d_ionut", iCut))) {
+      cut->AddCut(GetAnalysisCut("kineJpsiEle_ionut"));
+      cut->AddCut(GetAnalysisCut("dcaCut1_ionut"));
+      cut->AddCut(GetAnalysisCut("trackQualityTight_ionut"));
+      cut->AddCut(GetAnalysisCut(Form("pidJpsiEle%d_ionut", iCut)));
+      return cut;
+    }
+  }
+
   //---------------------------------------------------------------
   // Cuts for the selection of legs from dalitz decay
   //
@@ -3223,6 +3253,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName)
   if (!nameStr.compare("eventStandardSel8WithITSROFRecomputedCut")) {
     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::kIsNoITSROFBorderRecomputed, 0.5, 1.5);
     return cut;
   }
@@ -3992,6 +4023,76 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName)
     return cut;
   }
 
+  if (!nameStr.compare("trackQuality_ionut")) {
+    cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5);
+    cut->AddCut(VarManager::kTPCncls, 70, 161);
+    cut->AddCut(VarManager::kITSchi2, 0.0, 5.0);
+    cut->AddCut(VarManager::kTPCchi2, 0.0, 2.0);
+    return cut;
+  }
+
+  if (!nameStr.compare("trackQualityTight_ionut")) {
+    cut->AddCut(VarManager::kIsITSibAny, 0.5, 1.5);
+    cut->AddCut(VarManager::kTPCncls, 100, 161);
+    cut->AddCut(VarManager::kITSchi2, 0.0, 3.0);
+    cut->AddCut(VarManager::kTPCchi2, 0.0, 2.0);
+    cut->AddCut(VarManager::kITSncls, 5.0, 8.0);
+    return cut;
+  }
+
+  if (!nameStr.compare("kineJpsiEle_ionut")) {
+    cut->AddCut(VarManager::kP, 1.0, 15.0);
+    cut->AddCut(VarManager::kEta, -0.9, 0.9);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle0_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, -2.0, 4.0, false, VarManager::kPin, 1.0, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kPin, 4.0, 150.0);
+    cut->AddCut(VarManager::kTPCnSigmaEl, 98.1, 98.11, false, VarManager::kPin, 0.0, 1.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle1_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, -1.5, 4.0, false, VarManager::kPin, 1.0, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0, false, VarManager::kPin, 4.0, 150.0);
+    cut->AddCut(VarManager::kTPCnSigmaEl, 98.1, 98.11, false, VarManager::kPin, 0.0, 1.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle2_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle3_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, -0.5, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle4_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, 0.0, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle5_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, 0.5, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
+  if (!nameStr.compare("pidJpsiEle6_ionut")) {
+    cut->AddCut(VarManager::kTPCnSigmaEl, -1.0, 4.0);
+    cut->AddCut(VarManager::kTOFnSigmaEl, -1.0, 4.0);
+    cut->AddCut(VarManager::kTPCnSigmaPr, -4.0, 4.0, true);
+    return cut;
+  }
+
   if (!nameStr.compare("standardPrimaryTrackDCAz")) {
     cut->AddCut(VarManager::kTrackDCAxy, -3.0, 3.0);
     cut->AddCut(VarManager::kTrackDCAz, -1.0, 1.0);
diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx
index 4e380a93090..0ee10b5f844 100644
--- a/PWGDQ/Core/HistogramsLibrary.cxx
+++ b/PWGDQ/Core/HistogramsLibrary.cxx
@@ -54,17 +54,17 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h
     }
     if (subGroupStr.Contains("time")) {
       hm->AddHistogram(histClass, "CollTime", "Coll. time wrt BC", false, 100, 0.0, 100.0, VarManager::kCollisionTime);
-      hm->AddHistogram(histClass, "CollTimeRes", "Coll. time resolution", false, 100, 0.0, 100.0, VarManager::kCollisionTimeRes);
+      hm->AddHistogram(histClass, "CollTimeRes", "Coll. time resolution", false, 100, 0.0, 200.0, VarManager::kCollisionTimeRes);
       hm->AddHistogram(histClass, "CollTime_VtxZ", "Coll. time wrt BC vs vtx-z", false, 50, -15.0, 15., VarManager::kVtxZ, 100, 0.0, 100.0, VarManager::kCollisionTime);
       hm->AddHistogram(histClass, "CollTimeRes_VtxZ", "Coll. time resolution ", false, 50, -15.0, 15., VarManager::kVtxZ, 100, 0.0, 100.0, VarManager::kCollisionTimeRes);
-      hm->AddHistogram(histClass, "CollTimeRes_MultTPC", "Coll. time resolution ", false, 50, 0.0, 500., VarManager::kMultTPC, 100, 0.0, 100.0, VarManager::kCollisionTimeRes);
-      hm->AddHistogram(histClass, "CollTimeRes_MultPV", "Coll. time resolution ", false, 50, 0.0, 500., VarManager::kVtxNcontribReal, 100, 0.0, 100.0, VarManager::kCollisionTimeRes);
+      hm->AddHistogram(histClass, "CollTimeRes_MultTPC", "Coll. time resolution ", false, 50, 0.0, 50000., VarManager::kMultTPC, 100, 0.0, 200.0, VarManager::kCollisionTimeRes);
+      hm->AddHistogram(histClass, "CollTimeRes_MultPV", "Coll. time resolution ", false, 100, 0.0, 4000., VarManager::kVtxNcontribReal, 100, 0.0, 200.0, VarManager::kCollisionTimeRes);
       hm->AddHistogram(histClass, "TimeFromSOR", "Time since SOR", false, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR);
     }
     if (subGroupStr.Contains("vtx")) {
       hm->AddHistogram(histClass, "VtxX", "Vtx X", false, 200, -0.1, 0.1, VarManager::kVtxX);
       hm->AddHistogram(histClass, "VtxY", "Vtx Y", false, 200, -0.1, 0.1, VarManager::kVtxY);
-      hm->AddHistogram(histClass, "VtxYVtxX", "Vtx Y vs Vtx X", false, 100, -0.1, 0.1, VarManager::kVtxX, 100, -0.1, 0.1, VarManager::kVtxY);
+      hm->AddHistogram(histClass, "VtxYVtxX", "Vtx Y vs Vtx X", false, 200, -0.06, 0.0, VarManager::kVtxX, 200, -0.03, 0.03, VarManager::kVtxY);
     }
     if (subGroupStr.Contains("vtxpp")) {
       hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 100.0, VarManager::kVtxNcontrib);
@@ -73,11 +73,9 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h
       hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 20000.0, VarManager::kVtxNcontrib);
     }
     if (subGroupStr.Contains("cent")) {
-      hm->AddHistogram(histClass, "CentV0M", "CentV0M", false, 100, 0., 100., VarManager::kCentVZERO);
-      hm->AddHistogram(histClass, "CentV0M_vtxZ", "CentV0M vs Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ, 20, 0., 100., VarManager::kCentVZERO);
       hm->AddHistogram(histClass, "CentFT0C", "CentFT0C", false, 100, 0., 100., VarManager::kCentFT0C);
       hm->AddHistogram(histClass, "CentFT0C_vtxZ", "CentFT0C vs Vtx Z", false, 60, -15.0, 15.0, VarManager::kVtxZ, 20, 0., 100., VarManager::kCentFT0C);
-      hm->AddHistogram(histClass, "CentFT0C_MultTPC", "CentFT0C vs MultTPC", false, 100, 0., 100., VarManager::kCentFT0C, 50, 0., 50., VarManager::kMultTPC);
+      hm->AddHistogram(histClass, "CentFT0C_MultTPC", "CentFT0C vs MultTPC", false, 100, 0., 100., VarManager::kCentFT0C, 100, 0., 50000., VarManager::kMultTPC);
       hm->AddHistogram(histClass, "CentFT0C_Run", "Cent FT0C", true, VarManager::GetDummyNRuns(), -0.5 + VarManager::GetDummyFirst(), 0.5 + VarManager::GetDummyLast(), VarManager::kRunNo, 100, 0., 100., VarManager::kCentFT0C, 1, 0, 1, VarManager::kNothing, VarManager::GetRunStr().Data());
     }
     if (subGroupStr.Contains("mult")) {
@@ -98,25 +96,31 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h
       } 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);
-        hm->AddHistogram(histClass, "MultFV0A", "MultFV0A", false, 200, 0.0, 100000.0, VarManager::kMultFV0A);
-        hm->AddHistogram(histClass, "MultFT0A", "MultFT0A", false, 200, 0.0, 100000.0, VarManager::kMultFT0A);
+        hm->AddHistogram(histClass, "MultFV0A", "MultFV0A", false, 200, 0.0, 300000.0, VarManager::kMultFV0A);
+        hm->AddHistogram(histClass, "MultFT0A", "MultFT0A", false, 200, 0.0, 300000.0, VarManager::kMultFT0A);
         hm->AddHistogram(histClass, "MultFT0C", "MultFT0C", false, 200, 0.0, 100000.0, VarManager::kMultFT0C);
         hm->AddHistogram(histClass, "MultFDDA", "MultFDDA", false, 100, 0.0, 100000.0, VarManager::kMultFDDA);
         hm->AddHistogram(histClass, "MultFDDC", "MultFDDC", false, 100, 0.0, 100000.0, VarManager::kMultFDDC);
-        hm->AddHistogram(histClass, "MultZNA", "MultZNA", false, 200, 0.0, 5000.0, VarManager::kMultZNA);
-        hm->AddHistogram(histClass, "MultZNC", "MultZNC", false, 200, 0.0, 5000.0, VarManager::kMultZNC);
+        hm->AddHistogram(histClass, "MultZNA", "MultZNA", false, 400, 0.0, 400.0, VarManager::kMultZNA);
+        hm->AddHistogram(histClass, "MultZNC", "MultZNC", false, 400, 0.0, 400.0, VarManager::kMultZNC);
+        hm->AddHistogram(histClass, "MultZNA_ZNC", "MultZNA vs ZNC", false, 400, 0.0, 400.0, VarManager::kMultZNA, 400, 0.0, 400.0, VarManager::kMultZNC);
         hm->AddHistogram(histClass, "MultTracklets", "MultTracklets", false, 100, 0.0, 25000.0, VarManager::kMultTracklets);
         hm->AddHistogram(histClass, "VtxNContribReal", "Vtx n contributors (real)", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal);
         hm->AddHistogram(histClass, "VtxNContribReal_vsTimeSOR", "VtxNContribReal vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, 0.0, 5000.0, VarManager::kVtxNcontribReal);
-        hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 5000.0, VarManager::kVtxNcontrib);
-        hm->AddHistogram(histClass, "MultTPC_MultFV0A", "MultTPC vs MultFV0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 100000.0, VarManager::kMultFV0A);
-        hm->AddHistogram(histClass, "MultTPC_MultFT0A", "MultTPC vs MultFT0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 100000.0, VarManager::kMultFT0A);
+        hm->AddHistogram(histClass, "VtxNContrib", "Vtx n contributors", false, 100, 0.0, 20000.0, VarManager::kVtxNcontrib);
+        hm->AddHistogram(histClass, "MultTPC_MultFV0A", "MultTPC vs MultFV0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 300000.0, VarManager::kMultFV0A);
+        hm->AddHistogram(histClass, "MultTPC_MultFT0A", "MultTPC vs MultFT0A", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 300000.0, VarManager::kMultFT0A);
         hm->AddHistogram(histClass, "MultTPC_MultFT0C", "MultTPC vs MultFT0C", false, 100, 0, 50000.0, VarManager::kMultTPC, 100, 0, 100000.0, VarManager::kMultFT0C);
-        hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 100000.0, VarManager::kMultFT0A, 100, 0, 100000.0, VarManager::kMultFT0C);
+        hm->AddHistogram(histClass, "MultFT0A_MultFT0C", "MultFT0A vs MultFT0C", false, 100, 0, 100000.0, VarManager::kMultFT0A, 100, 0, 300000.0, VarManager::kMultFT0C);
+        hm->AddHistogram(histClass, "VtxNContribReal_MultTPC", "Vtx n contributors (real) vs mult TPC", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal, 200, 0.0, 50000.0, VarManager::kMultTPC);
+        hm->AddHistogram(histClass, "VtxNContribReal_ZNA", "Vtx n contributors (real) vs ZNA", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal, 200, 0.0, 400.0, VarManager::kMultZNA);
+        hm->AddHistogram(histClass, "VtxNContribReal_ZNC", "Vtx n contributors (real) vs ZNC", false, 100, 0.0, 5000.0, VarManager::kVtxNcontribReal, 200, 0.0, 400.0, VarManager::kMultZNC);
+        hm->AddHistogram(histClass, "MultZNA_FT0C", "MultZNA vs FT0C", false, 400, 0.0, 400.0, VarManager::kMultZNA, 200, 0.0, 100000.0, VarManager::kMultFT0C);
+        hm->AddHistogram(histClass, "MultZNC_FT0C", "MultZNC vs FT0C", false, 400, 0.0, 400.0, VarManager::kMultZNC, 200, 0.0, 100000.0, VarManager::kMultFT0C);
         hm->AddHistogram(histClass, "TPCpileupZA", "TPC pileup Z, A-side", false, 200, -50.0, 50.0, VarManager::kNTPCpileupZA);
         hm->AddHistogram(histClass, "TPCpileupZC", "TPC pileup Z, C-side", false, 200, -50.0, 50.0, VarManager::kNTPCpileupZC);
-        hm->AddHistogram(histClass, "TPCpileupNcontribA", "TPC pileup n-contributors, A-side", false, 1000, 0.0, 10000.0, VarManager::kNTPCpileupContribA);
-        hm->AddHistogram(histClass, "TPCpileupNcontribC", "TPC pileup n-contributors, C-side", false, 1000, 0.0, 10000.0, VarManager::kNTPCpileupContribC);
+        hm->AddHistogram(histClass, "TPCpileupNcontribA", "TPC pileup n-contributors, A-side", false, 300, 0.0, 3000.0, VarManager::kNTPCpileupContribA);
+        hm->AddHistogram(histClass, "TPCpileupNcontribC", "TPC pileup n-contributors, C-side", false, 300, 0.0, 3000.0, VarManager::kNTPCpileupContribC);
       }
     }
     if (subGroupStr.Contains("ftmulpbpb")) {
@@ -452,7 +456,19 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h
         hm->AddHistogram(histClass, "TPCnSigEle_pIN", "TPC n-#sigma(e) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaEl);
         hm->AddHistogram(histClass, "TPCnSigEle_timeFromSOR", "TPC n-#sigma(e) vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaEl);
         hm->AddHistogram(histClass, "TPCnSigPi_pIN", "TPC n-#sigma(#pi) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaPi);
-        hm->AddHistogram(histClass, "TPCnSigPi_timeFromSOR", "TPC n-#sigma(#pi) vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_timeFromSOR", "TPC n-#sigma(#pi) vs time from SOR", true, 1000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_eta", "TPC n-#sigma(#pi) vs #eta", false, 20, -1.0, 1.0, VarManager::kEta, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_etaPin_prof", "<TPC n-#sigma(#pi)> vs (#eta,p_{IN}), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 20, 0.0, 10.0, VarManager::kPin, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_etaCent_prof", "<TPC n-#sigma(#pi)> vs (#eta,cent), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 20, 0.0, 100.0, VarManager::kCentFT0C, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_etaContrib_prof", "<TPC n-#sigma(#pi)> vs (#eta,n-contrib real), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 20, 0.0, 4000.0, VarManager::kVtxNcontribReal, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_etaZA_prof", "<TPC n-#sigma(#pi)> vs (#eta,ZA), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 30, -15.0, 15.0, VarManager::kNTPCpileupZA, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_etaNZA_prof", "<TPC n-#sigma(#pi)> vs (#eta,NZA), --s--", true, 20, -1.0, 1.0, VarManager::kEta, 30, 0.0, 1500.0, VarManager::kNTPCpileupContribA, 10, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_centFT0C", "TPC n-#sigma(#pi) vs centrality", false, 20, 0.0, 100.0, VarManager::kCentFT0C, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_itsOccup", "TPC n-#sigma(#pi) vs vtx. contrib real", false, 50, 0.0, 4000.0, VarManager::kVtxNcontribReal, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_pileupZA", "TPC n-#sigma(#pi) vs pileup ZA", false, 60, -15.0, 15.0, VarManager::kNTPCpileupZA, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_pileupZC", "TPC n-#sigma(#pi) vs pileup ZC", false, 60, -15.0, 15.0, VarManager::kNTPCpileupZC, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_pileupNA", "TPC n-#sigma(#pi) vs n.pileup contrib A", false, 60, 0.0, 1500.0, VarManager::kNTPCpileupContribA, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
+        hm->AddHistogram(histClass, "TPCnSigPi_pileupNC", "TPC n-#sigma(#pi) vs n.pileup contrib C", false, 60, 0.0, 1500.0, VarManager::kNTPCpileupContribC, 200, -5.0, 5.0, VarManager::kTPCnSigmaPi);
         hm->AddHistogram(histClass, "TPCnSigKa_pIN", "TPC n-#sigma(K) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaKa);
         hm->AddHistogram(histClass, "TPCnSigPr_pIN", "TPC n-#sigma(p) vs pIN", false, 100, 0.0, 10.0, VarManager::kPin, 100, -5.0, 5.0, VarManager::kTPCnSigmaPr);
         hm->AddHistogram(histClass, "TPCnSigPr_timeFromSOR", "TPC n-#sigma(p) vs time from SOR", true, 10000, 0.0, 1000.0, VarManager::kTimeFromSOR, 10, -5.0, 5.0, VarManager::kTPCnSigmaPr);
@@ -801,7 +817,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h
       if (subGroupStr.Contains("pbpb")) {
         hm->AddHistogram(histClass, "Mass_CentFT0C", "", false, 500, 0.0, 5.0, VarManager::kMass, 20, 0.0, 100.0, VarManager::kCentFT0C);
         hm->AddHistogram(histClass, "Pt_CentFT0C", "", false, 500, 0.0, 1.5, VarManager::kPt, 20, 0.0, 100.0, VarManager::kCentFT0C);
-        hm->AddHistogram(histClass, "Mass_Pt_CentFT0C", "", false, 500, 0.0, 5.0, VarManager::kMass, 400, 0.0, 40.0, VarManager::kPt, 20, 0.0, 100.0, VarManager::kCentFT0C);
+        hm->AddHistogram(histClass, "Mass_Pt_CentFT0C", "", false, 500, 0.0, 5.0, VarManager::kMass, 250, 0.0, 10.0, VarManager::kPt, 10, 0.0, 100.0, VarManager::kCentFT0C);
       }
       if (subGroupStr.Contains("mult")) {
         hm->AddHistogram(histClass, "Mass_Pt_MultFV0A", "", false, 200, 0.0, 5.0, VarManager::kMass, 40, 0.0, 40.0, VarManager::kPt, 100, 0.0, 25000.0, VarManager::kMultFV0A);
diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h
index 0adc70b7169..e0a6085f44e 100644
--- a/PWGDQ/Core/VarManager.h
+++ b/PWGDQ/Core/VarManager.h
@@ -1471,6 +1471,7 @@ void VarManager::FillEvent(T const& event, float* values)
     values[kBC] = event.globalBC();
     values[kBCOrbit] = event.globalBC() % o2::constants::lhc::LHCMaxBunches;
     values[kTimestamp] = event.timestamp();
+    values[kTimeFromSOR] = (fgSOR > 0 ? (event.timestamp() - fgSOR) / 60000. : -1.0);
     values[kCentVZERO] = event.centRun2V0M();
     values[kCentFT0C] = event.centFT0C();
     if (fgUsedVars[kIsNoITSROFBorderRecomputed]) {
@@ -1627,6 +1628,14 @@ void VarManager::FillEvent(T const& event, float* values)
     values[kPsi2ANEG] = Psi2ANEG;
     values[kPsi2B] = Psi2B;
     values[kPsi2C] = Psi2C;
+
+    values[kR2SP_AB] = (values[kQ2X0A] * values[kQ2X0B] + values[kQ2Y0A] * values[kQ2Y0B]);
+    values[kR2SP_AC] = (values[kQ2X0A] * values[kQ2X0C] + values[kQ2Y0A] * values[kQ2Y0C]);
+    values[kR2SP_BC] = (values[kQ2X0B] * values[kQ2X0C] + values[kQ2Y0B] * values[kQ2Y0C]);
+
+    values[kR2EP_AB] = TMath::Cos(2 * (Psi2A - Psi2B));
+    values[kR2EP_AC] = TMath::Cos(2 * (Psi2A - Psi2C));
+    values[kR2EP_BC] = TMath::Cos(2 * (Psi2B - Psi2C));
   }
 
   if constexpr ((fillMap & CollisionMC) > 0) {
diff --git a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx
index 09e53dd1a68..bcb465d13fb 100644
--- a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx
+++ b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx
@@ -356,9 +356,9 @@ struct TableMakerMC {
         bool checked = false;
         if constexpr (soa::is_soa_filtered_v<aod::McParticles>) {
           auto mctrack_raw = mcTracks.rawIteratorAt(mctrack.globalIndex());
-          checked = sig.CheckSignal(false, mctrack_raw);
+          checked = sig.CheckSignal(true, mctrack_raw);
         } else {
-          checked = sig.CheckSignal(false, mctrack);
+          checked = sig.CheckSignal(true, mctrack);
         }
         if (checked) {
           mcflags |= (uint16_t(1) << i);
diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx
index b288c1f3974..7c1a51ddbc0 100644
--- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx
+++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx
@@ -506,7 +506,7 @@ struct AnalysisTrackSelection {
       if (filterMap > 0) {
         for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) {
           if (track.has_reducedMCTrack()) {
-            if ((*sig).CheckSignal(false, track.reducedMCTrack())) {
+            if ((*sig).CheckSignal(true, track.reducedMCTrack())) {
               mcDecision |= (uint32_t(1) << isig);
             }
           }
@@ -774,7 +774,7 @@ struct AnalysisMuonSelection {
       for (auto sig = fMCSignals.begin(); sig != fMCSignals.end(); sig++, isig++) {
         if constexpr ((TMuonFillMap & VarManager::ObjTypes::ReducedMuon) > 0) {
           if (track.has_reducedMCTrack()) {
-            if ((*sig).CheckSignal(false, track.reducedMCTrack())) {
+            if ((*sig).CheckSignal(true, track.reducedMCTrack())) {
               mcDecision |= (uint32_t(1) << isig);
             }
           }
@@ -874,6 +874,8 @@ struct AnalysisPrefilterSelection {
   Configurable<std::string> fConfigPrefilterTrackCut{"cfgPrefilterTrackCut", "", "Prefilter track cut"};
   Configurable<std::string> fConfigPrefilterPairCut{"cfgPrefilterPairCut", "", "Prefilter pair cut"};
   Configurable<std::string> fConfigTrackCuts{"cfgTrackCuts", "", "Track cuts for which to run the prefilter"};
+  // Track related options
+  Configurable<bool> fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"};
 
   std::map<uint32_t, uint32_t> fPrefilterMap;
   AnalysisCompositeCut* fPairCut;
@@ -938,8 +940,8 @@ struct AnalysisPrefilterSelection {
     VarManager::SetupTwoProngFwdDCAFitter(5.0f, true, 200.0f, 1.0e-3f, 0.9f, true);
   }
 
-  template <uint32_t TTrackFillMap, typename TTracks>
-  void runPrefilter(soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts> const& assocs, TTracks const& /*tracks*/)
+  template <uint32_t TTrackFillMap, typename TEvent, typename TTracks>
+  void runPrefilter(TEvent const& event, soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts> const& assocs, TTracks const& /*tracks*/)
   {
 
     for (auto& [assoc1, assoc2] : o2::soa::combinations(assocs, assocs)) {
@@ -964,6 +966,9 @@ struct AnalysisPrefilterSelection {
 
       // compute pair quantities
       VarManager::FillPair<VarManager::kDecayToEE, TTrackFillMap>(track1, track2);
+      if (fPropTrack) {
+        VarManager::FillPairCollision<VarManager::kDecayToEE, TTrackFillMap>(event, track1, track2);
+      }
       // if the pair fullfils the criteria, add an entry into the prefilter map for the two tracks
       if (fPairCut->IsSelected(VarManager::fgValues)) {
         if (fPrefilterMap.find(track1.globalIndex()) == fPrefilterMap.end() && track1Candidate > 0) {
@@ -984,7 +989,7 @@ struct AnalysisPrefilterSelection {
     for (auto& event : events) {
       auto groupedAssocs = assocs.sliceBy(trackAssocsPerCollision, event.globalIndex());
       if (groupedAssocs.size() > 1) {
-        runPrefilter<gkTrackFillMap>(groupedAssocs, tracks);
+        runPrefilter<gkTrackFillMap>(event, groupedAssocs, tracks);
       }
     }
     uint32_t mymap = -1;
@@ -1056,6 +1061,9 @@ struct AnalysisSameEventPairing {
   Configurable<std::string> fConfigMCGenSignals{"cfgBarrelMCGenSignals", "", "Comma separated list of MC signals (generated)"};
   Configurable<bool> fConfigSkimSignalOnly{"fConfigSkimSignalOnly", false, "Configurable to select only matched candidates"};
 
+  // Track related options
+  Configurable<bool> fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"};
+
   Service<o2::ccdb::BasicCCDBManager> fCCDB;
 
   // Filter filterEventSelected = aod::dqanalysisflags::isEventSelected & uint32_t(1);
@@ -1431,7 +1439,7 @@ struct AnalysisSameEventPairing {
           mcDecision = 0;
           for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) {
             if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) {
-              if ((*sig).CheckSignal(false, t1.reducedMCTrack(), t2.reducedMCTrack())) {
+              if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) {
                 mcDecision |= (uint32_t(1) << isig);
               }
             }
@@ -1442,6 +1450,9 @@ struct AnalysisSameEventPairing {
           }
 
           VarManager::FillPair<TPairType, TTrackFillMap>(t1, t2);
+          if (fPropTrack) {
+            VarManager::FillPairCollision<TPairType, TTrackFillMap>(event, t1, t2);
+          }
           if constexpr (TTwoProngFitter) {
             VarManager::FillPairVertexing<TPairType, TEventFillMap, TTrackFillMap>(event, t1, t2, fConfigPropToPCA);
           }
@@ -1478,7 +1489,7 @@ struct AnalysisSameEventPairing {
           mcDecision = 0;
           for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) {
             if (t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) {
-              if ((*sig).CheckSignal(false, t1.reducedMCTrack(), t2.reducedMCTrack())) {
+              if ((*sig).CheckSignal(true, t1.reducedMCTrack(), t2.reducedMCTrack())) {
                 mcDecision |= (uint32_t(1) << isig);
               }
             }
@@ -1490,6 +1501,9 @@ struct AnalysisSameEventPairing {
           }
 
           VarManager::FillPair<TPairType, TTrackFillMap>(t1, t2);
+          if (fPropTrack) {
+            VarManager::FillPairCollision<TPairType, TTrackFillMap>(event, t1, t2);
+          }
           if constexpr (TTwoProngFitter) {
             VarManager::FillPairVertexing<TPairType, TEventFillMap, TTrackFillMap>(event, t1, t2, fConfigPropToPCA);
           }
@@ -1637,9 +1651,9 @@ struct AnalysisSameEventPairing {
         bool checked = false;
         /*if constexpr (soa::is_soa_filtered_v<TTracksMC>) {
           auto mctrack_raw = groupedMCTracks.rawIteratorAt(mctrack.globalIndex());
-          checked = sig.CheckSignal(false, mctrack_raw);
+          checked = sig.CheckSignal(true, mctrack_raw);
         } else {*/
-        checked = sig.CheckSignal(false, mctrack);
+        checked = sig.CheckSignal(true, mctrack);
         //}
         if (checked) {
           fHistMan->FillHistClass(Form("MCTruthGen_%s", sig.GetName()), VarManager::fgValues);
@@ -1658,7 +1672,7 @@ struct AnalysisSameEventPairing {
             if (sig.GetNProngs() != 2) { // NOTE: 2-prong signals required here
               continue;
             }
-            if (sig.CheckSignal(false, t1_raw, t2_raw)) {
+            if (sig.CheckSignal(true, t1_raw, t2_raw)) {
               VarManager::FillPairMC(t1, t2);
               fHistMan->FillHistClass(Form("MCTruthGenPair_%s", sig.GetName()), VarManager::fgValues);
             }
@@ -1947,7 +1961,7 @@ struct AnalysisDileptonTrack {
           mcDecision = 0;
           isig = 0;
           for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) {
-            if ((*sig).CheckSignal(false, lepton1MC, lepton2MC, trackMC)) {
+            if ((*sig).CheckSignal(true, lepton1MC, lepton2MC, trackMC)) {
               mcDecision |= (uint32_t(1) << isig);
             }
           }
@@ -1968,7 +1982,7 @@ struct AnalysisDileptonTrack {
           mcDecision = 0;
           isig = 0;
           for (auto sig = fRecMCSignals.begin(); sig != fRecMCSignals.end(); sig++, isig++) {
-            if ((*sig).CheckSignal(false, lepton1MC, lepton2MC, trackMC)) {
+            if ((*sig).CheckSignal(true, lepton1MC, lepton2MC, trackMC)) {
               mcDecision |= (uint32_t(1) << isig);
             }
           }
@@ -2056,7 +2070,7 @@ struct AnalysisDileptonTrack {
       // TODO:  Use the mcReducedFlags to select signals
       isig = 0;
       for (auto& sig : fGenMCSignals) {
-        if (sig.CheckSignal(false, track)) {
+        if (sig.CheckSignal(true, track)) {
           fHistMan->FillHistClass(fHistNamesMCgen[isig++], VarManager::fgValues);
         }
       }
diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx
index 58fff03663d..f16d172f0ce 100644
--- a/PWGDQ/Tasks/tableReader_withAssoc.cxx
+++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx
@@ -98,8 +98,10 @@ DECLARE_SOA_TABLE(BmesonCandidates, "AOD", "DQBMESONS", dqanalysisflags::massBca
 
 // Declarations of various short names
 using MyEvents = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended>;
+using MyEventsMultExtra = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::ReducedEventsMultPV, aod::ReducedEventsMultAll>;
 using MyEventsZdc = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::ReducedZdcs>;
 using MyEventsSelected = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::EventCuts>;
+using MyEventsMultExtraSelected = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::ReducedEventsMultPV, aod::ReducedEventsMultAll, aod::EventCuts>;
 using MyEventsHashSelected = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::EventCuts, aod::MixingHashes>;
 using MyEventsVtxCov = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::ReducedEventsVtxCov>;
 using MyEventsVtxCovSelected = soa::Join<aod::ReducedEvents, aod::ReducedEventsExtended, aod::ReducedEventsVtxCov, aod::EventCuts>;
@@ -126,6 +128,7 @@ constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::ReducedEvent |
 constexpr static uint32_t gkEventFillMapWithZdc = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedZdc;
 constexpr static uint32_t gkEventFillMapWithCov = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov;
 constexpr static uint32_t gkEventFillMapWithCovZdc = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov | VarManager::ReducedZdc;
+constexpr static uint32_t gkEventFillMapWithMultExtra = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventMultExtra;
 // constexpr static uint32_t gkEventFillMapWithQvector = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventQvector;
 // constexpr static uint32_t gkEventFillMapWithCovQvector = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended | VarManager::ObjTypes::ReducedEventVtxCov | VarManager::ObjTypes::ReducedEventQvector;
 constexpr static uint32_t gkTrackFillMap = VarManager::ObjTypes::ReducedTrack | VarManager::ObjTypes::ReducedTrackBarrel | VarManager::ObjTypes::ReducedTrackBarrelPID;
@@ -174,7 +177,6 @@ struct AnalysisEventSelection {
 
   std::map<int64_t, bool> fSelMap;                     // key: reduced event global index, value: event selection decision
   std::map<uint64_t, std::vector<int64_t>> fBCCollMap; // key: global BC, value: vector of reduced event global indices
-  std::map<string, string> fMetadataRCT, fHeader;
   int fCurrentRun;
 
   void init(o2::framework::InitContext&)
@@ -214,18 +216,20 @@ struct AnalysisEventSelection {
   void runEventSelection(TEvents const& events)
   {
     if (events.size() > 0 && events.begin().runNumber() != fCurrentRun) {
-      fHeader = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), fMetadataRCT, -1);
-      uint64_t sor = std::atol(fHeader["SOR"].c_str());
-      uint64_t eor = std::atol(fHeader["EOR"].c_str());
-      LOGP(debug, "=========================== SOR / EOR is {} / {}", sor, eor);
-      // cout << "=========================== SOR / EOR is " << sor << " / " << eor << endl;
+      std::map<string, string> metadataRCT, header;
+      header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), metadataRCT, -1);
+      uint64_t sor = std::atol(header["SOR"].c_str());
+      uint64_t eor = std::atol(header["EOR"].c_str());
+      VarManager::SetSORandEOR(sor, eor);
+      LOG(info) << "============================= SOR / EOR :: " << sor << " / " << eor;
+
       auto alppar = fCCDB->getForTimeStamp<o2::itsmft::DPLAlpideParam<0>>("ITS/Config/AlpideParam", events.begin().timestamp());
       EventSelectionParams* par = fCCDB->getForTimeStamp<EventSelectionParams>("EventSelection/EventSelectionParams", events.begin().timestamp());
       int itsROFrameStartBorderMargin = fConfigITSROFrameStartBorderMargin < 0 ? par->fITSROFrameStartBorderMargin : fConfigITSROFrameStartBorderMargin;
       int itsROFrameEndBorderMargin = fConfigITSROFrameEndBorderMargin < 0 ? par->fITSROFrameEndBorderMargin : fConfigITSROFrameEndBorderMargin;
       VarManager::SetITSROFBorderselection(alppar->roFrameBiasInBC, alppar->roFrameLengthInBC, itsROFrameStartBorderMargin, itsROFrameEndBorderMargin);
       LOGP(debug, "==============++++++++++++========== roBias / roLength / start / end :: {} / {} / {} / {}", alppar->roFrameBiasInBC, alppar->roFrameLengthInBC, itsROFrameStartBorderMargin, itsROFrameEndBorderMargin);
-      // cout << "==============++++++++++++========== roBias / roLength / start / end :: " << alppar->roFrameBiasInBC << " / " << alppar->roFrameLengthInBC << " / " << itsROFrameStartBorderMargin << " / " << itsROFrameEndBorderMargin << endl;
+
       fCurrentRun = events.begin().runNumber();
     }
 
@@ -320,6 +324,11 @@ struct AnalysisEventSelection {
     runEventSelection<gkEventFillMapWithZdc>(events);
     publishSelections<gkEventFillMapWithZdc>(events);
   }
+  void processSkimmedWithMultExtra(MyEventsMultExtra const& events)
+  {
+    runEventSelection<gkEventFillMapWithMultExtra>(events);
+    publishSelections<gkEventFillMapWithMultExtra>(events);
+  }
   void processDummy(MyEvents&)
   {
     // do nothing
@@ -327,6 +336,7 @@ struct AnalysisEventSelection {
 
   PROCESS_SWITCH(AnalysisEventSelection, processSkimmed, "Run event selection on DQ skimmed events", false);
   PROCESS_SWITCH(AnalysisEventSelection, processSkimmedWithZdc, "Run event selection on DQ skimmed events, with ZDC", false);
+  PROCESS_SWITCH(AnalysisEventSelection, processSkimmedWithMultExtra, "Run event selection on DQ skimmed events, with mult extra", false);
   PROCESS_SWITCH(AnalysisEventSelection, processDummy, "Dummy function", false);
 };
 
@@ -351,6 +361,7 @@ struct AnalysisTrackSelection {
   Configurable<bool> fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"};
 
   Service<o2::ccdb::BasicCCDBManager> fCCDB;
+  o2::ccdb::CcdbApi fCCDBApi;
 
   HistogramManager* fHistMan;
   std::vector<AnalysisCompositeCut> fTrackCuts;
@@ -400,6 +411,7 @@ struct AnalysisTrackSelection {
       fCCDB->setLocalObjectValidityChecking();
       fCCDB->setCreatedNotAfter(fConfigNoLaterThan.value);
     }
+    fCCDBApi.init(fConfigCcdbUrl.value);
   }
 
   template <uint32_t TEventFillMap, uint32_t TTrackFillMap, typename TEvents, typename TTracks>
@@ -408,14 +420,16 @@ struct AnalysisTrackSelection {
     fNAssocsInBunch.clear();
     fNAssocsOutOfBunch.clear();
 
-    if (fConfigComputeTPCpostCalib && events.size() > 0 && fCurrentRun != events.begin().runNumber()) {
-      auto calibList = fCCDB->getForTimeStamp<TList>(fConfigCcdbPathTPC.value, events.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 (events.size() > 0 && fCurrentRun != events.begin().runNumber()) {
+      if (fConfigComputeTPCpostCalib) {
+        auto calibList = fCCDB->getForTimeStamp<TList>(fConfigCcdbPathTPC.value, events.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"));
+      }
 
       o2::parameters::GRPMagField* grpmag = fCCDB->getForTimeStamp<o2::parameters::GRPMagField>(grpmagPath, events.begin().timestamp());
       if (grpmag != nullptr) {
@@ -424,6 +438,12 @@ struct AnalysisTrackSelection {
         LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", events.begin().timestamp());
       }
 
+      std::map<string, string> metadataRCT, header;
+      header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), metadataRCT, -1);
+      uint64_t sor = std::atol(header["SOR"].c_str());
+      uint64_t eor = std::atol(header["EOR"].c_str());
+      VarManager::SetSORandEOR(sor, eor);
+
       fCurrentRun = events.begin().runNumber();
     }
 
@@ -528,6 +548,10 @@ struct AnalysisTrackSelection {
   {
     runTrackSelection<gkEventFillMap, gkTrackFillMap>(assocs, events, tracks);
   }
+  void processSkimmedWithMultExtra(ReducedTracksAssoc const& assocs, MyEventsMultExtraSelected const& events, MyBarrelTracks const& tracks)
+  {
+    runTrackSelection<gkEventFillMapWithMultExtra, gkTrackFillMap>(assocs, events, tracks);
+  }
   void processSkimmedWithCov(ReducedTracksAssoc const& assocs, MyEventsVtxCovSelected const& events, MyBarrelTracksWithCov const& tracks)
   {
     runTrackSelection<gkEventFillMapWithCov, gkTrackFillMapWithCov>(assocs, events, tracks);
@@ -538,6 +562,7 @@ struct AnalysisTrackSelection {
   }
 
   PROCESS_SWITCH(AnalysisTrackSelection, processSkimmed, "Run barrel track selection on DQ skimmed track associations", false);
+  PROCESS_SWITCH(AnalysisTrackSelection, processSkimmedWithMultExtra, "Run barrel track selection on DQ skimmed track associations, with extra multiplicity tables", false);
   PROCESS_SWITCH(AnalysisTrackSelection, processSkimmedWithCov, "Run barrel track selection on DQ skimmed tracks w/ cov matrix associations", false);
   PROCESS_SWITCH(AnalysisTrackSelection, processDummy, "Dummy function", false);
 };
@@ -931,6 +956,7 @@ struct AnalysisSameEventPairing {
   Configurable<bool> fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"};
 
   Service<o2::ccdb::BasicCCDBManager> fCCDB;
+  o2::ccdb::CcdbApi fCCDBApi;
 
   Filter filterEventSelected = aod::dqanalysisflags::isEventSelected == uint32_t(1);
 
@@ -960,7 +986,7 @@ struct AnalysisSameEventPairing {
 
   void init(o2::framework::InitContext& context)
   {
-    fEnableBarrelHistos = context.mOptions.get<bool>("processAllSkimmed") || context.mOptions.get<bool>("processBarrelOnlySkimmed") || context.mOptions.get<bool>("processBarrelOnlyWithCollSkimmed");
+    fEnableBarrelHistos = context.mOptions.get<bool>("processAllSkimmed") || context.mOptions.get<bool>("processBarrelOnlySkimmed") || context.mOptions.get<bool>("processBarrelOnlyWithCollSkimmed") || context.mOptions.get<bool>("processBarrelOnlySkimmedNoCov");
     fEnableBarrelMixingHistos = context.mOptions.get<bool>("processMixingAllSkimmed") || context.mOptions.get<bool>("processMixingBarrelSkimmed");
     fEnableMuonHistos = context.mOptions.get<bool>("processAllSkimmed") || context.mOptions.get<bool>("processMuonOnlySkimmed");
     fEnableMuonMixingHistos = context.mOptions.get<bool>("processMixingAllSkimmed");
@@ -1107,6 +1133,7 @@ struct AnalysisSameEventPairing {
     fCCDB->setURL(fConfigCcdbUrl.value);
     fCCDB->setCaching(true);
     fCCDB->setLocalObjectValidityChecking();
+    fCCDBApi.init(fConfigCcdbUrl.value);
 
     if (fConfigNoCorr) {
       VarManager::SetupFwdDCAFitterNoCorr();
@@ -1164,7 +1191,7 @@ struct AnalysisSameEventPairing {
     fOutputList.setObject(fHistMan->GetMainHistogramList());
   }
 
-  void initParamsFromCCDB(uint64_t timestamp, bool withTwoProngFitter = true)
+  void initParamsFromCCDB(uint64_t timestamp, int runNumber, bool withTwoProngFitter = true)
   {
 
     if (fConfigUseRemoteField.value) {
@@ -1197,6 +1224,12 @@ struct AnalysisSameEventPairing {
         VarManager::SetupTwoProngDCAFitter(fConfigMagField.value, true, 200.0f, 4.0f, 1.0e-3f, 0.9f, fConfigUseAbsDCA.value); // needed because take in varmanager Bz from fgFitterTwoProngBarrel for PhiV calculations
       }
     }
+
+    std::map<string, string> metadataRCT, header;
+    header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", runNumber), metadataRCT, -1);
+    uint64_t sor = std::atol(header["SOR"].c_str());
+    uint64_t eor = std::atol(header["EOR"].c_str());
+    VarManager::SetSORandEOR(sor, eor);
   }
 
   // Template function to run same event pairing (barrel-barrel, muon-muon, barrel-muon)
@@ -1205,7 +1238,7 @@ struct AnalysisSameEventPairing {
   {
     if (events.size() > 0) { // Additional protection to avoid crashing of events.begin().runNumber()
       if (fCurrentRun != events.begin().runNumber()) {
-        initParamsFromCCDB(events.begin().timestamp(), TTwoProngFitter);
+        initParamsFromCCDB(events.begin().timestamp(), events.begin().runNumber(), TTwoProngFitter);
         fCurrentRun = events.begin().runNumber();
       }
     }
@@ -1581,6 +1614,13 @@ struct AnalysisSameEventPairing {
     runSameEventPairing<true, VarManager::kDecayToEE, gkEventFillMapWithCov, gkTrackFillMapWithCov>(events, trackAssocsPerCollision, barrelAssocs, barrelTracks);
   }
 
+  void processBarrelOnlySkimmedNoCov(MyEventsSelected const& events,
+                                     soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts, aod::Prefilter> const& barrelAssocs,
+                                     MyBarrelTracksWithAmbiguities const& barrelTracks)
+  {
+    runSameEventPairing<false, VarManager::kDecayToEE, gkEventFillMap, gkTrackFillMap>(events, trackAssocsPerCollision, barrelAssocs, barrelTracks);
+  }
+
   void processBarrelOnlyWithCollSkimmed(MyEventsVtxCovSelected const& events,
                                         soa::Join<aod::ReducedTracksAssoc, aod::BarrelTrackCuts, aod::Prefilter> const& barrelAssocs,
                                         MyBarrelTracksWithCovWithAmbiguitiesWithColl const& barrelTracks)
@@ -1616,6 +1656,7 @@ struct AnalysisSameEventPairing {
   PROCESS_SWITCH(AnalysisSameEventPairing, processAllSkimmed, "Run all types of pairing, with skimmed tracks/muons", false);
   PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmed, "Run barrel only pairing, with skimmed tracks", false);
   PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlyWithCollSkimmed, "Run barrel only pairing, with skimmed tracks and with collision information", false);
+  PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmedNoCov, "Run barrel only pairing (no covariances), with skimmed tracks and with collision information", false);
   PROCESS_SWITCH(AnalysisSameEventPairing, processMuonOnlySkimmed, "Run muon only pairing, with skimmed tracks", false);
   PROCESS_SWITCH(AnalysisSameEventPairing, processMixingAllSkimmed, "Run all types of mixed pairing, with skimmed tracks/muons", false);
   PROCESS_SWITCH(AnalysisSameEventPairing, processMixingBarrelSkimmed, "Run barrel type mixing pairing, with skimmed tracks", false);
diff --git a/PWGEM/Dilepton/Core/PhotonHBT.h b/PWGEM/Dilepton/Core/PhotonHBT.h
index 839a96fdfc1..2499c668283 100644
--- a/PWGEM/Dilepton/Core/PhotonHBT.h
+++ b/PWGEM/Dilepton/Core/PhotonHBT.h
@@ -402,9 +402,9 @@ struct PhotonHBT {
     const AxisSpec axis_qinv{60, 0.0, +0.3, "q_{inv} (GeV/c)"};
     const AxisSpec axis_kstar{60, 0.0, +0.3, "k* (GeV/c)"};
     const AxisSpec axis_qabs_lcms{60, 0.0, +0.3, "|#bf{q}|^{LCMS} (GeV/c)"};
-    const AxisSpec axis_qout{60, -0.3, +0.3, "q_{out} (GeV/c)"};   // qout does not change between LAB and LCMS frame
-    const AxisSpec axis_qside{60, -0.3, +0.3, "q_{side} (GeV/c)"}; // qside does not change between LAB and LCMS frame
-    const AxisSpec axis_qlong{60, -0.3, +0.3, "q_{long} (GeV/c)"};
+    const AxisSpec axis_qout{60, 0.0, +0.3, "q_{out} (GeV/c)"};   // qout does not change between LAB and LCMS frame
+    const AxisSpec axis_qside{60, 0.0, +0.3, "q_{side} (GeV/c)"}; // qside does not change between LAB and LCMS frame
+    const AxisSpec axis_qlong{60, 0.0, +0.3, "q_{long} (GeV/c)"};
 
     if (cfgDo3D) {
       fRegistry.add("Pair/same/hs_3d", "diphoton correlation 3D LCMS", kTHnSparseD, {axis_qout, axis_qside, axis_qlong, axis_kt}, true);
@@ -555,19 +555,16 @@ struct PhotonHBT {
   template <int ev_id, typename TCollision>
   void fillPairHistogram(TCollision const&, const ROOT::Math::PtEtaPhiMVector v1, const ROOT::Math::PtEtaPhiMVector v2, const float weight = 1.f)
   {
-
     // Lab. frame
     ROOT::Math::PtEtaPhiMVector q12 = v1 - v2;
     ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2);
     float qinv = -q12.M(); // for identical particles -> qinv = 2 x kstar
     float kt = k12.Pt();
-    // float mt = std::sqrt(std::pow(k12.M(), 2) + std::pow(kt, 2));
 
     // ROOT::Math::XYZVector q_3d = q12.Vect();                                   // 3D q vector
     ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt
     ROOT::Math::XYZVector uv_long(0, 0, 1);                                    // unit vector for long, beam axis
     ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long);                     // unit vector for side
-    // float qlong_lab = q_3d.Dot(uv_long);
 
     ROOT::Math::PxPyPzEVector v1_cartesian(v1);
     ROOT::Math::PxPyPzEVector v2_cartesian(v2);
@@ -586,11 +583,14 @@ struct PhotonHBT {
     float qlong_lcms = q_3d_lcms.Dot(uv_long);
     float qabs_lcms = q_3d_lcms.R();
 
+    // float qabs_lcms_tmp = std::sqrt(std::pow(qout_lcms, 2) + std::pow(qside_lcms, 2) + std::pow(qlong_lcms, 2));
+    // LOGF(info, "qabs_lcms = %f, qabs_lcms_tmp = %f", qabs_lcms, qabs_lcms_tmp);
+
     // pair rest frame (PRF)
     ROOT::Math::Boost boostPRF = ROOT::Math::Boost(-beta_x, -beta_y, -beta_z);
-    ROOT::Math::PxPyPzEVector v1_pfr = boostPRF(v1_cartesian);
-    ROOT::Math::PxPyPzEVector v2_pfr = boostPRF(v2_cartesian);
-    ROOT::Math::PxPyPzEVector rel_k = v1_pfr - v2_pfr;
+    ROOT::Math::PxPyPzEVector v1_prf = boostPRF(v1_cartesian);
+    ROOT::Math::PxPyPzEVector v2_prf = boostPRF(v2_cartesian);
+    ROOT::Math::PxPyPzEVector rel_k = v1_prf - v2_prf;
     float kstar = 0.5 * rel_k.P();
     // LOGF(info, "qabs_lcms = %f, qinv = %f, kstar = %f", qabs_lcms, qinv, kstar);
 
@@ -609,7 +609,7 @@ struct PhotonHBT {
     // LOGF(info, "qabs_lcms = %f, qabs_lcms_tmp = %f", qabs_lcms, qabs_lcms_tmp);
 
     if (cfgDo3D) {
-      fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_3d"), qout_lcms, qside_lcms, qlong_lcms, kt, weight);
+      fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_3d"), fabs(qout_lcms), fabs(qside_lcms), fabs(qlong_lcms), kt, weight); // qosl can be [-inf, +inf] and CF is symmetric for pos and neg qosl. To reduce stat. unc. absolute value is taken here.
     } else {
       if constexpr (pairtype == ggHBTPairType::kPCMPCM) { // identical particle femtoscopy
         fRegistry.fill(HIST("Pair/") + HIST(event_pair_types[ev_id]) + HIST("hs_1d"), qinv, qabs_lcms, kt, weight);
diff --git a/PWGEM/Dilepton/TableProducer/eventSelection.cxx b/PWGEM/Dilepton/TableProducer/eventSelection.cxx
index f7bcfc4803a..2c804ddf2d4 100644
--- a/PWGEM/Dilepton/TableProducer/eventSelection.cxx
+++ b/PWGEM/Dilepton/TableProducer/eventSelection.cxx
@@ -118,5 +118,5 @@ struct EMEventSelection {
 };
 WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
 {
-  return WorkflowSpec{adaptAnalysisTask<EMEventSelection>(cfgc, TaskName{"event-selection"})};
+  return WorkflowSpec{adaptAnalysisTask<EMEventSelection>(cfgc, TaskName{"em-event-selection"})};
 }
diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx
index bbeed367428..4c3d50f2356 100644
--- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx
+++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx
@@ -83,8 +83,6 @@ struct skimmerPrimaryElectron {
   Configurable<float> maxTPCNsigmaPr{"maxTPCNsigmaPr", 2.5, "max. TPC n sigma for proton exclusion"};
   Configurable<float> minTPCNsigmaPr{"minTPCNsigmaPr", -2.5, "min. TPC n sigma for proton exclusion"};
   Configurable<bool> requireTOF{"requireTOF", false, "require TOF hit"};
-  Configurable<float> minTOFbeta{"minTOFbeta", 0.97, "min TOF beta for single track"}; // |beta - 1| < 0.015 corresponds to 3 sigma in pp
-  Configurable<float> maxTOFbeta{"maxTOFbeta", 1.03, "max TOF beta for single track"}; // |beta - 1| < 0.015 corresponds to 3 sigma in pp
 
   HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false};
 
@@ -236,7 +234,7 @@ struct skimmerPrimaryElectron {
       return false;
     }
 
-    if ((0.0 < track.beta() && track.beta() < minTOFbeta) || maxTOFbeta < track.beta()) {
+    if (track.hasTOF() && (maxTOFNsigmaEl < fabs(track.tofNSigmaEl()))) {
       return false;
     }
 
@@ -249,11 +247,11 @@ struct skimmerPrimaryElectron {
     float dcaXY = dcaInfo[0];
     float dcaZ = dcaInfo[1];
 
-    if (abs(dcaXY) > dca_xy_max || abs(dcaZ) > dca_z_max) {
+    if (fabs(dcaXY) > dca_xy_max || fabs(dcaZ) > dca_z_max) {
       return false;
     }
 
-    if (track_par_cov_recalc.getPt() < minpt || abs(track_par_cov_recalc.getEta()) > maxeta) {
+    if (track_par_cov_recalc.getPt() < minpt || fabs(track_par_cov_recalc.getEta()) > maxeta) {
       return false;
     }
 
@@ -263,7 +261,7 @@ struct skimmerPrimaryElectron {
       dca_3d = 999.f;
     } else {
       float chi2 = (dcaXY * dcaXY * track_par_cov_recalc.getSigmaZ2() + dcaZ * dcaZ * track_par_cov_recalc.getSigmaY2() - 2. * dcaXY * dcaZ * track_par_cov_recalc.getSigmaZY()) / det;
-      dca_3d = std::sqrt(std::abs(chi2) / 2.);
+      dca_3d = std::sqrt(std::fabs(chi2) / 2.);
     }
     if (dca_3d > dca_3d_sigma_max) {
       return false;
@@ -293,7 +291,7 @@ struct skimmerPrimaryElectron {
     if (minTPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < maxTPCNsigmaPr) {
       return false;
     }
-    if (!(track.beta() < 0.f || (minTOFbeta < track.beta() && track.beta() < maxTOFbeta))) {
+    if (track.hasTOF() && (maxTOFNsigmaEl < fabs(track.tofNSigmaEl()))) {
       return false;
     }
     return true;
@@ -305,10 +303,7 @@ struct skimmerPrimaryElectron {
     if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi) {
       return false;
     }
-    if (!(track.beta() < 0.f || (minTOFbeta < track.beta() && track.beta() < maxTOFbeta))) {
-      return false;
-    }
-    return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && abs(track.tofNSigmaEl()) < maxTOFNsigmaEl;
+    return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && fabs(track.tofNSigmaEl()) < maxTOFNsigmaEl;
   }
 
   template <typename TCollision, typename TTrack>
@@ -404,7 +399,7 @@ struct skimmerPrimaryElectron {
   Preslice<aod::TrackAssoc> trackIndicesPerCollision = aod::track_association::collisionId;
   std::vector<std::pair<int, int>> stored_trackIds;
   Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& o2::aod::track::tpcChi2NCl < maxchi2tpc&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true;
-  Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl && ((minTOFbeta < o2::aod::pidtofbeta::beta && o2::aod::pidtofbeta::beta < maxTOFbeta) || o2::aod::pidtofbeta::beta < 0.f) && (o2::aod::pidtpc::tpcNSigmaPi < minTPCNsigmaPi || maxTPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi);
+  Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl && (o2::aod::pidtpc::tpcNSigmaPi < minTPCNsigmaPi || maxTPCNsigmaPi < o2::aod::pidtpc::tpcNSigmaPi);
   using MyFilteredTracks = soa::Filtered<MyTracks>;
 
   Partition<MyFilteredTracks> posTracks = o2::aod::track::signed1Pt > 0.f;
@@ -728,14 +723,14 @@ struct prefilterPrimaryElectron {
     o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo);
     getPxPyPz(track_par_cov_recalc, pVec_recalc);
 
-    if (abs(dcaInfo[0]) < min_dcatopv) {
+    if (fabs(dcaInfo[0]) < min_dcatopv) {
       return false;
     }
 
     if (isITSonlyTrack(track) && track_par_cov_recalc.getPt() > max_pt_itsonly) {
       return false;
     }
-    if (abs(track_par_cov_recalc.getEta()) > maxeta) {
+    if (fabs(track_par_cov_recalc.getEta()) > maxeta) {
       return false;
     }
 
@@ -786,7 +781,6 @@ struct prefilterPrimaryElectron {
 
   Preslice<aod::TrackAssoc> trackIndicesPerCollision = aod::track_association::collisionId;
 
-  // Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& min_dcatopv < nabs(o2::aod::track::dcaXY) && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true;
   Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true;
   using MyFilteredTracks = soa::Filtered<MyTracks>;
   Partition<MyFilteredTracks> posTracks = o2::aod::track::signed1Pt > 0.f;
diff --git a/PWGJE/Core/JetUtilities.h b/PWGJE/Core/JetUtilities.h
index a681d76bf89..dac55dfbaa1 100644
--- a/PWGJE/Core/JetUtilities.h
+++ b/PWGJE/Core/JetUtilities.h
@@ -141,12 +141,20 @@ std::tuple<std::vector<std::vector<int>>, std::vector<std::vector<int>>> MatchCl
 template <typename T, typename U>
 float deltaR(T const& A, U const& B)
 {
-  float dPhi = RecoDecay::constrainAngle(A.phi() - B.phi(), -M_PI);
+  float dPhi = RecoDecay::constrainAngle(RecoDecay::constrainAngle(A.phi(), -M_PI) - RecoDecay::constrainAngle(B.phi(), -M_PI), -M_PI);
   float dEta = A.eta() - B.eta();
 
-  return TMath::Sqrt(dEta * dEta + dPhi * dPhi);
+  return std::sqrt(dEta * dEta + dPhi * dPhi);
 }
+// same as deltaR but explicit specification of the eta and phi components
+template <typename T, typename U, typename V, typename W>
+float deltaR(T const& eta1, U const& phi1, V const& eta2, W const& phi2)
+{
+  float dPhi = RecoDecay::constrainAngle(RecoDecay::constrainAngle(phi1, -M_PI) - RecoDecay::constrainAngle(phi2, -M_PI), -M_PI);
+  float dEta = eta1 - eta2;
 
+  return std::sqrt(dEta * dEta + dPhi * dPhi);
+}
 }; // namespace jetutilities
 
 #endif // PWGJE_CORE_JETUTILITIES_H_
diff --git a/PWGJE/DataModel/GammaJetAnalysisTree.h b/PWGJE/DataModel/GammaJetAnalysisTree.h
new file mode 100644
index 00000000000..beb927f381c
--- /dev/null
+++ b/PWGJE/DataModel/GammaJetAnalysisTree.h
@@ -0,0 +1,75 @@
+// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
+// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
+// All rights not expressly granted are reserved.
+//
+// This software is distributed under the terms of the GNU General Public
+// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
+//
+// In applying this license CERN does not waive the privileges and immunities
+// granted to it by virtue of its status as an Intergovernmental Organization
+// or submit itself to any jurisdiction.
+
+///
+/// \brief Table definitions for gamma-jet analyses
+///
+/// \author Florian Jonas <florian.jonas@cern.ch>
+
+#ifndef PWGJE_DATAMODEL_GAMMAJETANALYSISTREE_H_
+#define PWGJE_DATAMODEL_GAMMAJETANALYSISTREE_H_
+
+#include "Framework/AnalysisDataModel.h"
+#include "PWGJE/DataModel/EMCALClusters.h"
+#include "PWGJE/Core/JetDerivedDataUtilities.h"
+#include "PWGJE/DataModel/Jet.h"
+
+namespace o2::aod
+{
+
+namespace gjevent
+{ // TODO add rho                          //! event index
+DECLARE_SOA_COLUMN(Multiplicity, multiplicity, float);
+DECLARE_SOA_COLUMN(Centrality, centrality, float);
+DECLARE_SOA_COLUMN(Rho, rho, float);
+DECLARE_SOA_COLUMN(EventSel, eventSel, uint8_t);
+DECLARE_SOA_BITMAP_COLUMN(Alias, alias, 32);
+} // namespace gjevent
+DECLARE_SOA_TABLE(GjEvents, "AOD", "GJEVENT", o2::soa::Index<>, gjevent::Multiplicity, gjevent::Centrality, gjevent::Rho, gjevent::EventSel, gjevent::Alias)
+
+using GjEvent = GjEvents::iterator;
+
+namespace gjgamma
+{
+DECLARE_SOA_INDEX_COLUMN(GjEvent, gjevent);                            //! event index
+DECLARE_SOA_COLUMN(Energy, energy, float);                             //! cluster energy (GeV)
+DECLARE_SOA_COLUMN(Eta, eta, float);                                   //! cluster pseudorapidity (calculated using vertex)
+DECLARE_SOA_COLUMN(Phi, phi, float);                                   //! cluster azimuthal angle (calculated using vertex)
+DECLARE_SOA_COLUMN(M02, m02, float);                                   //! shower shape long axis
+DECLARE_SOA_COLUMN(M20, m20, float);                                   //! shower shape short axis
+DECLARE_SOA_COLUMN(NCells, nCells, ushort);                            //! number of cells in cluster
+DECLARE_SOA_COLUMN(Time, time, float);                                 //! cluster time (ns)
+DECLARE_SOA_COLUMN(IsExotic, isExotic, bool);                          //! flag to mark cluster as exotic
+DECLARE_SOA_COLUMN(DistanceToBadChannel, distanceToBadChannel, float); //! distance to bad channel
+DECLARE_SOA_COLUMN(NLM, nlm, ushort);                                  //! number of local maxima
+DECLARE_SOA_COLUMN(IsoRaw, isoraw, ushort);                            //! isolation in cone not corrected for Rho
+DECLARE_SOA_COLUMN(PerpConeRho, perpconerho, float);                   //! rho in perpendicular cone
+DECLARE_SOA_COLUMN(TMdeltaPhi, tmdeltaphi, float);                     //! delta phi between cluster and closest match
+DECLARE_SOA_COLUMN(TMdeltaEta, tmdeltaeta, float);                     //! delta eta between cluster and closest match
+DECLARE_SOA_COLUMN(TMtrackP, tmtrackp, float);                         //! track momentum of closest match, -1 if no match found
+} // namespace gjgamma
+DECLARE_SOA_TABLE(GjGammas, "AOD", "GJGAMMA",
+                  gjgamma::GjEventId, gjgamma::Energy, gjgamma::Eta, gjgamma::Phi, gjgamma::M02, gjgamma::M20, gjgamma::NCells, gjgamma::Time, gjgamma::IsExotic, gjgamma::DistanceToBadChannel, gjgamma::NLM, gjgamma::IsoRaw, gjgamma::PerpConeRho, gjgamma::TMdeltaPhi, gjgamma::TMdeltaEta, gjgamma::TMtrackP)
+namespace gjchjet
+{
+DECLARE_SOA_INDEX_COLUMN(GjEvent, gjevent);
+DECLARE_SOA_COLUMN(Pt, pt, float);
+DECLARE_SOA_COLUMN(Eta, eta, float);
+DECLARE_SOA_COLUMN(Phi, phi, float);
+DECLARE_SOA_COLUMN(Energy, energy, float);
+DECLARE_SOA_COLUMN(Mass, mass, float);
+DECLARE_SOA_COLUMN(Area, area, float);
+DECLARE_SOA_COLUMN(NConstituents, nConstituents, ushort);
+} // namespace gjchjet
+DECLARE_SOA_TABLE(GjChargedJets, "AOD", "GJCHJET", gjchjet::GjEventId, gjchjet::Pt, gjchjet::Eta, gjchjet::Phi, gjchjet::Energy, gjchjet::Mass, gjchjet::Area, gjchjet::NConstituents)
+} // namespace o2::aod
+
+#endif // PWGJE_DATAMODEL_GAMMAJETANALYSISTREE_H_
diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt
index adbd4e141a5..a9ac88c8f28 100644
--- a/PWGJE/Tasks/CMakeLists.txt
+++ b/PWGJE/Tasks/CMakeLists.txt
@@ -168,6 +168,10 @@ if(FastJet_FOUND)
                         SOURCES fulljetspectrapp.cxx
                         PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore
                         COMPONENT_NAME Analysis)
+    o2physics_add_dpl_workflow(gamma-jet-tree-producer
+                        SOURCES gammajettreeproducer.cxx
+                        PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::PWGJECore O2Physics::AnalysisCore
+                        COMPONENT_NAME Analysis)
     o2physics_add_dpl_workflow(bjet-tagging-ml
                         SOURCES bjetTaggingML.cxx
                         PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2Physics::MLCore
diff --git a/PWGJE/Tasks/gammajettreeproducer.cxx b/PWGJE/Tasks/gammajettreeproducer.cxx
new file mode 100644
index 00000000000..d721ca725df
--- /dev/null
+++ b/PWGJE/Tasks/gammajettreeproducer.cxx
@@ -0,0 +1,295 @@
+// 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/ASoA.h"
+#include "Framework/AnalysisDataModel.h"
+#include "Framework/AnalysisTask.h"
+#include "Framework/HistogramRegistry.h"
+
+#include "Common/Core/RecoDecay.h"
+#include "Common/Core/TrackSelection.h"
+#include "Common/Core/TrackSelectionDefaults.h"
+#include "Common/DataModel/EventSelection.h"
+#include "Common/DataModel/TrackSelectionTables.h"
+
+#include "PWGJE/Core/FastJetUtilities.h"
+#include "PWGJE/Core/JetDerivedDataUtilities.h"
+#include "PWGJE/Core/JetUtilities.h"
+#include "PWGJE/DataModel/Jet.h"
+#include "PWGJE/DataModel/GammaJetAnalysisTree.h"
+
+#include "EMCALBase/Geometry.h"
+#include "EMCALCalib/BadChannelMap.h"
+#include "PWGJE/DataModel/EMCALClusters.h"
+#include "DataFormatsEMCAL/Cell.h"
+#include "DataFormatsEMCAL/Constants.h"
+#include "DataFormatsEMCAL/AnalysisCluster.h"
+#include "TVector2.h"
+
+#include "CommonDataFormat/InteractionRecord.h"
+
+#include "EventFiltering/filterTables.h"
+
+// \struct GammaJetTreeProducer
+/// \brief Task to produce a tree for gamma-jet analysis, including photons (and information of isolation) and charged and full jets
+/// \author Florian Jonas <florian.jonas@cern.ch>, UC Berkeley/LBNL
+/// \since 02.08.2024
+///
+using namespace o2;
+using namespace o2::framework;
+using namespace o2::framework::expressions;
+using selectedClusters = o2::soa::Filtered<o2::aod::JClusters>;
+
+#include "Framework/runDataProcessing.h"
+
+struct GammaJetTreeProducer {
+  // analysis tree
+  // charged jets
+  // photon candidates
+  Produces<aod::GjChargedJets> chargedJetsTable;
+  Produces<aod::GjEvents> eventsTable;
+  Produces<aod::GjGammas> gammasTable;
+
+  HistogramRegistry mHistograms{"GammaJetTreeProducerHisto"};
+
+  // ---------------
+  // Configureables
+  // ---------------
+
+  // event cuts
+  Configurable<double> mVertexCut{"vertexCut", 10.0, "apply z-vertex cut with value in cm"};
+  Configurable<std::string> eventSelections{"eventSelections", "sel8", "choose event selection"};
+  Configurable<std::string> triggerMasks{"triggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"};
+  Configurable<std::string>
+    trackSelections{"trackSelections", "globalTracks", "set track selections"};
+  Configurable<float> trackMinPt{"trackMinPt", 0.15, "minimum track pT cut"};
+  Configurable<float> jetPtMin{"jetPtMin", 5.0, "minimum jet pT cut"};
+  Configurable<float> jetR{"jetR", 0.4, "jet resolution parameter"};
+  Configurable<float> isoR{"isoR", 0.4, "isolation cone radius"};
+
+  // cluster cuts
+  Configurable<int> mClusterDefinition{"clusterDefinition", 10, "cluster definition to be selected, e.g. 10=kV3Default"};
+  // Preslice<o2::aod::JClusterTracks> perClusterMatchedTracks = o2::aod::jcluster::clusterId;
+
+  int mRunNumber = 0;
+  int eventSelection = -1;
+  int trackSelection = -1;
+
+  std::unordered_map<int32_t, int32_t> collisionMapping;
+  std::vector<int> triggerMaskBits;
+
+  void init(InitContext const&)
+  {
+    using o2HistType = HistType;
+    using o2Axis = AxisSpec;
+
+    eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast<std::string>(eventSelections));
+    triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks);
+    trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast<std::string>(trackSelections));
+
+    // create histograms
+    LOG(info) << "Creating histograms";
+
+    const o2Axis ptAxis{100, 0, 100, "p_{T} (GeV/c)"};
+    const o2Axis energyAxis{100, 0, 100, "E (GeV)"};
+    const o2Axis m02Axis{100, 0, 3, "m02"};
+
+    mHistograms.add("clusterE", "Energy of cluster", o2HistType::kTH1F, {energyAxis});
+    mHistograms.add("trackPt", "pT of track", o2HistType::kTH1F, {ptAxis});
+    mHistograms.add("chjetPt", "pT of charged jet", o2HistType::kTH1F, {ptAxis});
+    mHistograms.add("chjetpt_vs_constpt", "pT of charged jet vs pT of constituents", o2HistType::kTH2F, {ptAxis, ptAxis});
+  }
+
+  // ---------------------
+  // Helper functions
+  // ---------------------
+  bool isTrackSelected(const auto& track)
+  {
+    if (!jetderiveddatautilities::selectTrack(track, trackSelection)) {
+      return false;
+    }
+    if (track.pt() < trackMinPt) {
+      return false;
+    }
+
+    return true;
+  }
+
+  bool isEventAccepted(const auto& collision)
+  {
+
+    if (collision.posZ() > mVertexCut) {
+      return false;
+    }
+    if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) {
+      return false;
+    }
+    if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) {
+      return false;
+    }
+    if (!jetderiveddatautilities::eventEMCAL(collision)) {
+      return false;
+    }
+    return true;
+  }
+
+  double ch_iso_in_cone(const auto& cluster, JetTracks const& tracks, float radius = 0.4)
+  {
+    double iso = 0;
+    for (auto track : tracks) {
+      if (!isTrackSelected(track)) {
+        continue;
+      }
+      // make dR function live somwhere else
+      float dR = jetutilities::deltaR(cluster, track);
+      if (dR < radius) {
+        iso += track.pt();
+      }
+    }
+    return iso;
+  }
+  double ch_perp_cone_rho(const auto& cluster, JetTracks const& tracks, float radius = 0.4)
+  {
+    double ptSumLeft = 0;
+    double ptSumRight = 0;
+
+    double cPhi = TVector2::Phi_0_2pi(cluster.phi());
+
+    // rotate cone left by 90 degrees
+    float cPhiLeft = cPhi - TMath::Pi() / 2;
+    float cPhiRight = cPhi + TMath::Pi() / 2;
+
+    // loop over tracks
+    float dRLeft, dRRight;
+    for (auto track : tracks) {
+      if (!isTrackSelected(track)) {
+        continue;
+      }
+      dRLeft = jetutilities::deltaR(cluster.eta(), cPhiLeft, track.eta(), track.phi());
+      dRRight = jetutilities::deltaR(cluster.eta(), cPhiRight, track.eta(), track.phi());
+
+      if (dRLeft < radius) {
+        ptSumLeft += track.pt();
+      }
+      if (dRRight < radius) {
+        ptSumRight += track.pt();
+      }
+    }
+
+    float rho = (ptSumLeft + ptSumRight) / (2 * TMath::Pi() * radius * radius);
+    return rho;
+  }
+
+  // ---------------------
+  // Processing functions
+  // ---------------------
+  void processClearMaps(JetCollisions const&)
+  {
+    collisionMapping.clear();
+  }
+  PROCESS_SWITCH(GammaJetTreeProducer, processClearMaps, "process function that clears all the maps in each dataframe", true);
+
+  // define cluster filter. It selects only those clusters which are of the type
+  // sadly passing of the string at runtime is not possible for technical region so cluster definition is
+  // an integer instead
+  Filter clusterDefinitionSelection = (o2::aod::jcluster::definition == mClusterDefinition);
+  // Process clusters
+  void processClusters(soa::Join<JetCollisions, aod::BkgChargedRhos, aod::JCollisionBCs>::iterator const& collision, selectedClusters const& clusters, JetTracks const& tracks)
+  {
+    if (!isEventAccepted(collision)) {
+      return;
+    }
+
+    eventsTable(collision.multiplicity(), collision.centrality(), collision.rho(), collision.eventSel(), collision.alias_raw());
+    collisionMapping[collision.globalIndex()] = eventsTable.lastIndex();
+
+    // loop over clusters
+    for (auto cluster : clusters) {
+
+      // fill histograms
+      mHistograms.fill(HIST("clusterE"), cluster.energy());
+
+      double isoraw = ch_iso_in_cone(cluster, tracks, isoR);
+      double perpconerho = ch_perp_cone_rho(cluster, tracks, isoR);
+
+      // find closest matched track
+      double dEta = 0;
+      double dPhi = 0;
+      // double dRMin = 100;
+      double p = -1;
+
+      // auto tracksofcluster = matchedtracks.sliceBy(perClusterMatchedTracks, cluster.globalIndex());
+      // for (const auto& match : tracksofcluster) {
+      //   // ask the jtracks table for track with ID trackID
+      //   double dR = deltaR(cluster.eta(), cluster.phi(), match.tracks_as<o2::aod::JTracks>().Eta(), match.tracks_as<o2::aod::JTracks>().Phi());
+      //   if (dR < dRMin) {
+      //     dRMin = dR;
+      //     dEta = cluster.eta() - match.tracks_as<o2::aod::JTracks>().eta();
+      //     dPhi = TVector2::Phi_0_2pi(cluster.phi()) - TVector2::Phi_0_2pi(match.tracks_as<o2::aod::JTracks>().phi());
+      //     if (abs(dPhi) > M_PI) {
+      //       dPhi = 2 * M_PI - abs(dPhi);
+      //     }
+      //     p = match.tracks_as<o2::aod::JTracks>().p();
+      //   }
+      // }
+
+      // // for compression reasons make dPhi and dEta 0 if no match is found
+      // if (p == -1) {
+      //   dPhi = 0;
+      //   dEta = 0;
+      // }
+
+      gammasTable(eventsTable.lastIndex(), cluster.energy(), cluster.eta(), cluster.phi(), cluster.m02(), cluster.m20(), cluster.nCells(), cluster.time(), cluster.isExotic(), cluster.distanceToBadChannel(), cluster.nlm(), isoraw, perpconerho, dPhi, dEta, p);
+    }
+
+    // dummy loop over tracks
+    for (auto track : tracks) {
+      mHistograms.fill(HIST("trackPt"), track.pt());
+    }
+  }
+  PROCESS_SWITCH(GammaJetTreeProducer, processClusters, "Process EMCal clusters", true);
+
+  Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f);
+  // Process charged jets
+  void processChargedJets(soa::Join<JetCollisions, aod::BkgChargedRhos, aod::JCollisionBCs>::iterator const& collision, soa::Filtered<soa::Join<aod::ChargedJets, aod::ChargedJetConstituents>> const& chargedJets, JetTracks const&)
+  {
+    // event selection
+    if (!isEventAccepted(collision)) {
+      return;
+    }
+
+    // loop over charged jets
+    for (auto jet : chargedJets) {
+      if (jet.pt() < jetPtMin)
+        continue;
+      ushort nconst = 0;
+      // loop over constituents
+      for (auto& constituent : jet.template tracks_as<JetTracks>()) {
+        mHistograms.fill(HIST("chjetpt_vs_constpt"), jet.pt(), constituent.pt());
+        nconst++;
+      }
+      int32_t storedColIndex = -1;
+      if (auto foundCol = collisionMapping.find(collision.globalIndex()); foundCol != collisionMapping.end()) {
+        storedColIndex = foundCol->second;
+      }
+      chargedJetsTable(storedColIndex, jet.pt(), jet.eta(), jet.phi(), jet.energy(), jet.mass(), jet.area(), nconst);
+      // fill histograms
+      mHistograms.fill(HIST("chjetPt"), jet.pt());
+    }
+  }
+  PROCESS_SWITCH(GammaJetTreeProducer, processChargedJets, "Process charged jets", true);
+};
+WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
+{
+  WorkflowSpec workflow{
+    adaptAnalysisTask<GammaJetTreeProducer>(cfgc, TaskName{"gamma-jet-tree-producer"})};
+  return workflow;
+}
diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h
index c61c1b25a7b..afc076d1a54 100644
--- a/PWGLF/DataModel/LFSlimNucleiTables.h
+++ b/PWGLF/DataModel/LFSlimNucleiTables.h
@@ -41,6 +41,7 @@ DECLARE_SOA_COLUMN(TPCfindableCls, tpcFindableCls, uint8_t);
 DECLARE_SOA_COLUMN(TPCcrossedRows, tpcCrossedRows, uint8_t);
 DECLARE_SOA_COLUMN(ITSclsMap, itsClsMap, uint8_t);
 DECLARE_SOA_COLUMN(TPCnCls, tpcNCls, uint8_t);
+DECLARE_SOA_COLUMN(TPCnClsShared, tpcNClsShared, uint8_t);
 DECLARE_SOA_COLUMN(ITSclusterSizes, itsClusterSizes, uint32_t);
 DECLARE_SOA_COLUMN(gPt, genPt, float);
 DECLARE_SOA_COLUMN(gEta, genEta, float);
@@ -83,6 +84,7 @@ DECLARE_SOA_TABLE(NucleiTable, "AOD", "NUCLEITABLE",
                   NucleiTableNS::TPCcrossedRows,
                   NucleiTableNS::ITSclsMap,
                   NucleiTableNS::TPCnCls,
+                  NucleiTableNS::TPCnClsShared,
                   NucleiTableNS::ITSclusterSizes);
 
 DECLARE_SOA_TABLE(NucleiTableFlow, "AOD", "NUCLEITABLEFLOW",
@@ -116,6 +118,7 @@ DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC",
                   NucleiTableNS::TPCcrossedRows,
                   NucleiTableNS::ITSclsMap,
                   NucleiTableNS::TPCnCls,
+                  NucleiTableNS::TPCnClsShared,
                   NucleiTableNS::ITSclusterSizes,
                   NucleiTableNS::gPt,
                   NucleiTableNS::gEta,
diff --git a/PWGLF/DataModel/LFStrangenessPIDTables.h b/PWGLF/DataModel/LFStrangenessPIDTables.h
index 36a345b87ad..e689dc28141 100644
--- a/PWGLF/DataModel/LFStrangenessPIDTables.h
+++ b/PWGLF/DataModel/LFStrangenessPIDTables.h
@@ -137,15 +137,15 @@ DECLARE_SOA_COLUMN(BachTOFEventTime, bachTOFEventTime, float);   //! bachelor tr
 
 // delta-times
 DECLARE_SOA_COLUMN(PosTOFDeltaTXiPi, posTOFDeltaTXiPi, float);   //! positive track TOFDeltaT from pion <- lambda <- xi expectation
-DECLARE_SOA_COLUMN(PosTOFDeltaTXiPr, posTOFDeltaTXiPr, float);   //! positive track TOFDeltaT from pion <- lambda <- xi expectation
+DECLARE_SOA_COLUMN(PosTOFDeltaTXiPr, posTOFDeltaTXiPr, float);   //! positive track TOFDeltaT from proton <- lambda <- xi expectation
 DECLARE_SOA_COLUMN(NegTOFDeltaTXiPi, negTOFDeltaTXiPi, float);   //! negative track TOFDeltaT from pion <- lambda <- xi expectation
-DECLARE_SOA_COLUMN(NegTOFDeltaTXiPr, negTOFDeltaTXiPr, float);   //! negative track TOFDeltaT from pion <- lambda <- xi expectation
+DECLARE_SOA_COLUMN(NegTOFDeltaTXiPr, negTOFDeltaTXiPr, float);   //! negative track TOFDeltaT from proton <- lambda <- xi expectation
 DECLARE_SOA_COLUMN(BachTOFDeltaTXiPi, bachTOFDeltaTXiPi, float); //! bachelor track TOFDeltaT from pion <- xi expectation
 DECLARE_SOA_COLUMN(PosTOFDeltaTOmPi, posTOFDeltaTOmPi, float);   //! positive track TOFDeltaT from pion <- lambda <- omega expectation
-DECLARE_SOA_COLUMN(PosTOFDeltaTOmPr, posTOFDeltaTOmPr, float);   //! positive track TOFDeltaT from pion <- lambda <- omega expectation
+DECLARE_SOA_COLUMN(PosTOFDeltaTOmPr, posTOFDeltaTOmPr, float);   //! positive track TOFDeltaT from proton <- lambda <- omega expectation
 DECLARE_SOA_COLUMN(NegTOFDeltaTOmPi, negTOFDeltaTOmPi, float);   //! negative track TOFDeltaT from pion <- lambda <- omega expectation
-DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float);   //! negative track TOFDeltaT from pion <- lambda <- omega expectation
-DECLARE_SOA_COLUMN(BachTOFDeltaTOmPi, bachTOFDeltaTOmPi, float); //! bachelor track TOFDeltaT from pion <- omega expectation
+DECLARE_SOA_COLUMN(NegTOFDeltaTOmPr, negTOFDeltaTOmPr, float);   //! negative track TOFDeltaT from proton <- lambda <- omega expectation
+DECLARE_SOA_COLUMN(BachTOFDeltaTOmKa, bachTOFDeltaTOmKa, float); //! bachelor track TOFDeltaT from kaon <- omega expectation
 
 // n-sigmas
 DECLARE_SOA_COLUMN(TOFNSigmaXiLaPi, tofNSigmaXiLaPi, float); //! meson track NSigma from pion <- lambda <- xi expectation
@@ -170,7 +170,7 @@ DECLARE_SOA_TABLE(CascTOFPIDs, "AOD", "CASCTOFPID", // processed information for
                   cascdata::BachTOFDeltaTXiPi,
                   cascdata::PosTOFDeltaTOmPi, cascdata::PosTOFDeltaTOmPr,
                   cascdata::NegTOFDeltaTOmPi, cascdata::NegTOFDeltaTOmPr,
-                  cascdata::BachTOFDeltaTOmPi);
+                  cascdata::BachTOFDeltaTOmKa);
 DECLARE_SOA_TABLE(CascTOFNSigmas, "AOD", "CascTOFNSigmas", // Nsigmas for cascades
                   cascdata::TOFNSigmaXiLaPi, cascdata::TOFNSigmaXiLaPr, cascdata::TOFNSigmaXiPi,
                   cascdata::TOFNSigmaOmLaPi, cascdata::TOFNSigmaOmLaPr, cascdata::TOFNSigmaOmKa);
diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h
index 1eedee47828..2e77610a4c6 100644
--- a/PWGLF/DataModel/LFStrangenessTables.h
+++ b/PWGLF/DataModel/LFStrangenessTables.h
@@ -22,10 +22,31 @@
 #include "Common/DataModel/Qvectors.h"
 #include "Common/DataModel/McCollisionExtra.h"
 #include "PWGLF/DataModel/EPCalibrationTables.h"
+#include "PWGUD/DataModel/UDTables.h"
 
 namespace o2::aod
 {
 
+namespace stracollision
+{
+DECLARE_SOA_DYNAMIC_COLUMN(IsUPC, isUPC, //! check whether this is a UPC or hadronic collision
+                           [](int value) -> bool { return value <= 2 ? true : false; });
+DECLARE_SOA_DYNAMIC_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, //! get the total sum of the FV0 A amplitudes
+                           [](float value) -> float { return value; });
+DECLARE_SOA_DYNAMIC_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, //! get the total sum of the FT0 A amplitudes
+                           [](float value) -> float { return value; });
+DECLARE_SOA_DYNAMIC_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, //! get the total sum of the FT0 C amplitudes
+                           [](float value) -> float { return value; });
+DECLARE_SOA_DYNAMIC_COLUMN(TotalFDDAmplitudeA, totalFDDAmplitudeA, //! get the total sum of the FDD A amplitudes
+                           [](float value) -> float { return value; });
+DECLARE_SOA_DYNAMIC_COLUMN(TotalFDDAmplitudeC, totalFDDAmplitudeC, //! get the total sum of the FDD C amplitudes
+                           [](float value) -> float { return value; });
+DECLARE_SOA_DYNAMIC_COLUMN(EnergyCommonZNA, energyCommonZNA, //! get the total sum of the ZN A amplitudes
+                           [](float value) -> float { return value; });
+DECLARE_SOA_DYNAMIC_COLUMN(EnergyCommonZNC, energyCommonZNC, //! get the total sum of the ZN A amplitudes
+                           [](float value) -> float { return value; });
+} // namespace stracollision
+
 //______________________________________________________
 // Collision declarations for derived data analysis
 // this is optional but will ensure full flexibility
@@ -35,13 +56,16 @@ DECLARE_SOA_TABLE(StraCollisions, "AOD", "STRACOLLISION", //! basic collision pr
 DECLARE_SOA_TABLE(StraCents, "AOD", "STRACENTS", //! centrality percentiles
                   cent::CentFT0M, cent::CentFT0A,
                   cent::CentFT0C, cent::CentFV0A);
+// !!! DEPRECATED TABLE: StraRawCents_000 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001
 DECLARE_SOA_TABLE(StraRawCents_000, "AOD", "STRARAWCENTS", //! debug information
                   mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, mult::MultNTracksPVeta1);
+// !!! DEPRECATED TABLE: StraRawCents_001 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001
 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_001, "AOD", "STRARAWCENTS", 1,     //! debug information
                             mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors
                             mult::MultNTracksPVeta1,                        // track multiplicities
                             mult::MultZNA, mult::MultZNC, mult::MultZEM1,   // ZDC signals
                             mult::MultZEM2, mult::MultZPA, mult::MultZPC);
+// !!! DEPRECATED TABLE: StraRawCents_002 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001
 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_002, "AOD", "STRARAWCENTS", 2,            //! debug information
                             mult::MultFT0A, mult::MultFT0C, mult::MultFV0A,        // FIT detectors
                             mult::MultNTracksPVeta1,                               // track multiplicities with eta cut for INEL>0
@@ -49,6 +73,7 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_002, "AOD", "STRARAWCENTS", 2,
                             mult::MultAllTracksTPCOnly, mult::MultAllTracksITSTPC, // track multiplicities, all, no eta cut
                             mult::MultZNA, mult::MultZNC, mult::MultZEM1,          // ZDC signals
                             mult::MultZEM2, mult::MultZPA, mult::MultZPC);
+// !!! DEPRECATED TABLE: StraRawCents_003 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001
 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_003, "AOD", "STRARAWCENTS", 3,     //! debug information
                             mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors
                             mult::MultNTracksPVeta1,                        // track multiplicities with eta cut for INEL>0
@@ -59,6 +84,7 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_003, "AOD", "STRARAWCENTS", 3,     //!
                             mult::MultAllTracksITSTPC,                      // ITSTPC track multiplicities, all, no eta cut
                             mult::MultZNA, mult::MultZNC, mult::MultZEM1,   // ZDC signals
                             mult::MultZEM2, mult::MultZPA, mult::MultZPC);
+// !!! DEPRECATED TABLE: StraRawCents_004 !!! All info in StraEvSels_001, in order to group all event characteristics in a unique table. Please use StraEvSels_001
 DECLARE_SOA_TABLE_VERSIONED(StraRawCents_004, "AOD", "STRARAWCENTS", 4,     //! debug information
                             mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors
                             mult::MultNTracksPVeta1,                        // track multiplicities with eta cut for INEL>0
@@ -70,8 +96,40 @@ DECLARE_SOA_TABLE_VERSIONED(StraRawCents_004, "AOD", "STRARAWCENTS", 4,     //!
                             mult::MultZNA, mult::MultZNC, mult::MultZEM1,   // ZDC signals
                             mult::MultZEM2, mult::MultZPA, mult::MultZPC,
                             evsel::NumTracksInTimeRange); // add occupancy as extra
-DECLARE_SOA_TABLE(StraEvSels, "AOD", "STRAEVSELS", //! event selection: sel8
+DECLARE_SOA_TABLE(StraEvSels_000, "AOD", "STRAEVSELS",    //! event selection: sel8
                   evsel::Sel8, evsel::Selection);
+DECLARE_SOA_TABLE_VERSIONED(StraEvSels_001, "AOD", "STRAEVSELS", 1,         //! debug information
+                            evsel::Sel8, evsel::Selection,                  //! event selection: sel8
+                            mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, // FIT detectors
+                            mult::MultFDDA, mult::MultFDDC,
+                            mult::MultNTracksPVeta1,                      // track multiplicities with eta cut for INEL>0
+                            mult::MultPVTotalContributors,                // number of PV contribs total
+                            mult::MultNTracksGlobal,                      // global track multiplicities
+                            mult::MultNTracksITSTPC,                      // track multiplicities, PV contribs, no eta cut
+                            mult::MultAllTracksTPCOnly,                   // TPConly track multiplicities, all, no eta cut
+                            mult::MultAllTracksITSTPC,                    // ITSTPC track multiplicities, all, no eta cut
+                            mult::MultZNA, mult::MultZNC, mult::MultZEM1, // ZDC signals
+                            mult::MultZEM2, mult::MultZPA, mult::MultZPC,
+                            evsel::NumTracksInTimeRange,     // add occupancy as extra
+                            udcollision::GapSide,            // UPC info: 0 for side A, 1 for side C, 2 for both sides, 3 neither A or C, 4 not enough or too many pv contributors
+                            udcollision::TotalFT0AmplitudeA, // UPC info: re-assigned FT0-A amplitude, in case of SG event, from the most active bc
+                            udcollision::TotalFT0AmplitudeC, // UPC info: re-assigned FT0-C amplitude, in case of SG event, from the most active bc
+                            udcollision::TotalFV0AmplitudeA, // UPC info: re-assigned FV0-A amplitude, in case of SG event, from the most active bc
+                            udcollision::TotalFDDAmplitudeA, // UPC info: re-assigned FDD-A amplitude, in case of SG event, from the most active bc
+                            udcollision::TotalFDDAmplitudeC, // UPC info: re-assigned FDD-C amplitude, in case of SG event, from the most active bc
+                            udzdc::EnergyCommonZNA,          // UPC info: re-assigned ZN-A amplitude, in case of SG event, from the most active bc
+                            udzdc::EnergyCommonZNC,          // UPC info: re-assigned ZN-C amplitude, in case of SG event, from the most active bc
+
+                            // Dynamic columns for manipulating information
+                            // stracollision::TotalFV0AmplitudeA<mult::MultFV0A>,
+                            // stracollision::TotalFT0AmplitudeA<mult::MultFT0A>,
+                            // stracollision::TotalFT0AmplitudeC<mult::MultFT0C>,
+                            // stracollision::TotalFDDAmplitudeA<mult::MultFDDA>,
+                            // stracollision::TotalFDDAmplitudeC<mult::MultFDDC>,
+                            // stracollision::EnergyCommonZNA<mult::MultZNA>,
+                            // stracollision::EnergyCommonZNC<mult::MultZNC>,
+                            stracollision::IsUPC<udcollision::GapSide>);
+
 DECLARE_SOA_TABLE(StraFT0AQVs, "AOD", "STRAFT0AQVS", //! t0a Qvec
                   qvec::QvecFT0ARe, qvec::QvecFT0AIm, qvec::SumAmplFT0A);
 DECLARE_SOA_TABLE(StraFT0CQVs, "AOD", "STRAFT0CQVS", //! t0c Qvec
@@ -89,6 +147,7 @@ DECLARE_SOA_TABLE(StraStamps, "AOD", "STRASTAMPS", //! information for ID-ing ma
                   bc::RunNumber, timestamp::Timestamp);
 
 using StraRawCents = StraRawCents_004;
+using StraEvSels = StraEvSels_001;
 using StraCollision = StraCollisions::iterator;
 using StraCent = StraCents::iterator;
 
diff --git a/PWGLF/DataModel/SPCalibrationTables.h b/PWGLF/DataModel/SPCalibrationTables.h
new file mode 100644
index 00000000000..82d622e2c8c
--- /dev/null
+++ b/PWGLF/DataModel/SPCalibrationTables.h
@@ -0,0 +1,71 @@
+// 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 SPCalibrationTables.h
+///
+/// author: prottay das 07/09/2024
+/// email: prottay.das@cern.ch
+
+#ifndef PWGLF_DATAMODEL_SPCALIBRATIONTABLES_H_
+#define PWGLF_DATAMODEL_SPCALIBRATIONTABLES_H_
+
+#include <cmath>
+
+#include "Common/DataModel/PIDResponse.h"
+#include "Common/Core/RecoDecay.h"
+#include "Common/DataModel/TrackSelectionTables.h"
+#include "Framework/AnalysisDataModel.h"
+
+namespace o2::aod
+{
+namespace spcalibrationtable
+{
+DECLARE_SOA_COLUMN(TriggerEvent, triggerevent, bool);
+DECLARE_SOA_COLUMN(TriggerEventRunNo, triggereventrunno, int);
+DECLARE_SOA_COLUMN(Cent, cent, float);
+DECLARE_SOA_COLUMN(Vz, vz, float);
+DECLARE_SOA_COLUMN(ZNAEN1, znaen1, float);
+DECLARE_SOA_COLUMN(ZNAEN2, znaen2, float);
+DECLARE_SOA_COLUMN(ZNAEN3, znaen3, float);
+DECLARE_SOA_COLUMN(ZNAEN4, znaen4, float);
+DECLARE_SOA_COLUMN(ZNCEN1, zncen1, float);
+DECLARE_SOA_COLUMN(ZNCEN2, zncen2, float);
+DECLARE_SOA_COLUMN(ZNCEN3, zncen3, float);
+DECLARE_SOA_COLUMN(ZNCEN4, zncen4, float);
+DECLARE_SOA_COLUMN(QXZDCA, qxZDCA, float);
+DECLARE_SOA_COLUMN(QXZDCC, qxZDCC, float);
+DECLARE_SOA_COLUMN(QYZDCA, qyZDCA, float);
+DECLARE_SOA_COLUMN(QYZDCC, qyZDCC, float);
+DECLARE_SOA_COLUMN(PsiZDCC, psiZDCC, float);
+DECLARE_SOA_COLUMN(PsiZDCA, psiZDCA, float);
+} // namespace spcalibrationtable
+DECLARE_SOA_TABLE(SPCalibrationTables, "AOD", "SPCALCOLS",
+                  spcalibrationtable::TriggerEvent,
+                  spcalibrationtable::TriggerEventRunNo,
+                  spcalibrationtable::Cent,
+                  spcalibrationtable::Vz,
+                  spcalibrationtable::ZNAEN1,
+                  spcalibrationtable::ZNAEN2,
+                  spcalibrationtable::ZNAEN3,
+                  spcalibrationtable::ZNAEN4,
+                  spcalibrationtable::ZNCEN1,
+                  spcalibrationtable::ZNCEN2,
+                  spcalibrationtable::ZNCEN3,
+                  spcalibrationtable::ZNCEN4,
+                  spcalibrationtable::QXZDCA,
+                  spcalibrationtable::QXZDCC,
+                  spcalibrationtable::QYZDCA,
+                  spcalibrationtable::QYZDCC,
+                  spcalibrationtable::PsiZDCC,
+                  spcalibrationtable::PsiZDCA);
+using SPCalibrationTable = SPCalibrationTables::iterator;
+} // namespace o2::aod
+#endif // PWGLF_DATAMODEL_SPCALIBRATIONTABLES_H_
diff --git a/PWGLF/DataModel/Vtx3BodyTables.h b/PWGLF/DataModel/Vtx3BodyTables.h
index 0e74ec86372..f1b88dfb455 100644
--- a/PWGLF/DataModel/Vtx3BodyTables.h
+++ b/PWGLF/DataModel/Vtx3BodyTables.h
@@ -43,6 +43,9 @@ DECLARE_SOA_COLUMN(Z, z, float);               //! decay position Z
 
 // Saved from finding: DCAs
 DECLARE_SOA_COLUMN(DCAVtxDaughters, dcaVtxdaughters, float); //! DCA among daughters
+DECLARE_SOA_COLUMN(DCAXYTrack0ToPV, dcaXYtrack0topv, float); //! DCAXY of prong0 to PV
+DECLARE_SOA_COLUMN(DCAXYTrack1ToPV, dcaXYtrack1topv, float); //! DCAXY of prong1 to PV
+DECLARE_SOA_COLUMN(DCAXYTrack2ToPV, dcaXYtrack2topv, float); //! DCAXY of prong2 to PV
 DECLARE_SOA_COLUMN(DCATrack0ToPV, dcatrack0topv, float);     //! DCA of prong0 to PV
 DECLARE_SOA_COLUMN(DCATrack1ToPV, dcatrack1topv, float);     //! DCA of prong1 to PV
 DECLARE_SOA_COLUMN(DCATrack2ToPV, dcatrack2topv, float);     //! DCA of prong2 to PV
@@ -132,6 +135,7 @@ DECLARE_SOA_TABLE_FULL(StoredVtx3BodyDatas, "Vtx3BodyDatas", "AOD", "Vtx3BodyDAT
                        vtx3body::PxTrack1, vtx3body::PyTrack1, vtx3body::PzTrack1,
                        vtx3body::PxTrack2, vtx3body::PyTrack2, vtx3body::PzTrack2,
                        vtx3body::DCAVtxDaughters,
+                       vtx3body::DCAXYTrack0ToPV, vtx3body::DCAXYTrack1ToPV, vtx3body::DCAXYTrack2ToPV,
                        vtx3body::DCATrack0ToPV, vtx3body::DCATrack1ToPV, vtx3body::DCATrack2ToPV,
                        vtx3body::TOFNSigmaBachDe,
 
@@ -246,15 +250,19 @@ DECLARE_SOA_COLUMN(TPCNSigmaPion, tpcNSigmaPion, float);         //! nsigma of T
 DECLARE_SOA_COLUMN(TPCNSigmaBachelor, tpcNSigmaBachelor, float); //! nsigma of TPC PID of the bachelor daughter
 DECLARE_SOA_COLUMN(TOFNSigmaBachelor, tofNSigmaBachelor, float); //! nsigma of TOF PID of the bachelor daughter
 // DCA to PV
-DECLARE_SOA_COLUMN(DCAProtonToPV, dcaProtontoPV, float);     //! DCA of the proton daughter to pv
-DECLARE_SOA_COLUMN(DCAPionToPV, dcaPiontoPV, float);         //! DCA of the pion daughter to pv
-DECLARE_SOA_COLUMN(DCABachelorToPV, dcaBachelortoPV, float); //! DCA of the bachelor daughter to pv
+DECLARE_SOA_COLUMN(DCAXYProtonToPV, dcaxyProtontoPV, float);     //! DCAXY of the proton daughter to pv
+DECLARE_SOA_COLUMN(DCAXYPionToPV, dcaxyPiontoPV, float);         //! DCAXY of the pion daughter to pv
+DECLARE_SOA_COLUMN(DCAXYBachelorToPV, dcaxyBachelortoPV, float); //! DCAXY of the bachelor daughter to pv
+DECLARE_SOA_COLUMN(DCAProtonToPV, dcaProtontoPV, float);         //! DCA of the proton daughter to pv
+DECLARE_SOA_COLUMN(DCAPionToPV, dcaPiontoPV, float);             //! DCA of the pion daughter to pv
+DECLARE_SOA_COLUMN(DCABachelorToPV, dcaBachelortoPV, float);     //! DCA of the bachelor daughter to pv
 // for MC
 DECLARE_SOA_COLUMN(GenP, genP, float);                                    // P of the hypertriton
 DECLARE_SOA_COLUMN(GenPt, genPt, float);                                  // pT of the hypertriton
 DECLARE_SOA_COLUMN(GenCt, genCt, float);                                  // ct of the hypertriton
 DECLARE_SOA_COLUMN(GenPhi, genPhi, float);                                // Phi of the hypertriton
 DECLARE_SOA_COLUMN(GenEta, genEta, float);                                // Eta of the hypertriton
+DECLARE_SOA_COLUMN(GenRapidity, genRapidity, float);                      // Rapidity of the hypertriton
 DECLARE_SOA_COLUMN(IsReco, isReco, bool);                                 // bool: true for reco
 DECLARE_SOA_COLUMN(IsSignal, isSignal, bool);                             // bool: true for signal
 DECLARE_SOA_COLUMN(PdgCode, pdgCode, int);                                // pdgCode of the mcparticle, -1 for fake pair
@@ -284,6 +292,7 @@ DECLARE_SOA_TABLE(Hyp3BodyCands, "AOD", "HYP3BODYCANDS",
                   hyp3body::ITSNclusSizeProton, hyp3body::ITSNclusSizePion, hyp3body::ITSNclusSizeBachelor,
                   hyp3body::TPCNSigmaProton, hyp3body::TPCNSigmaPion, hyp3body::TPCNSigmaBachelor,
                   hyp3body::TOFNSigmaBachelor,
+                  hyp3body::DCAXYProtonToPV, hyp3body::DCAXYPionToPV, hyp3body::DCAXYBachelorToPV,
                   hyp3body::DCAProtonToPV, hyp3body::DCAPionToPV, hyp3body::DCABachelorToPV);
 
 // output table for MC
@@ -309,6 +318,7 @@ DECLARE_SOA_TABLE(MCHyp3BodyCands, "AOD", "MCHYP3BODYCANDS",
                   hyp3body::ITSNclusSizeProton, hyp3body::ITSNclusSizePion, hyp3body::ITSNclusSizeBachelor,
                   hyp3body::TPCNSigmaProton, hyp3body::TPCNSigmaPion, hyp3body::TPCNSigmaBachelor,
                   hyp3body::TOFNSigmaBachelor,
+                  hyp3body::DCAXYProtonToPV, hyp3body::DCAXYPionToPV, hyp3body::DCAXYBachelorToPV,
                   hyp3body::DCAProtonToPV, hyp3body::DCAPionToPV, hyp3body::DCABachelorToPV,
                   // MC information
                   hyp3body::GenP,
@@ -316,6 +326,7 @@ DECLARE_SOA_TABLE(MCHyp3BodyCands, "AOD", "MCHYP3BODYCANDS",
                   hyp3body::GenCt,
                   hyp3body::GenPhi,
                   hyp3body::GenEta,
+                  hyp3body::GenRapidity,
                   hyp3body::IsSignal,
                   hyp3body::IsReco,
                   hyp3body::PdgCode,
diff --git a/PWGLF/DataModel/pidTOFGeneric.h b/PWGLF/DataModel/pidTOFGeneric.h
index f1db0aef03a..047ec6aa477 100644
--- a/PWGLF/DataModel/pidTOFGeneric.h
+++ b/PWGLF/DataModel/pidTOFGeneric.h
@@ -9,8 +9,8 @@
 // granted to it by virtue of its status as an Intergovernmental Organization
 // or submit itself to any jurisdiction.
 
-#ifndef PIDTOFGENERIC_H_
-#define PIDTOFGENERIC_H_
+#ifndef PWGLF_DATAMODEL_PIDTOFGENERIC_H_
+#define PWGLF_DATAMODEL_PIDTOFGENERIC_H_
 #include "CommonDataFormat/InteractionRecord.h"
 #include "Common/Core/PID/PIDTOF.h"
 
@@ -155,4 +155,4 @@ class TofPidNewCollision
 } // namespace pidtofgeneric
 } // namespace o2::aod
 
-#endif
+#endif // PWGLF_DATAMODEL_PIDTOFGENERIC_H_
diff --git a/PWGLF/TableProducer/Common/CMakeLists.txt b/PWGLF/TableProducer/Common/CMakeLists.txt
index a3c26273a81..e68b511978d 100644
--- a/PWGLF/TableProducer/Common/CMakeLists.txt
+++ b/PWGLF/TableProducer/Common/CMakeLists.txt
@@ -15,6 +15,11 @@ o2physics_add_dpl_workflow(epvector
     PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsVertexing
     COMPONENT_NAME Analysis)
 
+o2physics_add_dpl_workflow(spvector
+    SOURCES spvector.cxx
+    PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsVertexing
+    COMPONENT_NAME Analysis)
+
 o2physics_add_dpl_workflow(tpcpid
     SOURCES lfTPCPID.cxx
     PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
@@ -28,4 +33,4 @@ o2physics_add_dpl_workflow(zdcsp
 o2physics_add_dpl_workflow(mc-centrality
     SOURCES mcCentrality.cxx
     PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
-    COMPONENT_NAME Analysis)
\ No newline at end of file
+    COMPONENT_NAME Analysis)
diff --git a/PWGLF/TableProducer/Common/spvector.cxx b/PWGLF/TableProducer/Common/spvector.cxx
new file mode 100644
index 00000000000..bf9074e38e1
--- /dev/null
+++ b/PWGLF/TableProducer/Common/spvector.cxx
@@ -0,0 +1,345 @@
+// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
+// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
+// All rights not expressly granted are reserved.
+//
+// This software is distributed under the terms of the GNU General Public
+// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
+//
+// In applying this license CERN does not waive the privileges and immunities
+// granted to it by virtue of its status as an Intergovernmental Organization
+// or submit itself to any jurisdiction.
+//
+// \author: prottay das 07/09/2024
+// \email: prottay.das@cern.ch
+
+// C++/ROOT includes.
+#include <TH1F.h>
+#include <chrono>
+#include <string>
+#include <vector>
+#include <TComplex.h>
+#include <TMath.h>
+#include <array>
+#include <cmath>
+#include "Math/Vector4D.h"
+#include "TRandom3.h"
+#include "TF1.h"
+
+// o2Physics includes.
+#include "Framework/AnalysisDataModel.h"
+#include "Framework/AnalysisTask.h"
+#include "Framework/runDataProcessing.h"
+#include "Framework/HistogramRegistry.h"
+#include "Framework/StepTHn.h"
+#include "Common/DataModel/Multiplicity.h"
+#include "Common/DataModel/TrackSelectionTables.h"
+#include "CommonConstants/PhysicsConstants.h"
+#include "Common/Core/TrackSelection.h"
+#include "Common/DataModel/FT0Corrected.h"
+#include "FT0Base/Geometry.h"
+#include "FV0Base/Geometry.h"
+#include "Common/Core/trackUtilities.h"
+#include "Common/DataModel/Centrality.h"
+#include "Common/DataModel/EventSelection.h"
+#include "Common/DataModel/PIDResponse.h"
+#include "Common/Core/PID/PIDTOF.h"
+#include "Common/TableProducer/PID/pidTOFBase.h"
+#include "Common/Core/EventPlaneHelper.h"
+#include "Common/DataModel/Qvectors.h"
+#include "Common/CCDB/ctpRateFetcher.h"
+#include "DataFormatsParameters/GRPMagField.h"
+#include "DataFormatsParameters/GRPObject.h"
+#include "DataFormatsTPC/BetheBlochAleph.h"
+#include "DetectorsBase/GeometryManager.h"
+#include "DetectorsBase/Propagator.h"
+#include "Framework/ASoAHelpers.h"
+#include "ReconstructionDataFormats/Track.h"
+#include "PWGLF/DataModel/SPCalibrationTables.h"
+
+// o2 includes.
+#include "CCDB/CcdbApi.h"
+#include "CCDB/BasicCCDBManager.h"
+#include "DetectorsCommonDataFormats/AlignParam.h"
+
+using namespace o2;
+using namespace o2::framework;
+using namespace o2::framework::expressions;
+using namespace o2::constants::physics;
+
+using BCsRun3 = soa::Join<aod::BCsWithTimestamps, aod::Run3MatchedToBCSparse>;
+
+struct spvector {
+
+  Produces<aod::SPCalibrationTables> spcalibrationtable;
+
+  // Configurables.
+  struct : ConfigurableGroup {
+    Configurable<std::string> cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"};
+    Configurable<int64_t> nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"};
+  } cfgCcdbParam;
+
+  // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables.
+  Service<o2::ccdb::BasicCCDBManager> ccdb;
+  o2::ccdb::CcdbApi ccdbApi;
+  HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
+
+  Configurable<float> cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"};
+  Configurable<float> cfgCutCentrality{"cfgCutCentrality", 80.0f, "Centrality cut"};
+  Configurable<float> cfgCutPT{"cfgCutPT", 0.15, "PT cut on daughter track"};
+  Configurable<float> cfgCutPTMax{"cfgCutPTMax", 3.0, "Max PT cut on daughter track"};
+  Configurable<float> cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"};
+  Configurable<float> cfgMinEta{"cfgMinEta", 0.1, "Min Eta cut on daughter track"};
+  Configurable<float> cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"};
+  Configurable<float> cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"};
+
+  Configurable<int> QxyNbins{"QxyNbins", 100, "Number of bins in QxQy histograms"};
+  Configurable<float> lbinQxy{"lbinQxy", -5.0, "lower bin value in QxQy histograms"};
+  Configurable<float> hbinQxy{"hbinQxy", 5.0, "higher bin value in QxQy histograms"};
+  Configurable<int> ZDCgainNbins{"ZDCgainNbins", 500, "Number of bins in Gaineq histograms"};
+  Configurable<float> lbinZDCgain{"lbinZDCgain", 0.0, "lower bin value in Gaineq histograms"};
+  Configurable<float> hbinZDCgain{"hbinZDCgain", 1000.0, "higher bin value in Gaineq histograms"};
+
+  Configurable<bool> useGainCallib{"useGainCallib", false, "use gain calibration"};
+  Configurable<bool> useRecentere{"useRecentere", false, "use Recentering"};
+  Configurable<bool> useShift{"useShift", false, "use Shift"};
+  Configurable<std::string> ConfGainPath{"ConfGainPath", "Users/p/prottay/My/Object/test100", "Path to gain calibration"};
+  Configurable<std::string> ConfRecentere{"ConfRecentere", "Users/p/prottay/My/Object/NewPbPbpass4_23082024/recenter", "Path for recentere"};
+  Configurable<std::string> ConfShift{"ConfShift", "Users/p/prottay/My/Object/Finaltest2/recenereall", "Path for Shift"};
+
+  ConfigurableAxis configAxisCentrality{"configAxisCentrality", {80, 0.0, 80}, "centrality bining"};
+  // ConfigurableAxis configAxisZDCgain{"configAxisZDCgain", {ZDCgainNbins, lbinZDCgain, hbinZDCgain}, "gainamplitude bining"};
+  // ConfigurableAxis configAxisQx{"configAxisQx", {QxyNbins, lbinQxy, hbinQxy}, "qx bining"};
+  // ConfigurableAxis configAxisQy{"configAxisQy", {QxyNbins, lbinQxy, hbinQxy}, "qy bining"};
+
+  // Event selection cuts - Alex
+  TF1* fMultPVCutLow = nullptr;
+  TF1* fMultPVCutHigh = nullptr;
+  TF1* fMultCutLow = nullptr;
+  TF1* fMultCutHigh = nullptr;
+  TF1* fMultMultPVCut = nullptr;
+
+  int mRunNumber{-1};
+
+  template <typename TCollision>
+  bool eventSelected(TCollision collision, const float& centrality)
+  {
+    auto multNTracksPV = collision.multNTracksPV();
+    if (multNTracksPV < fMultPVCutLow->Eval(centrality))
+      return 0;
+    if (multNTracksPV > fMultPVCutHigh->Eval(centrality))
+      return 0;
+
+    return 1;
+  }
+
+  void initCCDB(BCsRun3::iterator const& bc)
+  {
+    if (mRunNumber == bc.runNumber()) {
+      return;
+    }
+    mRunNumber = bc.runNumber();
+  }
+
+  void init(o2::framework::InitContext&)
+  {
+
+    std::vector<double> occupancyBinning = {0.0, 500.0, 1000.0, 1500.0, 2000.0, 3000.0, 4000.0, 5000.0, 50000.0};
+
+    const AxisSpec centAxis{configAxisCentrality, "V0M (%)"};
+
+    // AxisSpec amplitudeZDC = {configAxisZDCgain, "ZDC amplitude"};
+    AxisSpec amplitudeZDC = {ZDCgainNbins, lbinZDCgain, hbinZDCgain, "ZDC amplitude"};
+    AxisSpec channelZDCAxis = {8, 0.0, 8.0, "ZDC tower"};
+    AxisSpec qxZDCAxis = {QxyNbins, lbinQxy, hbinQxy, "Qx"};
+    AxisSpec qyZDCAxis = {QxyNbins, lbinQxy, hbinQxy, "Qy"};
+    AxisSpec phiAxis = {50, -6.28, 6.28, "phi"};
+    AxisSpec vzAxis = {20, -10, 10, "vz"};
+
+    histos.add("hCentrality", "hCentrality", kTH1F, {{8, 0, 80.0}});
+    histos.add("Vz", "Vz", kTH1F, {vzAxis});
+
+    histos.add("hpQxZDCAC", "hpQxZDCAC", kTProfile, {centAxis});
+    histos.add("hpQyZDCAC", "hpQyZDCAC", kTProfile, {centAxis});
+    histos.add("hpQxZDCAQyZDCC", "hpQxZDCAQyZDCC", kTProfile, {centAxis});
+    histos.add("hpQxZDCCQyZDCA", "hpQxZDCCQyZDCA", kTProfile, {centAxis});
+    histos.add("QxZDCC", "QxZDCC", kTH2F, {centAxis, qxZDCAxis});
+    histos.add("QyZDCC", "QyZDCC", kTH2F, {centAxis, qyZDCAxis});
+    histos.add("QxZDCA", "QxZDCA", kTH2F, {centAxis, qxZDCAxis});
+    histos.add("QyZDCA", "QyZDCA", kTH2F, {centAxis, qyZDCAxis});
+    histos.add("PsiZDCC", "PsiZDCC", kTH2F, {centAxis, phiAxis});
+    histos.add("PsiZDCA", "PsiZDCA", kTH2F, {centAxis, phiAxis});
+    histos.add("ZDCAmp", "ZDCAmp", kTProfile2D, {channelZDCAxis, vzAxis});
+    histos.add("hZDCAmp", "hZDCAmp", kTH3F, {channelZDCAxis, vzAxis, amplitudeZDC});
+
+    // Event selection cut additional - Alex
+    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);
+
+    ccdb->setURL(cfgCcdbParam.cfgURL);
+    ccdbApi.init("http://alice-ccdb.cern.ch");
+    ccdb->setCaching(true);
+    ccdb->setLocalObjectValidityChecking();
+    ccdb->setCreatedNotAfter(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
+  }
+
+  int currentRunNumber = -999;
+  int lastRunNumber = -999;
+  TH2D* gainprofile;
+  TH2D* hrecentere;
+
+  // 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 MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::FT0sCorrected, aod::CentFT0Cs>;
+  // using MyTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection, aod::TrackSelectionExtension>>;
+
+  Preslice<aod::Zdcs> zdcPerCollision = aod::collision::bcId;
+
+  // void process(MyCollisions::iterator const& collision, aod::FT0s const& /*ft0s*/, BCsRun3 const& bcs, aod::Zdcs const&, MyTracks const&)
+  void process(MyCollisions::iterator const& collision, aod::FT0s const& /*ft0s*/, BCsRun3 const& bcs, aod::Zdcs const&)
+  {
+
+    auto centrality = collision.centFT0C();
+
+    if (bcs.size() != 0) {
+      gRandom->SetSeed(bcs.iteratorAt(0).globalBC());
+    }
+
+    auto bc = collision.foundBC_as<BCsRun3>();
+    if (!bc.has_zdc()) {
+      return;
+    }
+
+    currentRunNumber = collision.foundBC_as<BCsRun3>().runNumber();
+    auto vz = collision.posZ();
+    bool triggerevent = false;
+
+    float psiZDCC = -99;
+    float psiZDCA = -99;
+    auto qxZDCA = 0.0;
+    auto qxZDCC = 0.0;
+    auto qyZDCA = 0.0;
+    auto qyZDCC = 0.0;
+    auto sumA = 0.0;
+    auto sumC = 0.0;
+
+    auto zdc = bc.zdc();
+    auto zncEnergy = zdc.energySectorZNC();
+    auto znaEnergy = zdc.energySectorZNA();
+
+    if (znaEnergy[0] < 0.0 || znaEnergy[1] < 0.0 || znaEnergy[2] < 0.0 || znaEnergy[3] < 0.0)
+      return;
+    if (zncEnergy[0] < 0.0 || zncEnergy[1] < 0.0 || zncEnergy[2] < 0.0 || zncEnergy[3] < 0.0)
+      return;
+
+    if (collision.sel8() && centrality < cfgCutCentrality && TMath::Abs(vz) < cfgCutVertex && collision.has_foundFT0() && eventSelected(collision, centrality) && collision.selection_bit(aod::evsel::kNoTimeFrameBorder) && collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) {
+      triggerevent = true;
+      if (useGainCallib && (currentRunNumber != lastRunNumber)) {
+        gainprofile = ccdb->getForTimeStamp<TH2D>(ConfGainPath.value, bc.timestamp());
+      }
+
+      histos.fill(HIST("hCentrality"), centrality);
+      histos.fill(HIST("Vz"), vz);
+
+      initCCDB(bc);
+
+      auto gainequal = 1.0;
+      constexpr float x[4] = {-1.75, 1.75, -1.75, 1.75};
+      constexpr float y[4] = {-1.75, -1.75, 1.75, 1.75};
+
+      for (std::size_t iChA = 0; iChA < 8; iChA++) {
+        auto chanelid = iChA;
+        if (useGainCallib) {
+          gainequal = gainprofile->GetBinContent(gainprofile->FindBin(chanelid));
+        }
+
+        if (iChA < 4) {
+
+          if (znaEnergy[iChA] <= 0.0) {
+            return;
+          } else {
+            float ampl = gainequal * znaEnergy[iChA];
+            qxZDCA = qxZDCA + ampl * x[iChA];
+            qyZDCA = qyZDCA + ampl * y[iChA];
+            sumA = sumA + ampl;
+            histos.fill(HIST("ZDCAmp"), chanelid + 0.5, vz, ampl);
+            histos.fill(HIST("hZDCAmp"), chanelid + 0.5, vz, ampl);
+          }
+        } else {
+
+          if (zncEnergy[iChA - 4] <= 0.0) {
+            return;
+          } else {
+            float ampl = gainequal * zncEnergy[iChA - 4];
+            qxZDCC = qxZDCC + ampl * x[iChA - 4];
+            qyZDCC = qyZDCC + ampl * y[iChA - 4];
+            sumC = sumC + ampl;
+            histos.fill(HIST("ZDCAmp"), chanelid + 0.5, vz, ampl);
+            histos.fill(HIST("hZDCAmp"), chanelid + 0.5, vz, ampl);
+          }
+        }
+      }
+
+      if (sumA > 0) {
+        qxZDCA = qxZDCA / sumA;
+        qyZDCA = qyZDCA / sumA;
+      }
+      if (sumC > 0) {
+        qxZDCC = qxZDCC / sumC;
+        qyZDCC = qyZDCC / sumC;
+      }
+
+      if (sumA <= 1e-4 || sumC <= 1e-4) {
+        qxZDCA = 0.0;
+        qxZDCC = 0.0;
+        qyZDCA = 0.0;
+        qyZDCC = 0.0;
+        return;
+      }
+
+      if (useRecentere && (currentRunNumber != lastRunNumber)) {
+        hrecentere = ccdb->getForTimeStamp<TH2D>(ConfRecentere.value, bc.timestamp());
+      }
+
+      if (useRecentere) {
+
+        qxZDCA = (qxZDCA - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 0.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 0.5));
+        qyZDCA = (qyZDCA - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 1.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 1.5));
+        qxZDCC = (qxZDCC - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 2.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 2.5));
+        qyZDCC = (qyZDCC - hrecentere->GetBinContent(hrecentere->FindBin(centrality, 3.5))) / hrecentere->GetBinError(hrecentere->FindBin(centrality, 3.5));
+      }
+
+      psiZDCC = 1.0 * TMath::ATan2(qyZDCC, qxZDCC);
+      psiZDCA = 1.0 * TMath::ATan2(qyZDCA, qxZDCA);
+
+      histos.fill(HIST("hpQxZDCAC"), centrality, (qxZDCA * qxZDCC));
+      histos.fill(HIST("hpQyZDCAC"), centrality, (qyZDCA * qyZDCC));
+      histos.fill(HIST("hpQxZDCAQyZDCC"), centrality, (qxZDCA * qyZDCC));
+      histos.fill(HIST("hpQxZDCCQyZDCA"), centrality, (qxZDCC * qyZDCA));
+      histos.fill(HIST("QxZDCC"), centrality, qxZDCC);
+      histos.fill(HIST("QyZDCC"), centrality, qyZDCC);
+      histos.fill(HIST("QxZDCA"), centrality, qxZDCA);
+      histos.fill(HIST("QyZDCA"), centrality, qyZDCA);
+      histos.fill(HIST("PsiZDCA"), centrality, psiZDCA);
+      histos.fill(HIST("PsiZDCC"), centrality, psiZDCC);
+
+      lastRunNumber = currentRunNumber;
+    }
+
+    spcalibrationtable(triggerevent, lastRunNumber, centrality, vz, znaEnergy[0], znaEnergy[1], znaEnergy[2], znaEnergy[3], zncEnergy[0], zncEnergy[1], zncEnergy[2], zncEnergy[3], qxZDCA, qyZDCA, qxZDCC, qyZDCC, psiZDCC, psiZDCA);
+  }
+};
+
+WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
+{
+  return WorkflowSpec{
+    adaptAnalysisTask<spvector>(cfgc)};
+}
diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx
index dc313063a19..aef355695a9 100644
--- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx
+++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx
@@ -454,14 +454,17 @@ struct decay3bodyBuilder {
       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 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);
@@ -517,6 +520,7 @@ struct decay3bodyBuilder {
         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,
         tofNsigmaDe);
     }
   }
diff --git a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx
index 2c70f10f348..88cd22d1692 100644
--- a/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx
+++ b/PWGLF/TableProducer/Nuspex/ebyeMaker.cxx
@@ -303,7 +303,7 @@ struct ebyeMaker {
         track.tpcNClsShared() > v0trackNsharedClusTpc) {
       return false;
     }
-    if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2) {
+    if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2 || doprocessMiniMcRun2) {
       if (!(track.trackType() & o2::aod::track::Run2Track) ||
           !(track.flags() & o2::aod::track::TPCrefit)) {
         return false;
@@ -332,7 +332,7 @@ struct ebyeMaker {
         track.itsChi2NCl() > 36.f) {
       return false;
     }
-    if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2) {
+    if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2 || doprocessMiniMcRun2) {
       if (!(track.trackType() & o2::aod::track::Run2Track) ||
           !(track.flags() & o2::aod::track::TPCrefit) ||
           !(track.flags() & o2::aod::track::ITSrefit)) {
@@ -362,7 +362,7 @@ struct ebyeMaker {
     auto timestamp = bc.timestamp();
     o2::parameters::GRPObject* grpo = 0x0;
     o2::parameters::GRPMagField* grpmag = 0x0;
-    if (doprocessRun2 || doprocessMcRun2 || doprocessMiniRun2) {
+    if (doprocessRun2 || doprocessMcRun2 || doprocessMiniRun2 || doprocessMiniMcRun2) {
       auto grpPath{"GLO/GRP/GRP"};
       grpo = ccdb->getForTimeStamp<o2::parameters::GRPObject>("GLO/GRP/GRP", timestamp);
       if (!grpo) {
@@ -397,7 +397,7 @@ struct ebyeMaker {
   template <class T>
   float getOuterPID(T const& track)
   {
-    if (doprocessMiniRun2) {
+    if (doprocessMiniRun2 || doprocessMiniMcRun2) {
       if (track.hasTOF() && track.pt() > antipPtTof)
         return track.tofNSigmaPr();
       // else if (track.pt() < antipPtTof && track.pt() > antipPtMin) {
@@ -625,7 +625,7 @@ struct ebyeMaker {
         if (!posSelect || !negSelect)
           continue;
 
-        if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2) {
+        if (doprocessRun2 || doprocessMiniRun2 || doprocessMcRun2 || doprocessMiniMcRun2) {
           bool checkPosPileUp = posTrack.hasTOF() || (posTrack.flags() & o2::aod::track::ITSrefit);
           bool checkNegPileUp = negTrack.hasTOF() || (negTrack.flags() & o2::aod::track::ITSrefit);
           if (!checkPosPileUp && !checkNegPileUp) {
diff --git a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx
index 52f038356dc..b4445a5619a 100644
--- a/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx
+++ b/PWGLF/TableProducer/Nuspex/hypertriton3bodyfinder.cxx
@@ -687,14 +687,17 @@ struct hypertriton3bodyFinder {
     auto Track0Par = getTrackPar(dPtrack);
     o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo);
     auto Track0dcaXY = dcaInfo[0];
+    auto Track0dca = std::sqrt(Track0dcaXY * Track0dcaXY + dcaInfo[1] * dcaInfo[1]);
 
     auto Track1Par = getTrackPar(dNtrack);
     o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo);
     auto Track1dcaXY = dcaInfo[0];
+    auto Track1dca = std::sqrt(Track1dcaXY * Track1dcaXY + dcaInfo[1] * dcaInfo[1]);
 
     auto Track2Par = getTrackPar(dBachtrack);
     o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo);
     auto Track2dcaXY = dcaInfo[0];
+    auto Track2dca = std::sqrt(Track2dcaXY * Track2dcaXY + dcaInfo[1] * dcaInfo[1]);
 
     // H3L DCA Check
     // auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(), t2.sign());
@@ -712,6 +715,7 @@ struct hypertriton3bodyFinder {
       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,
       0); // To be fixed
   }
   //------------------------------------------------------------------
diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx
index 1e8fdfd22cd..09b2e909ec1 100644
--- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx
+++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx
@@ -91,6 +91,7 @@ struct NucleusCandidate {
   uint8_t TPCcrossedRows;
   uint8_t ITSclsMap;
   uint8_t TPCnCls;
+  uint8_t TPCnClsShared;
   uint8_t ITSnCls;
   uint32_t clusterSizesITS;
 };
@@ -689,7 +690,7 @@ struct nucleiSpectra {
           static_cast<int>(track.globalIndex()), static_cast<int>(track.collisionId()), (1 - 2 * iC) * mTrackParCov.getPt(), mTrackParCov.getEta(), mTrackParCov.getPhi(),
           correctedTpcInnerParam, beta, collision.posZ(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), track.tpcChi2NCl(),
           nSigmaTPC, tofMasses, fillTree, fillDCAHist, correctPV, isSecondary, fromWeakDecay, flag, track.tpcNClsFindable(), static_cast<uint8_t>(track.tpcNClsCrossedRows()), track.itsClusterMap(),
-          static_cast<uint8_t>(track.tpcNClsFound()), static_cast<uint8_t>(track.itsNCls()), static_cast<uint32_t>(track.itsClusterSizes())});
+          static_cast<uint8_t>(track.tpcNClsFound()), static_cast<uint8_t>(track.tpcNClsShared()), static_cast<uint8_t>(track.itsNCls()), static_cast<uint32_t>(track.itsClusterSizes())});
       }
     } // end loop over tracks
 
@@ -710,7 +711,7 @@ struct nucleiSpectra {
     fillDataInfo(collision, tracks);
     for (auto& c : nuclei::candidates) {
       if (c.fillTree) {
-        nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS);
+        nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS);
       }
       if (c.fillDCAHist) {
         for (int iS{0}; iS < nuclei::species; ++iS) {
@@ -736,7 +737,7 @@ struct nucleiSpectra {
     fillDataInfo(collision, tracks);
     for (auto& c : nuclei::candidates) {
       if (c.fillTree) {
-        nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS);
+        nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS);
       }
       if (c.fillDCAHist) {
         for (int iS{0}; iS < nuclei::species; ++iS) {
@@ -765,7 +766,7 @@ struct nucleiSpectra {
     fillDataInfo(collision, tracks);
     for (auto& c : nuclei::candidates) {
       if (c.fillTree) {
-        nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS);
+        nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS);
       }
       if (c.fillDCAHist) {
         for (int iS{0}; iS < nuclei::species; ++iS) {
@@ -839,7 +840,7 @@ struct nucleiSpectra {
         c.flags |= kIsSecondaryFromMaterial;
       }
       float absoDecL = computeAbsoDecL(particle);
-      nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absoDecL);
+      nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.TPCnClsShared, c.clusterSizesITS, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absoDecL);
     }
 
     int index{0};
@@ -860,7 +861,7 @@ struct nucleiSpectra {
 
         if (!isReconstructed[index] && (cfgTreeConfig->get(iS, 0u) || cfgTreeConfig->get(iS, 1u))) {
           float absDecL = computeAbsoDecL(particle);
-          nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, flags, 0, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absDecL);
+          nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, flags, 0, 0, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode(), goodCollisions[particle.mcCollisionId()], absDecL);
         }
         break;
       }
diff --git a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx
index 337d87223ad..857a02e1cf2 100644
--- a/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx
+++ b/PWGLF/TableProducer/Nuspex/threebodyRecoTask.cxx
@@ -54,6 +54,7 @@ struct Candidate3body {
   // 0 - proton, 1 - pion, 2 - bachelor
   uint8_t dautpcNclusters[3];
   uint8_t dauitsclussize[3];
+  uint8_t daudcaxytopv[3];
   uint8_t daudcatopv[3];
   float dautpcNsigma[3];
   bool isMatter;
@@ -65,6 +66,7 @@ struct Candidate3body {
   float bachelortofNsigma;
   TLorentzVector lgencand = {0, 0, 0, 0};
   float genct = -1;
+  float genrapidity = -999;
   bool isSignal = false;
   bool isReco = false;
   int pdgCode = -1;
@@ -112,6 +114,7 @@ struct threebodyRecoTask {
     "registry",
     {
       {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}},
+      {"hCentFT0C", "hCentFT0C", {HistType::kTH1F, {{100, 0.0f, 100.0f, "FT0C Centrality"}}}},
       {"hCandidatesCounter", "hCandidatesCounter", {HistType::kTH1F, {{12, 0.0f, 12.0f}}}},
       {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}},
       {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}},
@@ -122,6 +125,9 @@ struct threebodyRecoTask {
       {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}},
       {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}},
       {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}},
+      {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
+      {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
+      {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
@@ -351,6 +357,8 @@ struct threebodyRecoTask {
       registry.fill(HIST("hPtProton"), trackProton.pt());
       registry.fill(HIST("hPtPionMinus"), trackPion.pt());
       registry.fill(HIST("hPtDeuteron"), trackDeuteron.pt());
+      registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack0topv());
+      registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack1topv());
       registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack0topv());
       registry.fill(HIST("hDCAPionToPV"), candData.dcatrack1topv());
 
@@ -379,6 +387,8 @@ struct threebodyRecoTask {
       registry.fill(HIST("hPtAntiProton"), trackProton.pt());
       registry.fill(HIST("hPtPionPlus"), trackPion.pt());
       registry.fill(HIST("hPtAntiDeuteron"), trackDeuteron.pt());
+      registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack1topv());
+      registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack0topv());
       registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack1topv());
       registry.fill(HIST("hDCAPionToPV"), candData.dcatrack0topv());
 
@@ -409,10 +419,15 @@ struct threebodyRecoTask {
     cand3body.dautpcNclusters[0] = trackProton.tpcNClsFound();
     cand3body.dautpcNclusters[1] = trackPion.tpcNClsFound();
     cand3body.dautpcNclusters[2] = trackDeuteron.tpcNClsFound();
-    cand3body.dauitsclussize[0] = trackPion.itsClusterSizes();
+    cand3body.dauitsclussize[0] = trackProton.itsClusterSizes();
+    cand3body.dauitsclussize[1] = trackPion.itsClusterSizes();
+    cand3body.dauitsclussize[2] = trackDeuteron.itsClusterSizes();
     cand3body.dautpcNsigma[0] = trackProton.tpcNSigmaPr();
     cand3body.dautpcNsigma[1] = trackPion.tpcNSigmaPi();
     cand3body.dautpcNsigma[2] = trackDeuteron.tpcNSigmaDe();
+    cand3body.daudcaxytopv[0] = cand3body.isMatter ? candData.dcaXYtrack0topv() : candData.dcaXYtrack1topv();
+    cand3body.daudcaxytopv[1] = cand3body.isMatter ? candData.dcaXYtrack1topv() : candData.dcaXYtrack0topv();
+    cand3body.daudcaxytopv[2] = candData.dcaXYtrack2topv();
     cand3body.daudcatopv[0] = cand3body.isMatter ? candData.dcatrack0topv() : candData.dcatrack1topv();
     cand3body.daudcatopv[1] = cand3body.isMatter ? candData.dcatrack1topv() : candData.dcatrack0topv();
     cand3body.daudcatopv[2] = candData.dcatrack2topv();
@@ -426,6 +441,7 @@ struct threebodyRecoTask {
       cand3body.mcmotherId = lLabel;
       cand3body.lgencand = lmother;
       cand3body.genct = MClifetime;
+      cand3body.genrapidity = lmother.Rapidity();
       cand3body.isSignal = true;
       cand3body.isReco = true;
       cand3body.pdgCode = cand3body.isMatter ? motherPdgCode : -motherPdgCode;
@@ -514,6 +530,7 @@ struct threebodyRecoTask {
       return;
     }
     registry.fill(HIST("hEventCounter"), 2.5);
+    registry.fill(HIST("hCentFT0C"), collision.centFT0C());
 
     bool if_hasvtx = false;
 
@@ -537,6 +554,7 @@ struct threebodyRecoTask {
                       cand3body.dautpcNclusters[0], cand3body.dautpcNclusters[1], cand3body.dautpcNclusters[2],
                       cand3body.dauitsclussize[0], cand3body.dauitsclussize[1], cand3body.dauitsclussize[2],
                       cand3body.dautpcNsigma[0], cand3body.dautpcNsigma[1], cand3body.dautpcNsigma[2], cand3body.bachelortofNsigma,
+                      cand3body.daudcaxytopv[0], cand3body.daudcaxytopv[1], cand3body.daudcaxytopv[2],
                       cand3body.daudcatopv[0], cand3body.daudcatopv[1], cand3body.daudcatopv[2]);
     }
   }
@@ -587,7 +605,7 @@ struct threebodyRecoTask {
                 for (auto& lMother2 : lMCTrack2.mothers_as<aod::McParticles>()) {
                   if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) {
                     lLabel = lMother0.globalIndex();
-                    lPDG = lMother1.pdgCode();
+                    lPDG = lMother0.pdgCode();
                     if ((lPDG == motherPdgCode && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == bachelorPdgCode) ||
                         (lPDG == -motherPdgCode && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -bachelorPdgCode)) {
                       isTrueCand = true;
@@ -620,8 +638,9 @@ struct threebodyRecoTask {
                       cand3body.dautpcNclusters[0], cand3body.dautpcNclusters[1], cand3body.dautpcNclusters[2],
                       cand3body.dauitsclussize[0], cand3body.dauitsclussize[1], cand3body.dauitsclussize[2],
                       cand3body.dautpcNsigma[0], cand3body.dautpcNsigma[1], cand3body.dautpcNsigma[2], cand3body.bachelortofNsigma,
+                      cand3body.daudcaxytopv[0], cand3body.daudcaxytopv[1], cand3body.daudcaxytopv[2],
                       cand3body.daudcatopv[0], cand3body.daudcatopv[1], cand3body.daudcatopv[2],
-                      cand3body.lgencand.P(), cand3body.lgencand.Pt(), cand3body.genct, cand3body.lgencand.Phi(), cand3body.lgencand.Eta(),
+                      cand3body.lgencand.P(), cand3body.lgencand.Pt(), cand3body.genct, cand3body.lgencand.Phi(), cand3body.lgencand.Eta(), cand3body.lgencand.Rapidity(),
                       cand3body.isSignal, cand3body.isReco, cand3body.pdgCode, cand3body.SurvivedEventSelection);
       }
     }
@@ -653,7 +672,8 @@ struct threebodyRecoTask {
                     -1, -1, -1,
                     -1, -1, -1, -1,
                     -1, -1, -1,
-                    mcparticle.p(), mcparticle.pt(), MClifetime, mcparticle.phi(), mcparticle.eta(),
+                    -1, -1, -1,
+                    mcparticle.p(), mcparticle.pt(), MClifetime, mcparticle.phi(), mcparticle.eta(), mcparticle.y(),
                     true, false, mcparticle.pdgCode(), isSurEvSelection);
     }
   }
diff --git a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt
index defa3b1abf9..035c4ca6581 100644
--- a/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt
+++ b/PWGLF/TableProducer/Strangeness/Converters/CMakeLists.txt
@@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(strarawcentsconverter2v4
                     PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
                     COMPONENT_NAME Analysis)
 
+o2physics_add_dpl_workflow(straevselsconverter
+                    SOURCES straevselsconverter.cxx
+                    PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
+                    COMPONENT_NAME Analysis)
+
 o2physics_add_dpl_workflow(v0coresconverter
                     SOURCES v0coresconverter.cxx
                     PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
diff --git a/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter.cxx b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter.cxx
new file mode 100644
index 00000000000..9806e15abfc
--- /dev/null
+++ b/PWGLF/TableProducer/Strangeness/Converters/straevselsconverter.cxx
@@ -0,0 +1,62 @@
+// 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 Stra Event selections from 000 to 001
+struct straevselsconverter {
+  Produces<aod::StraEvSels_001> straEvSels_001;
+
+  void process(soa::Join<aod::StraEvSels_000, aod::StraRawCents_004> const& straEvSels_000_RawCents_004)
+  {
+    for (auto& values : straEvSels_000_RawCents_004) {
+      straEvSels_001(values.sel8(),
+                     values.selection_raw(),
+                     values.multFT0A(),
+                     values.multFT0C(),
+                     values.multFT0A(),
+                     0 /*dummy FDDA value*/,
+                     0 /*dummy FDDC value*/,
+                     values.multNTracksPVeta1(),
+                     values.multPVTotalContributors(),
+                     values.multNTracksGlobal(),
+                     values.multNTracksITSTPC(),
+                     values.multAllTracksTPCOnly(),
+                     values.multAllTracksITSTPC(),
+                     values.multZNA(),
+                     values.multZNC(),
+                     values.multZEM1(),
+                     values.multZEM2(),
+                     values.multZPA(),
+                     values.multZPC(),
+                     values.trackOccupancyInTimeRange(),
+                     -1 /*dummy gap side value*/,
+                     -999. /*dummy FT0-A value*/,
+                     -999. /*dummy FT0-C value*/,
+                     -999. /*dummy FV0-A value*/,
+                     -999. /*dummy FDD-A value*/,
+                     -999. /*dummy FDD-C value*/,
+                     -999. /*dummy ZN-A value*/,
+                     -999. /*dummy ZN-C value*/);
+    }
+  }
+};
+
+WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
+{
+  return WorkflowSpec{
+    adaptAnalysisTask<straevselsconverter>(cfgc)};
+}
diff --git a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx
index 08526c22d5d..c651eb31007 100644
--- a/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx
+++ b/PWGLF/TableProducer/Strangeness/strangederivedbuilder.cxx
@@ -58,6 +58,7 @@ using TracksWithExtra = soa::Join<aod::TracksIU, aod::TracksExtra, aod::pidTPCFu
 using TracksCompleteIUMC = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::TracksDCA, aod::McTrackLabels>;
 using FullTracksExtIUTOF = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::TOFEvTime, aod::TOFSignal>;
 using FullCollisions = soa::Join<aod::McCollisionLabels, aod::Collisions, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::FT0Mults>;
+using UDCollisionsFull = soa::Join<aod::UDCollisions, aod::SGCollisions, aod::UDCollisionsSels, aod::UDZdcsReduced, aod::UDCollsLabels>;
 
 // simple bit checkers
 #define bitset(var, nbit) ((var) |= (1 << (nbit)))
@@ -73,8 +74,7 @@ struct strangederivedbuilder {
   Produces<aod::StraMCCollisions> strangeMCColl;   // characterises collisions / MC
   Produces<aod::StraMCCollMults> strangeMCMults;   // characterises collisions / MC mults
   Produces<aod::StraCents> strangeCents;           // characterises collisions / centrality
-  Produces<aod::StraRawCents> strangeRawCents;     // characterises collisions / centrality
-  Produces<aod::StraEvSels> strangeEvSels;         // characterises collisions / sel8 selection
+  Produces<aod::StraEvSels> strangeEvSels;         // characterises collisions / centrality / sel8 selection
   Produces<aod::StraStamps> strangeStamps;         // provides timestamps, run numbers
   Produces<aod::V0CollRefs> v0collref;             // references collisions from V0s
   Produces<aod::CascCollRefs> casccollref;         // references collisions from cascades
@@ -167,12 +167,23 @@ struct strangederivedbuilder {
   Configurable<bool> fillRawFT0A{"fillRawFT0A", false, "Fill raw FT0A information for debug"};
   Configurable<bool> fillRawFT0C{"fillRawFT0C", true, "Fill raw FT0C information for debug"};
   Configurable<bool> fillRawFV0A{"fillRawFV0A", false, "Fill raw FV0A information for debug"};
+  Configurable<bool> fillRawFDDA{"fillRawFDDA", false, "Fill raw FDDA information for debug"};
+  Configurable<bool> fillRawFDDC{"fillRawFDDC", false, "Fill raw FDDC information for debug"};
   Configurable<bool> fillRawZDC{"fillRawZDC", false, "Fill raw ZDC information for debug"};
   Configurable<bool> fillRawNTracksEta1{"fillRawNTracksEta1", true, "Fill raw NTracks |eta|<1 information for debug"};
   Configurable<bool> fillRawNTracksForCorrelation{"fillRawNTracksForCorrelation", true, "Fill raw NTracks for correlation cuts"};
   Configurable<bool> fillTOFInformation{"fillTOFInformation", true, "Fill Daughter Track TOF information"};
 
   Configurable<bool> qaCentrality{"qaCentrality", false, "qa centrality flag: check base raw values"};
+  struct : ConfigurableGroup {
+    ConfigurableAxis axisFT0A{"FT0Aamplitude", {100, 0.0f, 2000.0f}, "FT0Aamplitude"};
+    ConfigurableAxis axisFT0C{"FT0Camplitude", {100, 0.0f, 2000.0f}, "FT0Camplitude"};
+    ConfigurableAxis axisFV0A{"FV0Aamplitude", {100, 0.0f, 2000.0f}, "FV0Aamplitude"};
+    ConfigurableAxis axisFDDA{"FDDAamplitude", {100, 0.0f, 2000.0f}, "FDDAamplitude"};
+    ConfigurableAxis axisFDDC{"FDDCamplitude", {100, 0.0f, 2000.0f}, "FDDCamplitude"};
+    ConfigurableAxis axisZNA{"ZNAamplitude", {100, 0.0f, 250.0f}, "ZNAamplitude"};
+    ConfigurableAxis axisZNC{"ZNCamplitude", {100, 0.0f, 250.0f}, "ZNCamplitude"};
+  } axisDetectors;
 
   // For manual sliceBy
   Preslice<aod::V0Datas> V0perCollision = o2::aod::v0data::collisionId;
@@ -180,6 +191,7 @@ struct strangederivedbuilder {
   Preslice<aod::KFCascDatas> KFCascperCollision = o2::aod::cascdata::collisionId;
   Preslice<aod::TraCascDatas> TraCascperCollision = o2::aod::cascdata::collisionId;
   Preslice<aod::McParticles> mcParticlePerMcCollision = o2::aod::mcparticle::mcCollisionId;
+  Preslice<UDCollisionsFull> udCollisionsPerCollision = o2::aod::udcollision::collisionId;
 
   std::vector<uint32_t> genK0Short;
   std::vector<uint32_t> genLambda;
@@ -230,6 +242,14 @@ struct strangederivedbuilder {
     // for QA and test purposes
     auto hRawCentrality = histos.add<TH1>("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality});
 
+    auto hFT0AMultVsFT0AUD = histos.add<TH2>("hFT0AMultVsFT0AUD", "hFT0AMultVsFT0AUD; FT0-A Mult; FT0-A UD", kTH2F, {axisDetectors.axisFT0A, axisDetectors.axisFT0A});
+    auto hFT0CMultVsFT0CUD = histos.add<TH2>("hFT0CMultVsFT0CUD", "hFT0CMultVsFT0CUD; FT0-C Mult; FT0-C UD", kTH2F, {axisDetectors.axisFT0C, axisDetectors.axisFT0C});
+    auto hFV0AMultVsFV0AUD = histos.add<TH2>("hFV0AMultVsFV0AUD", "hFV0AMultVsFV0AUD; FV0-A Mult; FV0-A UD", kTH2F, {axisDetectors.axisFV0A, axisDetectors.axisFV0A});
+    auto hFDDAMultVsFDDAUD = histos.add<TH2>("hFDDAMultVsFDDAUD", "hFDDAMultVsFDDAUD; FDD-A Mult; FDD-A UD", kTH2F, {axisDetectors.axisFDDA, axisDetectors.axisFDDA});
+    auto hFDDCMultVsFDDCUD = histos.add<TH2>("hFDDCMultVsFDDCUD", "hFDDCMultVsFDDCUD; FDD-C Mult; FDD-C UD", kTH2F, {axisDetectors.axisFDDC, axisDetectors.axisFDDC});
+    auto hZNAMultVsZNAUD = histos.add<TH2>("hZNAMultVsZNAUD", "hZNAMultVsZNAUD; ZNA Mult; ZNA UD", kTH2F, {axisDetectors.axisZNA, axisDetectors.axisZNA});
+    auto hZNCMultVsZNCUD = histos.add<TH2>("hZNCMultVsZNCUD", "hZNCMultVsZNCUD; ZNC Mult; ZNC UD", kTH2F, {axisDetectors.axisZNC, axisDetectors.axisZNC});
+
     for (int ii = 1; ii < 101; ii++) {
       float value = 100.5f - static_cast<float>(ii);
       hRawCentrality->SetBinContent(ii, value);
@@ -250,46 +270,76 @@ struct strangederivedbuilder {
     }
   }
 
-  void processCollisionsV0sOnly(soa::Join<aod::Collisions, aod::FT0Mults, aod::FV0Mults, aod::PVMults, aod::ZDCMults, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::EvSels, aod::MultsExtra, aod::MultsGlobal> const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&)
+  void processCollisionsV0sOnly(soa::Join<aod::Collisions, aod::FT0Mults, aod::FV0Mults, aod::FDDMults, aod::PVMults, aod::ZDCMults, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::EvSels, aod::MultsExtra, aod::MultsGlobal> const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const& /*bcs*/, UDCollisionsFull const& udCollisions)
   {
     for (const auto& collision : collisions) {
       const uint64_t collIdx = collision.globalIndex();
       auto V0Table_thisColl = V0s.sliceBy(V0perCollision, collIdx);
       bool strange = V0Table_thisColl.size() > 0;
+
+      auto bc = collision.bc_as<aod::BCsWithTimestamps>();
+
+      int gapSide = -1;
+      float totalFT0AmplitudeA = -999;
+      float totalFT0AmplitudeC = -999;
+      float totalFV0AmplitudeA = -999;
+      float totalFDDAmplitudeA = -999;
+      float totalFDDAmplitudeC = -999;
+      float energyCommonZNA = -999;
+      float energyCommonZNC = -999;
+      if (udCollisions.size() > 0) { // check that the UD collision table is not empty
+        auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collIdx);
+        if (udCollision.size() == 1) { // check that the slicing provide a unique UD collision
+          for (auto& udColl : udCollision) {
+            gapSide = udColl.gapSide();
+            totalFT0AmplitudeA = udColl.totalFT0AmplitudeA();
+            totalFT0AmplitudeC = udColl.totalFT0AmplitudeC();
+            totalFV0AmplitudeA = udColl.totalFV0AmplitudeA();
+            totalFDDAmplitudeA = udColl.totalFDDAmplitudeA();
+            totalFDDAmplitudeC = udColl.totalFDDAmplitudeC();
+            energyCommonZNA = udColl.energyCommonZNA();
+            energyCommonZNC = udColl.energyCommonZNC();
+          }
+        }
+      }
+
       // casc table sliced
       if (strange || fillEmptyCollisions) {
         strangeColl(collision.posX(), collision.posY(), collision.posZ());
         strangeCents(collision.centFT0M(), collision.centFT0A(),
                      collision.centFT0C(), collision.centFV0A());
-        strangeEvSels(collision.sel8(), collision.selection_raw());
-        auto bc = collision.bc_as<aod::BCsWithTimestamps>();
+        strangeEvSels(collision.sel8(), collision.selection_raw(),
+                      collision.multFT0A() * static_cast<float>(fillRawFT0A),
+                      collision.multFT0C() * static_cast<float>(fillRawFT0C),
+                      collision.multFV0A() * static_cast<float>(fillRawFV0A),
+                      collision.multFDDA() * static_cast<float>(fillRawFDDA),
+                      collision.multFDDC() * static_cast<float>(fillRawFDDC),
+                      collision.multNTracksPVeta1() * static_cast<int>(fillRawNTracksEta1),
+                      collision.multPVTotalContributors() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multNTracksGlobal() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multNTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multAllTracksTPCOnly() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multAllTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multZNA() * static_cast<float>(fillRawZDC),
+                      collision.multZNC() * static_cast<float>(fillRawZDC),
+                      collision.multZEM1() * static_cast<float>(fillRawZDC),
+                      collision.multZEM2() * static_cast<float>(fillRawZDC),
+                      collision.multZPA() * static_cast<float>(fillRawZDC),
+                      collision.multZPC() * static_cast<float>(fillRawZDC),
+                      collision.trackOccupancyInTimeRange(),
+                      // UPC info
+                      gapSide,
+                      totalFT0AmplitudeA, totalFT0AmplitudeC, totalFV0AmplitudeA,
+                      totalFDDAmplitudeA, totalFDDAmplitudeC,
+                      energyCommonZNA, energyCommonZNC);
         strangeStamps(bc.runNumber(), bc.timestamp());
-
-        if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) {
-          strangeRawCents(collision.multFT0A() * static_cast<float>(fillRawFT0A),
-                          collision.multFT0C() * static_cast<float>(fillRawFT0C),
-                          collision.multFV0A() * static_cast<float>(fillRawFV0A),
-                          collision.multNTracksPVeta1() * static_cast<int>(fillRawNTracksEta1),
-                          collision.multPVTotalContributors() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multNTracksGlobal() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multNTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multAllTracksTPCOnly() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multAllTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multZNA() * static_cast<float>(fillRawZDC),
-                          collision.multZNC() * static_cast<float>(fillRawZDC),
-                          collision.multZEM1() * static_cast<float>(fillRawZDC),
-                          collision.multZEM2() * static_cast<float>(fillRawZDC),
-                          collision.multZPA() * static_cast<float>(fillRawZDC),
-                          collision.multZPC() * static_cast<float>(fillRawZDC),
-                          collision.trackOccupancyInTimeRange());
-        }
       }
       for (int i = 0; i < V0Table_thisColl.size(); i++)
         v0collref(strangeColl.lastIndex());
     }
   }
 
-  void processCollisions(soa::Join<aod::Collisions, aod::FT0Mults, aod::FV0Mults, aod::PVMults, aod::ZDCMults, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::EvSels, aod::MultsExtra, aod::MultsGlobal> const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&)
+  void processCollisions(soa::Join<aod::Collisions, aod::FT0Mults, aod::FV0Mults, aod::FDDMults, aod::PVMults, aod::ZDCMults, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::EvSels, aod::MultsExtra, aod::MultsGlobal> const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const& /*bcs*/, UDCollisionsFull const& udCollisions)
   {
     // create collision indices beforehand
     std::vector<int> V0CollIndices(V0s.size(), -1);                 // index -1: no collision
@@ -314,33 +364,71 @@ struct strangederivedbuilder {
                      CascTable_thisColl.size() > 0 ||
                      KFCascTable_thisColl.size() > 0 ||
                      TraCascTable_thisColl.size() > 0;
+
+      auto bc = collision.bc_as<aod::BCsWithTimestamps>();
+
+      int gapSide = -1;
+      float totalFT0AmplitudeA = -999;
+      float totalFT0AmplitudeC = -999;
+      float totalFV0AmplitudeA = -999;
+      float totalFDDAmplitudeA = -999;
+      float totalFDDAmplitudeC = -999;
+      float energyCommonZNA = -999;
+      float energyCommonZNC = -999;
+      if (udCollisions.size() > 0) { // check that the UD collision table is not empty
+        auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collIdx);
+        if (udCollision.size() == 1) { // check that the slicing provide a unique UD collision
+          for (auto& udColl : udCollision) {
+            gapSide = udColl.gapSide();
+            totalFT0AmplitudeA = udColl.totalFT0AmplitudeA();
+            totalFT0AmplitudeC = udColl.totalFT0AmplitudeC();
+            totalFV0AmplitudeA = udColl.totalFV0AmplitudeA();
+            totalFDDAmplitudeA = udColl.totalFDDAmplitudeA();
+            totalFDDAmplitudeC = udColl.totalFDDAmplitudeC();
+            energyCommonZNA = udColl.energyCommonZNA();
+            energyCommonZNC = udColl.energyCommonZNC();
+
+            histos.fill(HIST("hFT0AMultVsFT0AUD"), collision.multFT0A(), udColl.totalFT0AmplitudeA());
+            histos.fill(HIST("hFT0CMultVsFT0CUD"), collision.multFT0C(), udColl.totalFT0AmplitudeC());
+            histos.fill(HIST("hFV0AMultVsFV0AUD"), collision.multFV0A(), udColl.totalFV0AmplitudeA());
+            histos.fill(HIST("hFDDAMultVsFDDAUD"), collision.multFDDA(), udColl.totalFDDAmplitudeA());
+            histos.fill(HIST("hFDDCMultVsFDDCUD"), collision.multFDDC(), udColl.totalFDDAmplitudeC());
+            histos.fill(HIST("hZNAMultVsZNAUD"), collision.multZNA(), udColl.energyCommonZNA());
+            histos.fill(HIST("hZNCMultVsZNCUD"), collision.multZNC(), udColl.energyCommonZNC());
+          }
+        }
+      }
+
       // casc table sliced
       if (strange || fillEmptyCollisions) {
         strangeColl(collision.posX(), collision.posY(), collision.posZ());
         strangeCents(collision.centFT0M(), collision.centFT0A(),
                      centrality, collision.centFV0A());
-        strangeEvSels(collision.sel8(), collision.selection_raw());
-        auto bc = collision.bc_as<aod::BCsWithTimestamps>();
+        strangeEvSels(collision.sel8(), collision.selection_raw(),
+                      collision.multFT0A() * static_cast<float>(fillRawFT0A),
+                      collision.multFT0C() * static_cast<float>(fillRawFT0C),
+                      collision.multFV0A() * static_cast<float>(fillRawFV0A),
+                      collision.multFDDA() * static_cast<float>(fillRawFDDA),
+                      collision.multFDDC() * static_cast<float>(fillRawFDDC),
+                      collision.multNTracksPVeta1() * static_cast<int>(fillRawNTracksEta1),
+                      collision.multPVTotalContributors() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multNTracksGlobal() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multNTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multAllTracksTPCOnly() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multAllTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multZNA() * static_cast<float>(fillRawZDC),
+                      collision.multZNC() * static_cast<float>(fillRawZDC),
+                      collision.multZEM1() * static_cast<float>(fillRawZDC),
+                      collision.multZEM2() * static_cast<float>(fillRawZDC),
+                      collision.multZPA() * static_cast<float>(fillRawZDC),
+                      collision.multZPC() * static_cast<float>(fillRawZDC),
+                      collision.trackOccupancyInTimeRange(),
+                      // UPC info
+                      gapSide,
+                      totalFT0AmplitudeA, totalFT0AmplitudeC, totalFV0AmplitudeA,
+                      totalFDDAmplitudeA, totalFDDAmplitudeC,
+                      energyCommonZNA, energyCommonZNC);
         strangeStamps(bc.runNumber(), bc.timestamp());
-
-        if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) {
-          strangeRawCents(collision.multFT0A() * static_cast<float>(fillRawFT0A),
-                          collision.multFT0C() * static_cast<float>(fillRawFT0C),
-                          collision.multFV0A() * static_cast<float>(fillRawFV0A),
-                          collision.multNTracksPVeta1() * static_cast<int>(fillRawNTracksEta1),
-                          collision.multPVTotalContributors() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multNTracksGlobal() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multNTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multAllTracksTPCOnly() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multAllTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multZNA() * static_cast<float>(fillRawZDC),
-                          collision.multZNC() * static_cast<float>(fillRawZDC),
-                          collision.multZEM1() * static_cast<float>(fillRawZDC),
-                          collision.multZEM2() * static_cast<float>(fillRawZDC),
-                          collision.multZPA() * static_cast<float>(fillRawZDC),
-                          collision.multZPC() * static_cast<float>(fillRawZDC),
-                          collision.trackOccupancyInTimeRange());
-        }
       }
 
       for (const auto& v0 : V0Table_thisColl)
@@ -364,7 +452,7 @@ struct strangederivedbuilder {
       tracasccollref(TraCascadeCollIndices[casc.globalIndex()]);
   }
 
-  void processCollisionsMC(soa::Join<aod::Collisions, aod::FT0Mults, aod::FV0Mults, aod::PVMults, aod::ZDCMults, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::EvSels, aod::McCollisionLabels, aod::MultsExtra, aod::MultsGlobal> const& collisions, soa::Join<aod::V0Datas, aod::McV0Labels> const& V0s, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const& /*V0MCCores*/, soa::Join<aod::CascDatas, aod::McCascLabels> const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&, soa::Join<aod::McCollisions, aod::McCollsExtra, aod::MultsExtraMC> const& mcCollisions, aod::McParticles const&)
+  void processCollisionsMC(soa::Join<aod::Collisions, aod::FT0Mults, aod::FV0Mults, aod::FDDMults, aod::PVMults, aod::ZDCMults, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFV0As, aod::EvSels, aod::McCollisionLabels, aod::MultsExtra, aod::MultsGlobal> const& collisions, soa::Join<aod::V0Datas, aod::McV0Labels> const& V0s, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const& /*V0MCCores*/, soa::Join<aod::CascDatas, aod::McCascLabels> const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const& /*bcs*/, UDCollisionsFull const& udCollisions, soa::Join<aod::McCollisions, aod::McCollsExtra, aod::MultsExtraMC> const& mcCollisions, aod::McParticles const&)
   {
     // create collision indices beforehand
     std::vector<int> V0CollIndices(V0s.size(), -1);                 // index -1: no collision
@@ -402,34 +490,72 @@ struct strangederivedbuilder {
                      CascTable_thisColl.size() > 0 ||
                      KFCascTable_thisColl.size() > 0 ||
                      TraCascTable_thisColl.size() > 0;
+
+      auto bc = collision.bc_as<aod::BCsWithTimestamps>();
+
+      int gapSide = -1;
+      float totalFT0AmplitudeA = -999;
+      float totalFT0AmplitudeC = -999;
+      float totalFV0AmplitudeA = -999;
+      float totalFDDAmplitudeA = -999;
+      float totalFDDAmplitudeC = -999;
+      float energyCommonZNA = -999;
+      float energyCommonZNC = -999;
+      if (udCollisions.size() > 0) { // check that the UD collision table is not empty
+        auto udCollision = udCollisions.sliceBy(udCollisionsPerCollision, collIdx);
+        if (udCollision.size() == 1) { // check that the slicing provide a unique UD collision
+          for (auto& udColl : udCollision) {
+            gapSide = udColl.gapSide();
+            totalFT0AmplitudeA = udColl.totalFT0AmplitudeA();
+            totalFT0AmplitudeC = udColl.totalFT0AmplitudeC();
+            totalFV0AmplitudeA = udColl.totalFV0AmplitudeA();
+            totalFDDAmplitudeA = udColl.totalFDDAmplitudeA();
+            totalFDDAmplitudeC = udColl.totalFDDAmplitudeC();
+            energyCommonZNA = udColl.energyCommonZNA();
+            energyCommonZNC = udColl.energyCommonZNC();
+
+            histos.fill(HIST("hFT0AMultVsFT0AUD"), collision.multFT0A(), udColl.totalFT0AmplitudeA());
+            histos.fill(HIST("hFT0CMultVsFT0CUD"), collision.multFT0C(), udColl.totalFT0AmplitudeC());
+            histos.fill(HIST("hFV0AMultVsFV0AUD"), collision.multFV0A(), udColl.totalFV0AmplitudeA());
+            histos.fill(HIST("hFDDAMultVsFDDAUD"), collision.multFDDA(), udColl.totalFDDAmplitudeA());
+            histos.fill(HIST("hFDDCMultVsFDDCUD"), collision.multFDDC(), udColl.totalFDDAmplitudeC());
+            histos.fill(HIST("hZNAMultVsZNAUD"), collision.multZNA(), udColl.energyCommonZNA());
+            histos.fill(HIST("hZNCMultVsZNCUD"), collision.multZNC(), udColl.energyCommonZNC());
+          }
+        }
+      }
+
       // casc table sliced
       if (strange || fillEmptyCollisions) {
         strangeColl(collision.posX(), collision.posY(), collision.posZ());
         strangeCollLabels(collision.mcCollisionId());
         strangeCents(collision.centFT0M(), collision.centFT0A(),
                      centrality, collision.centFV0A());
-        strangeEvSels(collision.sel8(), collision.selection_raw());
-        auto bc = collision.bc_as<aod::BCsWithTimestamps>();
+        strangeEvSels(collision.sel8(), collision.selection_raw(),
+                      collision.multFT0A() * static_cast<float>(fillRawFT0A),
+                      collision.multFT0C() * static_cast<float>(fillRawFT0C),
+                      collision.multFV0A() * static_cast<float>(fillRawFV0A),
+                      collision.multFDDA() * static_cast<float>(fillRawFDDA),
+                      collision.multFDDC() * static_cast<float>(fillRawFDDC),
+                      collision.multNTracksPVeta1() * static_cast<int>(fillRawNTracksEta1),
+                      collision.multPVTotalContributors() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multNTracksGlobal() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multNTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multAllTracksTPCOnly() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multAllTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
+                      collision.multZNA() * static_cast<float>(fillRawZDC),
+                      collision.multZNC() * static_cast<float>(fillRawZDC),
+                      collision.multZEM1() * static_cast<float>(fillRawZDC),
+                      collision.multZEM2() * static_cast<float>(fillRawZDC),
+                      collision.multZPA() * static_cast<float>(fillRawZDC),
+                      collision.multZPC() * static_cast<float>(fillRawZDC),
+                      collision.trackOccupancyInTimeRange(),
+                      // UPC info
+                      gapSide,
+                      totalFT0AmplitudeA, totalFT0AmplitudeC, totalFV0AmplitudeA,
+                      totalFDDAmplitudeA, totalFDDAmplitudeC,
+                      energyCommonZNA, energyCommonZNC);
         strangeStamps(bc.runNumber(), bc.timestamp());
-
-        if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1 || fillRawZDC) {
-          strangeRawCents(collision.multFT0A() * static_cast<float>(fillRawFT0A),
-                          collision.multFT0C() * static_cast<float>(fillRawFT0C),
-                          collision.multFV0A() * static_cast<float>(fillRawFV0A),
-                          collision.multNTracksPVeta1() * static_cast<int>(fillRawNTracksEta1),
-                          collision.multPVTotalContributors() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multNTracksGlobal() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multNTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multAllTracksTPCOnly() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multAllTracksITSTPC() * static_cast<int>(fillRawNTracksForCorrelation),
-                          collision.multZNA() * static_cast<float>(fillRawZDC),
-                          collision.multZNC() * static_cast<float>(fillRawZDC),
-                          collision.multZEM1() * static_cast<float>(fillRawZDC),
-                          collision.multZEM2() * static_cast<float>(fillRawZDC),
-                          collision.multZPA() * static_cast<float>(fillRawZDC),
-                          collision.multZPC() * static_cast<float>(fillRawZDC),
-                          collision.trackOccupancyInTimeRange());
-        }
       }
       for (const auto& v0 : V0Table_thisColl)
         V0CollIndices[v0.globalIndex()] = strangeColl.lastIndex();
@@ -470,7 +596,7 @@ struct strangederivedbuilder {
     // Figure out the numbering of the new tracks table
     // assume filling per order
     int nTracks = 0;
-    for (int i = 0; i < int(trackMap.size()); i++) {
+    for (int i = 0; i < static_cast<int>(trackMap.size()); i++) {
       if (trackMap[i] >= 0) {
         trackMap[i] = nTracks++;
       }
@@ -545,7 +671,7 @@ struct strangederivedbuilder {
     // Figure out the numbering of the new tracks table
     // assume filling per order
     int nTracks = 0;
-    for (int i = 0; i < int(trackMap.size()); i++) {
+    for (int i = 0; i < static_cast<int>(trackMap.size()); i++) {
       if (trackMap[i] >= 0) {
         trackMap[i] = nTracks++;
       }
@@ -637,7 +763,7 @@ struct strangederivedbuilder {
     // Figure out the numbering of the new mcMother table
     // assume filling per order
     int nParticles = 0;
-    for (int i = 0; i < int(motherReference.size()); i++) {
+    for (int i = 0; i < static_cast<int>(motherReference.size()); i++) {
       if (motherReference[i] >= 0) {
         motherReference[i] = nParticles++; // count particles of interest
       }
@@ -829,7 +955,7 @@ struct strangederivedbuilder {
 
   uint64_t combineProngIndices(uint32_t low, uint32_t high)
   {
-    return (((uint64_t)high) << 32) | ((uint64_t)low);
+    return ((static_cast<uint64_t>(high)) << 32) | (static_cast<uint64_t>(low));
   }
 
   void processV0FoundTags(aod::V0s const& foundV0s, aod::V0Datas const& findableV0s, aod::FindableV0s const& /* added to avoid troubles */)
@@ -851,7 +977,7 @@ struct strangederivedbuilder {
   using uint128_t = __uint128_t;
   uint128_t combineProngIndices128(uint32_t pos, uint32_t neg, uint32_t bach)
   {
-    return (((uint128_t)pos) << 64) | (((uint128_t)neg) << 32) | ((uint128_t)bach);
+    return ((static_cast<uint128_t>(pos)) << 64) | ((static_cast<uint128_t>(neg)) << 32) | (static_cast<uint128_t>(bach));
   }
 
   void processCascFoundTags(aod::Cascades const& foundCascades, aod::CascDatas const& findableCascades, aod::V0s const&, aod::FindableCascades const& /* added to avoid troubles */)
diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx
index 8928c5e2470..ba415978df2 100644
--- a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx
+++ b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx
@@ -62,6 +62,9 @@ struct hypertriton3bodyQa {
       {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}},
       {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}},
       {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}},
+      {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
+      {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
+      {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
@@ -103,6 +106,8 @@ struct hypertriton3bodyQa {
         registry.fill(HIST("hPtProton"), track0.pt());
         registry.fill(HIST("hPtPionMinus"), track1.pt());
         registry.fill(HIST("hPtDeuteron"), track2.pt());
+        registry.fill(HIST("hDCAXYProtonToPV"), vtx.dcaXYtrack0topv());
+        registry.fill(HIST("hDCAXYPionToPV"), vtx.dcaXYtrack1topv());
         registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv());
         registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv());
         registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows());
@@ -111,11 +116,14 @@ struct hypertriton3bodyQa {
         registry.fill(HIST("hPtPionPlus"), track0.pt());
         registry.fill(HIST("hPtAntiProton"), track1.pt());
         registry.fill(HIST("hPtAntiDeuteron"), track2.pt());
+        registry.fill(HIST("hDCAXYProtonToPV"), vtx.dcaXYtrack1topv());
+        registry.fill(HIST("hDCAXYPionToPV"), vtx.dcaXYtrack0topv());
         registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv());
         registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv());
         registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows());
         registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows());
       }
+      registry.fill(HIST("hDCAXYDeuteronToPV"), vtx.dcaXYtrack2topv());
       registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv());
       registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows());
     }
@@ -165,6 +173,9 @@ struct hypertriton3bodyAnalysis {
       {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}},
       {"hPtPionPlus", "hPtPionPlus", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}},
       {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}}}},
+      {"hDCAXYProtonToPV", "hDCAXYProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
+      {"hDCAXYPionToPV", "hDCAXYPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
+      {"hDCAXYDeuteronToPV", "hDCAXYDeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
       {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}},
@@ -371,6 +382,8 @@ struct hypertriton3bodyAnalysis {
       registry.fill(HIST("hPtProton"), trackProton.pt());
       registry.fill(HIST("hPtPionMinus"), trackPion.pt());
       registry.fill(HIST("hPtDeuteron"), trackDeuteron.pt());
+      registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack0topv());
+      registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack1topv());
       registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack0topv());
       registry.fill(HIST("hDCAPionToPV"), candData.dcatrack1topv());
 
@@ -392,6 +405,8 @@ struct hypertriton3bodyAnalysis {
       registry.fill(HIST("hPtAntiProton"), trackProton.pt());
       registry.fill(HIST("hPtPionPlus"), trackPion.pt());
       registry.fill(HIST("hPtAntiDeuteron"), trackDeuteron.pt());
+      registry.fill(HIST("hDCAXYProtonToPV"), candData.dcaXYtrack1topv());
+      registry.fill(HIST("hDCAXYPionToPV"), candData.dcaXYtrack0topv());
       registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack1topv());
       registry.fill(HIST("hDCAPionToPV"), candData.dcatrack0topv());
 
@@ -408,6 +423,7 @@ struct hypertriton3bodyAnalysis {
     } else {
       return;
     }
+    registry.fill(HIST("hDCAXYDeuteronToPV"), candData.dcaXYtrack2topv());
     registry.fill(HIST("hDCADeuteronToPV"), candData.dcatrack2topv());
     registry.fill(HIST("hVtxCosPA"), candData.vtxcosPA(dCollision.posX(), dCollision.posY(), dCollision.posZ()));
     registry.fill(HIST("hDCAVtxDau"), candData.dcaVtxdaughters());
diff --git a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx
index 012da260c95..861f820e157 100644
--- a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx
+++ b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx
@@ -633,7 +633,7 @@ struct derivedCascadeAnalysis {
     return true;
   }
 
-  void processCascades(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels>::iterator const& coll, soa::Join<aod::CascCollRefs, aod::CascCores, aod::CascExtras, aod::CascBBs, aod::CascTOFNSigmas> const& Cascades, soa::Join<aod::DauTrackExtras, aod::DauTrackTPCPIDs> const&)
+  void processCascades(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels>::iterator const& coll, soa::Join<aod::CascCollRefs, aod::CascCores, aod::CascExtras, aod::CascBBs, aod::CascTOFNSigmas> const& Cascades, soa::Join<aod::DauTrackExtras, aod::DauTrackTPCPIDs> const&)
   {
 
     if (!IsEventAccepted(coll, coll.sel8()))
@@ -907,7 +907,7 @@ struct derivedCascadeAnalysis {
       }
     }
   }
-  void processCascadesMCrec(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels, aod::StraCollLabels>::iterator const& coll, soa::Join<aod::CascCollRefs, aod::CascMCCollRefs, aod::CascCores, aod::CascMCCores, aod::CascExtras, aod::CascBBs, aod::CascTOFNSigmas> const& Cascades, soa::Join<aod::DauTrackExtras, aod::DauTrackTPCPIDs> const&)
+  void processCascadesMCrec(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraCollLabels>::iterator const& coll, soa::Join<aod::CascCollRefs, aod::CascMCCollRefs, aod::CascCores, aod::CascMCCores, aod::CascExtras, aod::CascBBs, aod::CascTOFNSigmas> const& Cascades, soa::Join<aod::DauTrackExtras, aod::DauTrackTPCPIDs> const&)
   {
     if (!IsEventAccepted(coll, coll.sel8()))
       return;
diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx
index 0c163e41a9f..606fca84348 100644
--- a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx
+++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx
@@ -49,6 +49,7 @@
 #include "Common/DataModel/Multiplicity.h"
 #include "Common/DataModel/Centrality.h"
 #include "Common/DataModel/PIDResponse.h"
+#include "PWGUD/Core/SGSelector.h"
 
 using namespace o2;
 using namespace o2::framework;
@@ -161,6 +162,19 @@ struct derivedlambdakzeroanalysis {
   ConfigurableAxis axisTPCsignal{"axisTPCsignal", {200, 0.0f, 200.0f}, "TPC signal"};
   ConfigurableAxis axisTOFdeltaT{"axisTOFdeltaT", {200, -5000.0f, 5000.0f}, "TOF Delta T (ps)"};
 
+  // UPC axes
+  ConfigurableAxis axisSelGap{"axisSelGap", {4, -1.5, 2.5}, "Gap side"};
+
+  // UPC selections
+  SGSelector sgSelector;
+  struct : ConfigurableGroup {
+    Configurable<float> FV0cut{"FV0cut", 100., "FV0A threshold"};
+    Configurable<float> FT0Acut{"FT0Acut", 200., "FT0A threshold"};
+    Configurable<float> FT0Ccut{"FT0Ccut", 100., "FT0C threshold"};
+    Configurable<float> ZDCcut{"ZDCcut", 10., "ZDC threshold"};
+    // Configurable<float> gapSel{"gapSel", 2, "Gap selection"};
+  } upcCuts;
+
   // AP plot axes
   ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"};
   ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"};
@@ -177,8 +191,8 @@ struct derivedlambdakzeroanalysis {
   ConfigurableAxis axisMonteCarloNch{"axisMonteCarloNch", {300, 0.0f, 3000.0f}, "N_{ch} MC"};
 
   // For manual sliceBy
-  // Preslice<soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels, aod::StraCollLabels>> perMcCollision = aod::v0data::straMCCollisionId;
-  PresliceUnsorted<soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels, aod::StraCollLabels>> perMcCollision = aod::v0data::straMCCollisionId;
+  // Preslice<soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraCollLabels>> perMcCollision = aod::v0data::straMCCollisionId;
+  PresliceUnsorted<soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraCollLabels>> perMcCollision = aod::v0data::straMCCollisionId;
 
   enum selection : uint64_t { selCosPA = 0,
                               selRadius,
@@ -289,9 +303,9 @@ struct derivedlambdakzeroanalysis {
       // TOF PID
       if (TofPidNsigmaCutK0Pi < 1e+5) // safeguard for no cut
         maskK0ShortSpecific = maskK0ShortSpecific | (uint64_t(1) << selTOFNSigmaNegativePionK0Short) | (uint64_t(1) << selTOFDeltaTNegativePionK0Short);
-      if (TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut
-        maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda);
       if (TofPidNsigmaCutLaPi < 1e+5) // safeguard for no cut
+        maskLambdaSpecific = maskLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativePionLambda) | (uint64_t(1) << selTOFDeltaTNegativePionLambda);
+      if (TofPidNsigmaCutLaPr < 1e+5) // safeguard for no cut
         maskAntiLambdaSpecific = maskAntiLambdaSpecific | (uint64_t(1) << selTOFNSigmaNegativeProtonLambda) | (uint64_t(1) << selTOFDeltaTNegativeProtonLambda);
     }
 
@@ -333,6 +347,9 @@ struct derivedlambdakzeroanalysis {
     histos.add("hEventOccupancy", "hEventOccupancy", kTH1F, {axisOccupancy});
     histos.add("hCentralityVsOccupancy", "hCentralityVsOccupancy", kTH2F, {axisCentrality, axisOccupancy});
 
+    histos.add("hGapSide", "Gap side; Entries", kTH1F, {{5, -0.5, 4.5}});
+    histos.add("hSelGapSide", "Selected gap side; Entries", kTH1F, {axisSelGap});
+
     // for QA and test purposes
     auto hRawCentrality = histos.add<TH1>("hRawCentrality", "hRawCentrality", kTH1F, {axisRawCentrality});
 
@@ -344,6 +361,12 @@ struct derivedlambdakzeroanalysis {
     // histograms versus mass
     if (analyseK0Short) {
       histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass});
+      // Non-UPC info
+      histos.add("h3dMassK0ShortHadronic", "h3dMassK0ShortHadronic", kTH3F, {axisCentrality, axisPt, axisK0Mass});
+      // UPC info
+      histos.add("h3dMassK0ShortSGA", "h3dMassK0ShortSGA", kTH3F, {axisCentrality, axisPt, axisK0Mass});
+      histos.add("h3dMassK0ShortSGC", "h3dMassK0ShortSGC", kTH3F, {axisCentrality, axisPt, axisK0Mass});
+      histos.add("h3dMassK0ShortDG", "h3dMassK0ShortDG", kTH3F, {axisCentrality, axisPt, axisK0Mass});
       if (doTPCQA) {
         histos.add("K0Short/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC});
         histos.add("K0Short/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC});
@@ -383,6 +406,12 @@ struct derivedlambdakzeroanalysis {
     }
     if (analyseLambda) {
       histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      // Non-UPC info
+      histos.add("h3dMassLambdaHadronic", "h3dMassLambdaHadronic", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      // UPC info
+      histos.add("h3dMassLambdaSGA", "h3dMassLambdaSGA", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      histos.add("h3dMassLambdaSGC", "h3dMassLambdaSGC", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      histos.add("h3dMassLambdaDG", "h3dMassLambdaDG", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
       if (doTPCQA) {
         histos.add("Lambda/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC});
         histos.add("Lambda/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC});
@@ -422,6 +451,12 @@ struct derivedlambdakzeroanalysis {
     }
     if (analyseAntiLambda) {
       histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      // Non-UPC info
+      histos.add("h3dMassAntiLambdaHadronic", "h3dMassAntiLambdaHadronic", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      // UPC info
+      histos.add("h3dMassAntiLambdaSGA", "h3dMassAntiLambdaSGA", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      histos.add("h3dMassAntiLambdaSGC", "h3dMassAntiLambdaSGC", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
+      histos.add("h3dMassAntiLambdaDG", "h3dMassAntiLambdaDG", kTH3F, {axisCentrality, axisPt, axisLambdaMass});
       if (doTPCQA) {
         histos.add("AntiLambda/h3dPosNsigmaTPC", "h3dPosNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC});
         histos.add("AntiLambda/h3dNegNsigmaTPC", "h3dNegNsigmaTPC", kTH3F, {axisCentrality, axisPtCoarse, axisNsigmaTPC});
@@ -822,7 +857,7 @@ struct derivedlambdakzeroanalysis {
   }
 
   template <typename TV0>
-  void analyseCandidate(TV0 v0, float pt, float centrality, uint64_t selMap)
+  void analyseCandidate(TV0 v0, float pt, float centrality, uint64_t selMap, uint8_t gapSide)
   // precalculate this information so that a check is one mask operation, not many
   {
     auto posTrackExtra = v0.template posTrackExtra_as<dauTracks>();
@@ -853,6 +888,14 @@ struct derivedlambdakzeroanalysis {
     if (verifyMask(selMap, maskSelectionK0Short) && analyseK0Short) {
       histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), v0.alpha(), v0.qtarm()); // cross-check
       histos.fill(HIST("h3dMassK0Short"), centrality, pt, v0.mK0Short());
+      if (gapSide == 0)
+        histos.fill(HIST("h3dMassK0ShortSGA"), centrality, pt, v0.mK0Short());
+      if (gapSide == 1)
+        histos.fill(HIST("h3dMassK0ShortSGC"), centrality, pt, v0.mK0Short());
+      if (gapSide == 2)
+        histos.fill(HIST("h3dMassK0ShortDG"), centrality, pt, v0.mK0Short());
+      if (gapSide > 2)
+        histos.fill(HIST("h3dMassK0ShortHadronic"), centrality, pt, v0.mK0Short());
       histos.fill(HIST("hMassK0Short"), v0.mK0Short());
       if (doPlainTopoQA) {
         histos.fill(HIST("K0Short/hPosDCAToPV"), v0.dcapostopv());
@@ -898,6 +941,14 @@ struct derivedlambdakzeroanalysis {
     }
     if (verifyMask(selMap, maskSelectionLambda) && analyseLambda) {
       histos.fill(HIST("h3dMassLambda"), centrality, pt, v0.mLambda());
+      if (gapSide == 0)
+        histos.fill(HIST("h3dMassLambdaSGA"), centrality, pt, v0.mLambda());
+      if (gapSide == 1)
+        histos.fill(HIST("h3dMassLambdaSGC"), centrality, pt, v0.mLambda());
+      if (gapSide == 2)
+        histos.fill(HIST("h3dMassLambdaDG"), centrality, pt, v0.mLambda());
+      if (gapSide > 2)
+        histos.fill(HIST("h3dMassLambdaHadronic"), centrality, pt, v0.mLambda());
       if (doPlainTopoQA) {
         histos.fill(HIST("Lambda/hPosDCAToPV"), v0.dcapostopv());
         histos.fill(HIST("Lambda/hNegDCAToPV"), v0.dcanegtopv());
@@ -942,6 +993,14 @@ struct derivedlambdakzeroanalysis {
     }
     if (verifyMask(selMap, maskSelectionAntiLambda) && analyseAntiLambda) {
       histos.fill(HIST("h3dMassAntiLambda"), centrality, pt, v0.mAntiLambda());
+      if (gapSide == 0)
+        histos.fill(HIST("h3dMassAntiLambdaSGA"), centrality, pt, v0.mAntiLambda());
+      if (gapSide == 1)
+        histos.fill(HIST("h3dMassAntiLambdaSGC"), centrality, pt, v0.mAntiLambda());
+      if (gapSide == 2)
+        histos.fill(HIST("h3dMassAntiLambdaDG"), centrality, pt, v0.mAntiLambda());
+      if (gapSide > 2)
+        histos.fill(HIST("h3dMassAntiLambdaHadronic"), centrality, pt, v0.mAntiLambda());
       if (doPlainTopoQA) {
         histos.fill(HIST("AntiLambda/hPosDCAToPV"), v0.dcapostopv());
         histos.fill(HIST("AntiLambda/hNegDCAToPV"), v0.dcanegtopv());
@@ -1077,7 +1136,7 @@ struct derivedlambdakzeroanalysis {
 
   // ______________________________________________________
   // Real data processing - no MC subscription
-  void processRealData(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels>::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&)
+  void processRealData(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels>::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&)
   {
     histos.fill(HIST("hEventSelection"), 0. /* all collisions */);
     if (!collision.sel8()) {
@@ -1150,6 +1209,17 @@ struct derivedlambdakzeroanalysis {
       centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C()));
     }
 
+    // gap side
+    int gapSide = collision.gapSide();
+    int selGapSide = -1;
+    // -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("hEventCentrality"), centrality);
 
     histos.fill(HIST("hCentralityVsNch"), centrality, collision.multNTracksPVeta1());
@@ -1175,13 +1245,13 @@ struct derivedlambdakzeroanalysis {
       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);
 
-      analyseCandidate(v0, v0.pt(), centrality, selMap);
+      analyseCandidate(v0, v0.pt(), centrality, selMap, selGapSide);
     } // end v0 loop
   }
 
   // ______________________________________________________
   // Simulated processing (subscribes to MC information too)
-  void processMonteCarlo(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels, aod::StraCollLabels>::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join<aod::StraMCCollisions, aod::StraMCCollMults> const& /*mccollisions*/, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const&)
+  void processMonteCarlo(soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraCollLabels>::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&, aod::MotherMCParts const&, soa::Join<aod::StraMCCollisions, aod::StraMCCollMults> const& /*mccollisions*/, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const&)
   {
     histos.fill(HIST("hEventSelection"), 0. /* all collisions */);
     if (!collision.sel8()) {
@@ -1254,6 +1324,17 @@ struct derivedlambdakzeroanalysis {
       centrality = hRawCentrality->GetBinContent(hRawCentrality->FindBin(collision.multFT0C()));
     }
 
+    // gap side
+    int gapSide = collision.gapSide();
+    int selGapSide = -1;
+    // -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("hEventCentrality"), centrality);
 
     histos.fill(HIST("hCentralityVsNch"), centrality, collision.multNTracksPVeta1());
@@ -1295,7 +1376,7 @@ struct derivedlambdakzeroanalysis {
         selMap = selMap | (uint64_t(1) << selPhysPrimK0Short) | (uint64_t(1) << selPhysPrimLambda) | (uint64_t(1) << selPhysPrimAntiLambda);
       }
 
-      analyseCandidate(v0, ptmc, centrality, selMap);
+      analyseCandidate(v0, ptmc, centrality, selMap, selGapSide);
 
       if (doCollisionAssociationQA) {
         // check collision association explicitly
@@ -1314,7 +1395,7 @@ struct derivedlambdakzeroanalysis {
 
   // ______________________________________________________
   // Simulated processing (subscribes to MC information too)
-  void processGenerated(soa::Join<aod::StraMCCollisions, aod::StraMCCollMults> const& mcCollisions, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const& V0MCCores, soa::Join<aod::CascMCCores, aod::CascMCCollRefs> const& CascMCCores, soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels, aod::StraCollLabels> const& collisions)
+  void processGenerated(soa::Join<aod::StraMCCollisions, aod::StraMCCollMults> const& mcCollisions, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const& V0MCCores, soa::Join<aod::CascMCCores, aod::CascMCCollRefs> const& CascMCCores, soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraCollLabels> const& collisions)
   {
     std::vector<int> listBestCollisionIdx = fillGenEventHist(mcCollisions, collisions);
     for (auto const& v0MC : V0MCCores) {
@@ -1401,7 +1482,7 @@ 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<int> fillGenEventHist(soa::Join<aod::StraMCCollisions, aod::StraMCCollMults> const& mcCollisions, soa::Join<aod::StraCollisions, aod::StraCents, aod::StraRawCents, aod::StraEvSels, aod::StraCollLabels> const& collisions)
+  std::vector<int> fillGenEventHist(soa::Join<aod::StraMCCollisions, aod::StraMCCollMults> const& mcCollisions, soa::Join<aod::StraCollisions, aod::StraCents, aod::StraEvSels, aod::StraCollLabels> const& collisions)
   {
     std::vector<int> listBestCollisionIdx(mcCollisions.size());
     for (auto const& mcCollision : mcCollisions) {
@@ -1497,49 +1578,49 @@ struct derivedlambdakzeroanalysis {
     auto hOmegaMinus = histos.get<TH2>(HIST("h2dGeneratedOmegaMinus"));
     auto hOmegaPlus = histos.get<TH2>(HIST("h2dGeneratedOmegaPlus"));
     for (auto& gVec : geK0Short) {
-      if (int(gVec.generatedK0Short().size()) != hK0Short->GetNcells())
+      if (static_cast<int>(gVec.generatedK0Short().size()) != hK0Short->GetNcells())
         LOGF(fatal, "K0Short: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedK0Short().size(), hK0Short->GetNcells());
       for (int iv = 0; iv < hK0Short->GetNcells(); iv++) {
         hK0Short->SetBinContent(iv, hK0Short->GetBinContent(iv) + gVec.generatedK0Short()[iv]);
       }
     }
     for (auto& gVec : geLambda) {
-      if (int(gVec.generatedLambda().size()) != hLambda->GetNcells())
+      if (static_cast<int>(gVec.generatedLambda().size()) != hLambda->GetNcells())
         LOGF(fatal, "Lambda: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedLambda().size(), hLambda->GetNcells());
       for (int iv = 0; iv < hLambda->GetNcells(); iv++) {
         hLambda->SetBinContent(iv, hLambda->GetBinContent(iv) + gVec.generatedLambda()[iv]);
       }
     }
     for (auto& gVec : geAntiLambda) {
-      if (int(gVec.generatedAntiLambda().size()) != hAntiLambda->GetNcells())
+      if (static_cast<int>(gVec.generatedAntiLambda().size()) != hAntiLambda->GetNcells())
         LOGF(fatal, "AntiLambda: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedAntiLambda().size(), hAntiLambda->GetNcells());
       for (int iv = 0; iv < hAntiLambda->GetNcells(); iv++) {
         hAntiLambda->SetBinContent(iv, hAntiLambda->GetBinContent(iv) + gVec.generatedAntiLambda()[iv]);
       }
     }
     for (auto& gVec : geXiMinus) {
-      if (int(gVec.generatedXiMinus().size()) != hXiMinus->GetNcells())
+      if (static_cast<int>(gVec.generatedXiMinus().size()) != hXiMinus->GetNcells())
         LOGF(fatal, "XiMinus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedXiMinus().size(), hXiMinus->GetNcells());
       for (int iv = 0; iv < hXiMinus->GetNcells(); iv++) {
         hXiMinus->SetBinContent(iv, hXiMinus->GetBinContent(iv) + gVec.generatedXiMinus()[iv]);
       }
     }
     for (auto& gVec : geXiPlus) {
-      if (int(gVec.generatedXiPlus().size()) != hXiPlus->GetNcells())
+      if (static_cast<int>(gVec.generatedXiPlus().size()) != hXiPlus->GetNcells())
         LOGF(fatal, "XiPlus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedXiPlus().size(), hXiPlus->GetNcells());
       for (int iv = 0; iv < hXiPlus->GetNcells(); iv++) {
         hXiPlus->SetBinContent(iv, hXiPlus->GetBinContent(iv) + gVec.generatedXiPlus()[iv]);
       }
     }
     for (auto& gVec : geOmegaMinus) {
-      if (int(gVec.generatedOmegaMinus().size()) != hOmegaMinus->GetNcells())
+      if (static_cast<int>(gVec.generatedOmegaMinus().size()) != hOmegaMinus->GetNcells())
         LOGF(fatal, "OmegaMinus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedOmegaMinus().size(), hOmegaMinus->GetNcells());
       for (int iv = 0; iv < hOmegaMinus->GetNcells(); iv++) {
         hOmegaMinus->SetBinContent(iv, hOmegaMinus->GetBinContent(iv) + gVec.generatedOmegaMinus()[iv]);
       }
     }
     for (auto& gVec : geOmegaPlus) {
-      if (int(gVec.generatedOmegaPlus().size()) != hOmegaPlus->GetNcells())
+      if (static_cast<int>(gVec.generatedOmegaPlus().size()) != hOmegaPlus->GetNcells())
         LOGF(fatal, "OmegaPlus: Number of elements in generated array and number of cells in receiving histogram differ: %i vs %i!", gVec.generatedOmegaPlus().size(), hOmegaPlus->GetNcells());
       for (int iv = 0; iv < hOmegaPlus->GetNcells(); iv++) {
         hOmegaPlus->SetBinContent(iv, hOmegaPlus->GetBinContent(iv) + gVec.generatedOmegaPlus()[iv]);
diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx
index e1773ce7e24..fca804b8a13 100644
--- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx
+++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx
@@ -1426,7 +1426,7 @@ struct correlateStrangeness {
       Double_t geta = mcParticle.eta();
       Double_t gpt = mcParticle.pt();
       Double_t gphi = mcParticle.phi();
-      if (abs(geta) > 0.8) {
+      if (std::abs(geta) > 0.8f) {
         continue;
       }
       if (abs(mcParticle.pdgCode()) == 211 || abs(mcParticle.pdgCode()) == 321 || abs(mcParticle.pdgCode()) == 2212 || abs(mcParticle.pdgCode()) == 11 || abs(mcParticle.pdgCode()) == 13) {
diff --git a/Tools/PIDML/pidMLProducer.cxx b/Tools/PIDML/pidMLProducer.cxx
index 68f85daac98..67cf4308a5e 100644
--- a/Tools/PIDML/pidMLProducer.cxx
+++ b/Tools/PIDML/pidMLProducer.cxx
@@ -190,11 +190,35 @@ struct PidMlProducer {
     }
   }
 
+  template <typename T>
+  float getTOFSignal(T const& track)
+  {
+    return tofMissing(track) ? std::numeric_limits<float>::quiet_NaN() : track.tofSignal();
+  }
+
+  template <typename T>
+  float getTOFBeta(T const& track)
+  {
+    return tofMissing(track) ? std::numeric_limits<float>::quiet_NaN() : track.beta();
+  }
+
+  template <typename T>
+  float getTRDSignal(T const& track)
+  {
+    return trdMissing(track) ? std::numeric_limits<float>::quiet_NaN() : track.trdSignal();
+  }
+
+  template <typename T>
+  uint8_t getTRDPattern(T const& track)
+  {
+    return trdMissing(track) ? static_cast<uint8_t>(0U) : track.trdPattern();
+  }
+
   void processDataML(MyCollisionML const& /*collision*/, BigTracksDataML const& tracks)
   {
     for (const auto& track : tracks) {
-      pidTracksTableDataML(track.tpcSignal(), track.trdSignal(), track.trdPattern(),
-                           track.tofSignal(), track.beta(),
+      pidTracksTableDataML(track.tpcSignal(), getTRDSignal(track), getTRDPattern(track),
+                           getTOFSignal(track), getTOFBeta(track),
                            track.p(), track.pt(), track.px(), track.py(), track.pz(),
                            track.sign(),
                            track.x(), track.y(), track.z(),
@@ -216,9 +240,9 @@ struct PidMlProducer {
                          collision.multFT0A(), collision.multFT0C(), collision.multFT0M(),
                          collision.multZNA(), collision.multZNC(),
                          collision.multTracklets(), collision.multTPC(),
-                         track.tpcSignal(), track.trdSignal(), track.trdPattern(),
+                         track.tpcSignal(), getTRDSignal(track), getTRDPattern(track),
                          track.trackEtaEmcal(), track.trackPhiEmcal(),
-                         track.tofSignal(), track.beta(),
+                         getTOFSignal(track), getTOFBeta(track),
                          track.p(), track.pt(), track.px(), track.py(), track.pz(),
                          track.sign(),
                          track.x(), track.y(), track.z(),
@@ -251,8 +275,8 @@ struct PidMlProducer {
       const auto mcParticle = track.mcParticle_as<aod::McParticles>();
       uint8_t isPrimary = static_cast<uint8_t>(mcParticle.isPhysicalPrimary());
       uint32_t pdgCode = mcParticle.pdgCode();
-      pidTracksTableMCML(track.tpcSignal(), track.trdSignal(), track.trdPattern(),
-                         track.tofSignal(), track.beta(),
+      pidTracksTableMCML(track.tpcSignal(), getTRDSignal(track), getTRDPattern(track),
+                         getTOFSignal(track), getTOFBeta(track),
                          track.p(), track.pt(), track.px(), track.py(), track.pz(),
                          track.sign(),
                          track.x(), track.y(), track.z(),
@@ -282,9 +306,9 @@ struct PidMlProducer {
                        collision.multFT0A(), collision.multFT0C(), collision.multFT0M(),
                        collision.multZNA(), collision.multZNC(),
                        collision.multTracklets(), collision.multTPC(),
-                       track.tpcSignal(), track.trdSignal(), track.trdPattern(),
+                       track.tpcSignal(), getTRDSignal(track), getTRDPattern(track),
                        track.trackEtaEmcal(), track.trackPhiEmcal(),
-                       track.tofSignal(), track.beta(),
+                       getTOFSignal(track), getTOFBeta(track),
                        track.p(), track.pt(), track.px(), track.py(), track.pz(),
                        track.sign(),
                        track.x(), track.y(), track.z(),