diff --git a/Phys/FunTuple/python/FunTuple/functorcollections.py b/Phys/FunTuple/python/FunTuple/functorcollections.py
index 810d804e69864672c44daec83b0c72a0c9a8f5e7..1cb23aff83b0656cea26864c4a896d498b5c7761 100644
--- a/Phys/FunTuple/python/FunTuple/functorcollections.py
+++ b/Phys/FunTuple/python/FunTuple/functorcollections.py
@@ -24,7 +24,7 @@ from PyConf.reading import get_odin, get_decreports, get_hlt1_selreports  # type
 from PyConf.application import make_data_with_FetchDataFromFile  # type: ignore[import]
 from PyConf.dataflow import DataHandle  # type: ignore[import]
 from PyConf.components import Algorithm  # type: ignore[import]
-from PyConf.Algorithms import HltTisTosAlg, Hlt1TrueSimEffAlg, Hlt2TrueSimEffAlg  # type: ignore[import]
+from PyConf.Algorithms import HltTisTosAlg, Hlt1TrueSimEffAlg, Hlt2TrueSimEffAlg, WeightedRelTableAlg  # type: ignore[import]
 import DaVinciMCTools  # type: ignore[import]
 from DecayTreeFitter import DecayTreeFitter  # type: ignore[import]
 from .FunctorCollection import FunctorCollection
@@ -40,7 +40,8 @@ __all__ = (
     "MCPromptDecay",
     "MCReconstructible",
     "MCReconstructed",
-    "TrackIsolation",
+    "ParticleIsolation",
+    "ConeIsolation",
     "NeutralCaloInfo",
     "DecayTreeFitterResults",
     "ParticleID",
@@ -838,41 +839,42 @@ def MCReconstructed(
     return FunctorCollection(func_dict)
 
 
-def TrackIsolation(*, iso_rel_table: Algorithm) -> FunctorCollection:
+def ParticleIsolation(*, iso_rel_table: Algorithm, name: str = "") -> FunctorCollection:
     """
-    Candidate-level collection of functors on track isolation, using information related to the particles
-    inside the cone around a given reference particle.
+    Candidate-level collection of functors on track or neutral isolation, using information from 'iso_rel_table' argument relating containers of reference and extra particle, namely head particles of the cone and particles inside the cone.
 
     Args:
-        iso_rel_table (WeightedRelTableAlg): algorithm instance returning the required relations table
+        iso_rel_table (Algorithm): algorithm instance returning the required relations table
             that maps a reference particle (forming the head of the cone)
-            to associated particles inside the cone itself.
+            to associated particles (inside the cone itself).
+        name (string, optional): string that helps in distinguishing variables
+            according to some criteria (for example if the isolation criteria are applied to charged or neutral particles).
+            Defaults to "".
 
     Example:
+        import Functors as F
         from FunTuple import FunTuple_Particles as Funtuple
-        from FunTuple.functorcollections import TrackIsolation
+        from FunTuple.functorcollections import ParticleIsolation
         from PyConf.Algorithms import WeightedRelTableAlg
+        from PyConf.reading import get_particles
 
+        branches = {"B": "[B0 -> ([J/psi(1S) -> tau+ mu-]CC)(K*(892)0 -> K+ pi-)]CC"}
+
+        b2ksttaumu_data = get_particles(f"/Event/HLT2/{line}/Particles")
+        b_cciso_data = get_particles(f"/Event/HLT2/{line}/B_{tes_long_track_iso}/Particles")
 
         iso_rel_table = WeightedRelTableAlg(
-           ReferenceParticles=...,
-           InputCandidates=...,
-           Cut=...,
+           ReferenceParticles=b2ksttaumu_data,
+           InputCandidates=b_cciso_data,
+           Cut=F.require_all(F.DR2()<1., ~F.FIND_IN_TREE()), #requires cone geometry with max_coneangle = 1. and extra particles not belonging to the signal
            OutputLevel=INFO)
 
-        variables = TrackIsolation(iso_rel_table)
+        variables = FC.ParticleIsolation(name="CC", iso_rel_table=iso_rel_table)
 
         tuple = Funtuple(name="MyTuple",
-           fields=...,
+           fields=branches,
            variables=variables,
            ...)
-
-
-    Todo:
-        Exclude particles that are in the decay descriptor and therefore belong to the decay that is being looked for.
-        At the moment WeightedRelTableAlg is making relations between the reference particle (head of the cone)
-        and related particles (particles within the cone) without checking whenever the particles in the cone
-        belong to the same decay of the head.
     """
     SUMCONE = lambda func: F.SUMCONE(
         Functor=func, Relations=iso_rel_table.OutputRelations
@@ -892,23 +894,109 @@ def TrackIsolation(*, iso_rel_table: Algorithm) -> FunctorCollection:
     # evaluate DELTA PHI between reference and related particles
     DELTA_PHI = F.ADJUST_ANGLE @ (REL_PHI - REF_PHI)
 
-    TrackIsolationVariables = {
-        "HEAD_CMULT": F.VALUE_OR(0)
+    prefix = "HEAD"
+    if name:
+        prefix += f"_{name}"
+
+    ParticleIsolationVariables = {
+        f"{prefix}_CMULT": F.VALUE_OR(0)
         @ F.MAP_INPUT_SIZE(Relations=iso_rel_table.OutputRelations),
-        "HEAD_CP": SUMCONE(F.P),
-        "HEAD_CPT": SUMCONE(F.PT),
-        "HEAD_CPX": SUMCONE(F.PX),
-        "HEAD_CPY": SUMCONE(F.PY),
-        "HEAD_CPZ": SUMCONE(F.PZ),
-        "HEAD_PASY": ASYM(F.P),
-        "HEAD_PTASY": ASYM(F.PT),
-        "HEAD_PXASY": ASYM(F.PX),
-        "HEAD_PYASY": ASYM(F.PY),
-        "HEAD_PZASY": ASYM(F.PZ),
-        "HEAD_DETA": F.MAP(DELTA_ETA()).bind(RELS(), F.FORWARDARGS),
-        "HEAD_DPHI": F.MAP(DELTA_PHI()).bind(RELS(), F.FORWARDARGS),
+        f"{prefix}_CP": SUMCONE(F.P),
+        f"{prefix}_CPT": SUMCONE(F.PT),
+        f"{prefix}_CPX": SUMCONE(F.PX),
+        f"{prefix}_CPY": SUMCONE(F.PY),
+        f"{prefix}_CPZ": SUMCONE(F.PZ),
+        f"{prefix}_PASY": ASYM(F.P),
+        f"{prefix}_PTASY": ASYM(F.PT),
+        f"{prefix}_PXASY": ASYM(F.PX),
+        f"{prefix}_PYASY": ASYM(F.PY),
+        f"{prefix}_PZASY": ASYM(F.PZ),
+        f"{prefix}_DETA": F.MAP(DELTA_ETA()).bind(RELS(), F.FORWARDARGS),
+        f"{prefix}_DPHI": F.MAP(DELTA_PHI()).bind(RELS(), F.FORWARDARGS),
     }
-    return FunctorCollection(TrackIsolationVariables)
+    return FunctorCollection(ParticleIsolationVariables)
+
+
+def ConeIsolation(
+    *,
+    head_cone: DataHandle,
+    charged_cone: DataHandle,
+    neutral_cone: DataHandle,
+    cut: DataHandle,
+    name: str = "",
+) -> FunctorCollection:
+    """
+    Candidate-level collection of functors on charged and neutral isolation, using information from relations between sets of particles determined by a given criteria. Calculates the relations that 'head_cone' particle selection has with 'charged_cone' particle selection and 'neutral_cone' particle selection, respectively. The cone isolation criteria are determined by the expression in the 'cut'.
+
+    Args:
+        head_cone (DataHandle): container that represents the reference particles (head of the cone).
+        charged_cone (DataHandle): container that represents the extra charged particles persisted from the event.
+        neutral_cone (DataHandle): container that represents the extra neutral particles persisted from the event.
+        cut (DataHandle): selection to relate head particles with extra particles
+        name (string, optional): string that helps in distinguishing variables
+            according to some criteria (for example the cone size criteria).
+            Defaults to "".
+
+    Example:
+        import Functors as F
+        from FunTuple import FunTuple_Particles as Funtuple
+        from FunTuple.functorcollections import ParticleIsolation
+        from PyConf.Algorithms import WeightedRelTableAlg
+        from PyConf.reading import get_particles
+        from GaudiKernel.SystemOfUnits import GeV
+
+        branches = {"B": "[B0 -> ([J/psi(1S) -> tau+ mu-]CC)(K*(892)0 -> K+ pi-)]CC"}
+
+        b2ksttaumu_data = get_particles(f"/Event/HLT2/{line}/Particles")
+        b_cciso_data = get_particles(f"/Event/HLT2/{line}/B_{tes_long_track_iso}/Particles")
+        b_nciso_data = get_particles(f"/Event/HLT2/{line}/B_{tes_neutrals_iso}/Particles")
+
+        variables = FC.ConeIsolation(name="MassConst", head_cone=b2ksttaumu_data, charged_cone=b_cciso_data, neutral_cone=b_nciso_data, cut=((F.COMB_MASS-F.MASS@F.FORWARDARG0)<0.5*GeV)
+
+        tuple = Funtuple(name="MyTuple",
+           fields=branches,
+           variables=variables,
+           ...)
+    """
+    # Prepare relation tables
+    cc_isoAlg = WeightedRelTableAlg(
+        ReferenceParticles=head_cone, InputCandidates=charged_cone, Cut=cut
+    )
+    nc_isoAlg = WeightedRelTableAlg(
+        ReferenceParticles=head_cone, InputCandidates=neutral_cone, Cut=cut
+    )
+
+    cc_str = "CC"
+    nc_str = "NC"
+    if name:
+        cc_str += f"_{name}"
+        nc_str += f"_{name}"
+
+    cc_prefix = "HEAD_" + cc_str
+    nc_prefix = "HEAD_" + nc_str
+    # Invoke twice the ParticleIsolation functorcollection, once for neutral and once for charged particles, then add to the functor dictionary
+    func_dict = {
+        f"{cc_prefix}_Max_PT": F.MAXCONE(
+            Functor=F.PT, Relations=cc_isoAlg.OutputRelations
+        ),
+        f"{cc_prefix}_Min_PT": F.MINCONE(
+            Functor=F.PT, Relations=cc_isoAlg.OutputRelations
+        ),
+        f"{nc_prefix}_Max_PT": F.MAXCONE(
+            Functor=F.PT, Relations=nc_isoAlg.OutputRelations
+        ),
+        f"{nc_prefix}_Min_PT": F.MINCONE(
+            Functor=F.PT, Relations=nc_isoAlg.OutputRelations
+        ),
+    }
+    func_dict.update(
+        ParticleIsolation(name=f"{cc_str}", iso_rel_table=cc_isoAlg).functor_dict
+    )
+    func_dict.update(
+        ParticleIsolation(name=f"{nc_str}", iso_rel_table=nc_isoAlg).functor_dict
+    )
+
+    return FunctorCollection(func_dict)
 
 
 def NeutralCaloInfo() -> FunctorCollection: