diff --git a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/hyperons.py b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/hyperons.py
index 0f4ed7c459a3dc18b94bdd10a11ebc32924721fb..001d7f1feaffb25de8f81f349f23fb3adde94521 100644
--- a/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/hyperons.py
+++ b/Hlt/Hlt2Conf/python/Hlt2Conf/lines/charm/hyperons.py
@@ -23,6 +23,11 @@ Most decays are prompt, some have a dedicated from-b selection.
   Hlt2Charm_Lb0ToLcpDm_LcpToL0Pip_DmToKpPimPim_DD_Line
   Hlt2Charm_Lb0ToLcpDsm_LcpToL0Pip_DmDsmToKmKpPim_LL_Line
   Hlt2Charm_Lb0ToLcpDsm_LcpToL0Pip_DmDsmToKmKpPim_DD_Line
+- Lc -> L K (+ S0 K)  (author: Miroslav Saur)
+  Hlt2Charm_LcpToL0Kp_LL_Line
+  Hlt2Charm_LcpToL0Kp_DD_Line
+  Hlt2Charm_LcpToL0Kp_LL_Inclb_PR_Line
+  Hlt2Charm_LcpToL0Kp_DD_Inclb_PR_Line
 - Xic+ -> L pi (+ S0 pi)
   Hlt2Charm_XicpToL0Pip_LL_Line
   Hlt2Charm_XicpToL0Pip_DD_Line
@@ -207,6 +212,7 @@ Functor wishlist:
 Other:
   - Revisit with isolation as RelatedInfo available
 """
+import Functors as F
 from GaudiKernel.SystemOfUnits import (GeV, MeV, mm, micrometer as um, ps)
 
 from Moore.config import register_line_builder
@@ -216,443 +222,950 @@ from ...standard_particles import (
     make_has_rich_long_pions, make_long_pions, make_has_rich_long_kaons,
     make_has_rich_long_protons, make_has_rich_down_pions, make_down_pions,
     make_has_rich_down_protons)
+from ...algorithms_thor import (ParticleCombiner, ParticleFilter, require_all)
 from .prefilters import charm_prefilters
-from .builders import (filter_particles, combine_2body, combine_3body,
-                       combine_4body)
 
 
-###################################################################
-## shortcuts for (combined) particles used throughout the module ##
-###################################################################
-# rationale : Some particle selections are used a lot throughout the module and it makes sense to change cuts here globally.
-#             The cut values are set here and they are immutable.
-#             We use _ to highlight that these are global functions within the scope of this file.
-def _make_long_pions_from_lambda():
-    return filter_particles(
-        make_long_pions(), pvs=make_pvs(), pt_min=100 * MeV, mipchi2_min=32.)
+# re-definitions of functors
+def _DZ_CHILD(i):
+    return F.CHILD(i, F.END_VZ) - F.END_VZ
+
+
+def _MIPCHI2_MIN(cut, pvs=make_pvs):
+    return F.MINIPCHI2CUT(IPChi2Cut=cut, Vertices=pvs())
+
+
+########################################################################
+## Local builders for (combined) particles used throughout the module ##
+########################################################################
+# Some selections are used multiple times throughout the module.
+# We define their builders upfront here. These builders are local
+# and follow the PEP 8 Style Guide for Python Code
+# https://www.python.org/dev/peps/pep-0008/#descriptive-naming-styles
+#  >  _single_leading_underscore: weak "internal use" indicator.
+#     E.g. from M import * does not import objects whose names
+#     start with an underscore.
+#
+# The cut values are set in the body of the builders,
+# such that they are immutable.
+# This ensures that:
+# - Only one filter or combiner instance is created and called.
+#   This speeds up the selection.
+# - Cut values are set only once and cannot be overwritten.
+#   The code is easier to read and less error-prone.
+#
+# Some builders are standalone and not part of the "configuration-flow"
+# mentioned in the style-guidelines used for Moore/RecoConf:
+# https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/recoconf/recoconf.html
+# The idea behind this is to re-define basic particles as starting point
+# for selections in the module. These builders use proto-particle-makers
+# and pvs directly in the body of the function. Other common selections,
+# like the Xi- builders consume "rare" input particles.
+# These rare input particles are intended to be used to configure the
+# control flow and speed up selections.
+########################################################################
+
+
+def _make_long_pions_for_lambda():
+    return ParticleFilter(
+        make_long_pions(),
+        F.FILTER(require_all(F.PT > 100 * MeV, _MIPCHI2_MIN(32.))))
 
 
-def _make_long_pions_from_ks():
-    return filter_particles(
+def _make_long_pions_for_kshort():
+    return ParticleFilter(
         make_has_rich_long_pions(),
-        pvs=make_pvs(),
-        pt_min=100 * MeV,
-        mipchi2_min=16.,
-        dllk_max=5.)
+        F.FILTER(
+            require_all(F.PT > 100 * MeV, _MIPCHI2_MIN(16.), F.PID_K < 5.)))
 
 
-def _make_long_pions_from_xi():
-    return filter_particles(
-        make_long_pions(), pvs=make_pvs(), pt_min=100 * MeV, mipchi2_min=8.)
+def _make_long_pions_for_xi():
+    return ParticleFilter(
+        make_long_pions(),
+        F.FILTER(require_all(F.PT > 100 * MeV, _MIPCHI2_MIN(8.))))
 
 
-def _make_long_pions_from_d():
-    return filter_particles(
+def _make_long_pions_for_d():
+    return ParticleFilter(
         make_has_rich_long_pions(),
-        make_pvs(),
-        pt_min=150 * MeV,
-        p_min=2 * GeV,
-        mipchi2_min=9.,
-        dllk_max=5.)
+        F.FILTER(
+            require_all(F.PT > 150 * MeV, F.P > 2 * GeV, _MIPCHI2_MIN(12.),
+                        F.PID_K < 5.)))
 
 
-def _make_down_pions_from_ks():
-    return filter_particles(
+def _make_down_pions_for_kshort():
+    return ParticleFilter(
         make_has_rich_down_pions(),
-        pt_min=200 * MeV,
-        p_min=2 * GeV,
-        dllk_max=5.)
+        F.FILTER(require_all(F.PT > 200 * MeV, F.P > 2 * GeV, F.PID_K < 5.)))
 
 
-def _make_down_pions_from_lambda():
-    return filter_particles(make_down_pions(), pt_min=180 * MeV)
+def _make_down_pions_for_lambda():
+    return ParticleFilter(make_down_pions(), F.FILTER(F.PT > 180 * MeV))
 
 
-def _make_long_kaons_from_omega():
-    return filter_particles(
+def _make_long_kaons_for_omega():
+    return ParticleFilter(
         make_has_rich_long_kaons(),
-        pvs=make_pvs(),
-        pt_min=180 * MeV,
-        p_min=3 * GeV,
-        mipchi2_min=9.,
-        dllk_min=-2.)
+        F.FILTER(
+            require_all(F.PT > 180 * MeV, F.P > 3 * GeV, _MIPCHI2_MIN(9.),
+                        F.PID_K > -2.)))
 
 
-def _make_long_kaons_from_d():
-    return filter_particles(
+def _make_long_kaons_for_d():
+    return ParticleFilter(
         make_has_rich_long_kaons(),
-        make_pvs(),
-        pt_min=200 * MeV,
-        p_min=3 * GeV,
-        mipchi2_min=9.,
-        dllk_min=0.)
+        F.FILTER(
+            require_all(F.PT > 200 * MeV, F.P > 3 * GeV, _MIPCHI2_MIN(12.),
+                        F.PID_K > 0.)))
 
 
-def _make_long_protons_from_lambda():
-    return filter_particles(
+def _make_long_protons_for_lambda():
+    return ParticleFilter(
         make_has_rich_long_protons(),
-        pvs=make_pvs(),
-        pt_min=400 * MeV,
-        p_min=9 * GeV,
-        mipchi2_min=6.,
-        dllp_min=-5.)
+        F.FILTER(
+            require_all(F.PT > 400 * MeV, F.P > 9 * GeV, _MIPCHI2_MIN(6.),
+                        F.PID_P > -5.)))
 
 
-def _make_down_protons_from_lambda():
-    return filter_particles(
+def _make_down_protons_for_lambda():
+    return ParticleFilter(
         make_has_rich_down_protons(),
-        pt_min=700 * MeV,
-        p_min=10 * GeV,
-        dllp_min=-5.)
+        F.FILTER(require_all(F.PT > 700 * MeV, F.P > 10 * GeV, F.PID_P > -5.)))
 
 
-def _make_ks_ll():
-    return combine_2body(
-        _make_long_pions_from_ks(),
-        _make_long_pions_from_ks(),
-        "KS0 -> pi+ pi-",
-        pvs=make_pvs(),
+def _make_ll_kshorts():
+    return ParticleCombiner(
+        [_make_long_pions_for_kshort(),
+         _make_long_pions_for_kshort()],
+        DecayDescriptor="KS0 -> pi+ pi-",
         name="Charm_Hyperons_KS0_LL",
-        comb_m_min=435 * MeV,
-        comb_m_max=560 * MeV,
-        m_min=455 * MeV,
-        m_max=540 * MeV,
-        comb_pt_min=300 * MeV,
-        pt_min=350 * MeV,
-        comb_p_min=3.5 * GeV,
-        p_min=4 * GeV,
-        doca_max=150 * um,
-        vchi2dof_max=9.,
-        bpvvdz_min=4 * mm,
-        bpvfdchi2_min=80.)
-
-
-def _make_ks_dd():
-    return combine_2body(
-        _make_down_pions_from_ks(),
-        _make_down_pions_from_ks(),
-        "KS0 -> pi+ pi-",
+        CombinationCut=require_all(
+            F.MASS > 435 * MeV,
+            F.MAXDOCACUT(150 * um),
+            F.MASS < 560 * MeV,
+            F.PT > 300 * MeV,
+            F.P > 3.5 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 455 * MeV,
+            F.MASS < 540 * MeV,
+            F.PT > 350 * MeV,
+            F.P > 4 * GeV,
+            F.CHI2DOF < 9.,
+            F.BPVVDZ(make_pvs()) > 4 * mm,
+            F.BPVFDCHI2(make_pvs()) > 80.,
+        ),
+    )
+
+
+def _make_dd_kshorts():
+    return ParticleCombiner(
+        [_make_down_pions_for_kshort(),
+         _make_down_pions_for_kshort()],
+        DecayDescriptor="KS0 -> pi+ pi-",
         name="Charm_Hyperons_KS0_DD",
-        comb_m_min=425 * MeV,
-        comb_m_max=570 * MeV,
-        m_min=455 * MeV,
-        m_max=540 * MeV,
-        comb_pt_min=400 * MeV,
-        pt_min=450 * MeV,
-        sum_pt_min=500 * MeV,
-        comb_p_min=4.5 * GeV,
-        p_min=5 * GeV,
-        doca_max=2 * mm,
-        docachi2_max=12.,
-        vchi2dof_max=12.)
-
-
-def _make_lambda_ll_from_c():
-    return combine_2body(
-        _make_long_protons_from_lambda(),
-        _make_long_pions_from_lambda(),
-        "[Lambda0 -> p+ pi-]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MAXDOCACUT(2 * mm),
+            F.MAXDOCACHI2CUT(12.),
+            F.MASS > 425 * MeV,
+            F.MASS < 570 * MeV,
+            F.PT > 400 * MeV,
+            F.P > 4.5 * GeV,
+            F.SUM(F.PT) > 500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 455 * MeV,
+            F.MASS < 540 * MeV,
+            F.PT > 450 * MeV,
+            F.P > 5 * GeV,
+            F.CHI2DOF < 12.,
+        ),
+    )
+
+
+def _make_ll_lambdas_for_charm():
+    return ParticleCombiner(
+        [_make_long_protons_for_lambda(),
+         _make_long_pions_for_lambda()],
+        DecayDescriptor="[Lambda0 -> p+ pi-]cc",
         name="Charm_Hyperons_LambdaFromC_LL",
-        comb_m_max=1190 * MeV,
-        m_max=1165 * MeV,
-        comb_pt_min=500 * MeV,
-        pt_min=600 * MeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        bpvvdz_min=8 * mm,
-        bpvfdchi2_min=120.)
-
-
-def _make_lambda_dd():
-    return combine_2body(
-        _make_down_protons_from_lambda(),
-        _make_down_pions_from_lambda(),
-        "[Lambda0 -> p+ pi-]cc",
+        CombinationCut=require_all(
+            F.MASS < 1190 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1165 * MeV,
+            F.PT > 600 * MeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(make_pvs()) > 8 * mm,
+            F.BPVFDCHI2(make_pvs()) > 120.,
+        ),
+    )
+
+
+def _make_dd_lambdas():
+    return ParticleCombiner(
+        [_make_down_protons_for_lambda(),
+         _make_down_pions_for_lambda()],
+        DecayDescriptor="[Lambda0 -> p+ pi-]cc",
         name="Charm_Hyperons_Lambda_DD",
-        comb_m_max=1190 * MeV,
-        m_max=1165 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1 * GeV,
-        comb_p_min=13 * GeV,
-        p_min=14 * GeV,
-        doca_max=2 * mm,
-        docachi2_max=12.,
-        vchi2dof_max=9.)
-
-
-# TODO: so far this is the same as _make_lambda_ll_from_c except for the doca_max cut. look at data to see if a displacement cut like BPVIP(CHI2) makes sense.
-def _make_lambda_ll_from_hyperon():
-    return combine_2body(
-        _make_long_protons_from_lambda(),
-        _make_long_pions_from_lambda(),
-        "[Lambda0 -> p+ pi-]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 1190 * MeV,
+            F.MAXDOCACUT(2 * mm),
+            F.MAXDOCACHI2CUT(12.),
+            F.PT > 0.9 * GeV,
+            F.P > 13 * GeV,
+            F.SUM(F.PT) > 1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1165 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 14 * GeV,
+            F.CHI2DOF < 9.,
+        ),
+    )
+
+
+# TODO: Look at data to see if a displacement cut like BPVIP(CHI2) makes sense.
+def _make_ll_lambdas_for_hyperon():
+    return ParticleCombiner(
+        [_make_long_protons_for_lambda(),
+         _make_long_pions_for_lambda()],
+        DecayDescriptor="[Lambda0 -> p+ pi-]cc",
         name="Charm_Hyperons_LambdaFromHyperon_LL",
-        comb_m_max=1190 * MeV,
-        m_max=1165 * MeV,
-        comb_pt_min=450 * MeV,
-        pt_min=550 * MeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        bpvvdz_min=8 * mm,
-        bpvfdchi2_min=480.)
-
-
-def _make_xi_lll():
-    return combine_2body(
-        _make_lambda_ll_from_hyperon(),
-        _make_long_pions_from_xi(),
-        "[Xi- -> Lambda0 pi-]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 1190 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 450 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1165 * MeV,
+            F.PT > 550 * MeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(make_pvs()) > 8 * mm,
+            F.BPVFDCHI2(make_pvs()) > 480.,
+        ),
+    )
+
+
+# This will always ever be called with ll_lambdas=_make_ll_lambdas_for_hyperon.
+def _make_lll_xis(ll_lambdas, pions, pvs):
+    return ParticleCombiner(
+        [ll_lambdas, pions],
+        DecayDescriptor="[Xi- -> Lambda0 pi-]cc",
         name="Charm_Hyperons_Xim_LLL",
-        comb_m_max=1400 * MeV,
-        m_max=1380 * MeV,
-        comb_pt_min=500 * MeV,
-        pt_min=600 * MeV,
-        doca_max=150 * um,
-        vchi2dof_max=9.,
-        dz1_min=8 * mm,
-        bpvvdz_min=4 * mm,
-        bpvfdchi2_min=16.)
-
-
-def _make_xi_ddl():
-    return combine_2body(
-        _make_lambda_dd(),
-        _make_long_pions_from_xi(),
-        "[Xi- -> Lambda0 pi-]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 1400 * MeV,
+            F.MAXDOCACUT(150 * um),
+            F.PT > 500 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1380 * MeV,
+            F.PT > 600 * MeV,
+            F.CHI2DOF < 9.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 4 * mm,
+            F.BPVFDCHI2(pvs) > 16.,
+        ),
+    )
+
+
+# This will always ever be called with dd_lambdas=_make_dd_lambdas.
+def _make_ddl_xis(dd_lambdas, pions, pvs):
+    return ParticleCombiner(
+        [dd_lambdas, pions],
+        DecayDescriptor="[Xi- -> Lambda0 pi-]cc",
         name="Charm_Hyperons_Xim_DDL",
-        comb_m_max=1400 * MeV,
-        m_max=1380 * MeV,
-        comb_pt_min=1 * GeV,
-        pt_min=1.1 * GeV,
-        comb_p_min=14 * GeV,
-        p_min=15 * GeV,
-        doca_max=750 * um,
-        vchi2dof_max=9.,
-        bpvvdz_min=4 * mm,
-        bpvfdchi2_min=16.)
-
-
-def _make_omega_lll():
-    return combine_2body(
-        _make_lambda_ll_from_hyperon(),
-        _make_long_kaons_from_omega(),
-        "[Omega- -> Lambda0 K-]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 1400 * MeV,
+            F.MAXDOCACUT(750 * um),
+            F.PT > 1 * GeV,
+            F.P > 14 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1380 * MeV,
+            F.PT > 1.1 * GeV,
+            F.P > 15 * GeV,
+            F.CHI2DOF < 9.,
+            F.BPVVDZ(pvs) > 4 * mm,
+            F.BPVFDCHI2(pvs) > 16.,
+        ),
+    )
+
+
+# This will always ever be called with ll_lambdas=_make_ll_lambdas_for_hyperon.
+def _make_lll_omegas(ll_lambdas, kaons, pvs):
+    return ParticleCombiner(
+        [ll_lambdas, kaons],
+        DecayDescriptor="[Omega- -> Lambda0 K-]cc",
         name="Charm_Hyperons_Omegam_LLL",
-        comb_m_max=1750 * MeV,
-        m_max=1730 * MeV,
-        comb_pt_min=550 * MeV,
-        pt_min=650 * MeV,
-        doca_max=150 * um,
-        vchi2dof_max=9.,
-        dz1_min=8 * mm,
-        bpvvdz_min=2 * mm,
-        bpvfdchi2_min=12.)
-
-
-def _make_omega_ddl():
-    return combine_2body(
-        _make_lambda_dd(),
-        _make_long_kaons_from_omega(),
-        "[Omega- -> Lambda0 K-]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 1750 * MeV,
+            F.MAXDOCACUT(150 * um),
+            F.PT > 550 * MeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1730 * MeV,
+            F.PT > 650 * MeV,
+            F.CHI2DOF < 9.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 2 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+        ),
+    )
+
+
+# This will always ever be called with dd_lambdas=_make_dd_lambdas.
+def _make_ddl_omegas(dd_lambdas, kaons, pvs):
+    return ParticleCombiner(
+        [dd_lambdas, kaons],
+        DecayDescriptor="[Omega- -> Lambda0 K-]cc",
         name="Charm_Hyperons_Omegam_DDL",
-        comb_m_max=1750 * MeV,
-        m_max=1730 * MeV,
-        comb_pt_min=1 * GeV,
-        pt_min=1.1 * GeV,
-        comb_p_min=14 * GeV,
-        p_min=15 * GeV,
-        doca_max=750 * um,
-        vchi2dof_max=9.,
-        bpvvdz_min=2 * mm,
-        bpvfdchi2_min=12.)
-
-
-def _make_dminus():
-    return combine_3body(
-        _make_long_kaons_from_d(),
-        _make_long_pions_from_d(),
-        _make_long_pions_from_d(),
-        "[D+ -> K- pi+ pi+]cc",
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 1750 * MeV,
+            F.MAXDOCACUT(750 * um),
+            F.PT > 1 * GeV,
+            F.P > 14 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 1730 * MeV,
+            F.PT > 1.1 * GeV,
+            F.P > 15 * GeV,
+            F.CHI2DOF < 9.,
+            F.BPVVDZ(pvs) > 2 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+        ),
+    )
+
+
+def _make_d_to_kpipi():
+    pions = _make_long_pions_for_d()
+    pvs = make_pvs()
+    return ParticleCombiner(
+        [_make_long_kaons_for_d(), pions, pions],
+        DecayDescriptor="[D+ -> K- pi+ pi+]cc",
         name="Charm_Hyperons_DpToKmPipPip",
-        doca12_max=150 * um,
-        doca13_max=250 * um,
-        doca23_max=250 * um,
-        comb12_m_max=1850 * MeV,
-        comb_m_min=1750 * MeV,
-        comb_m_max=1990 * MeV,
-        m_min=1770 * MeV,
-        m_max=1970 * MeV,
-        comb_pt_min=1.1 * GeV,
-        pt_min=1.2 * GeV,
-        sum_pt_min=1.4 * GeV,
-        comb_p_min=11 * GeV,
-        p_min=12 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=1 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_dsminus():
-    return combine_3body(
-        _make_long_kaons_from_d(),
-        _make_long_kaons_from_d(),
-        _make_long_pions_from_d(),
-        "[D_s+ -> K- K+ pi+]cc",
-        pvs=make_pvs(),
+        Combination12Cut=require_all(
+            F.MAXSDOCACUT(150 * um),
+            F.MASS < 1850 * MeV,
+        ),
+        CombinationCut=require_all(
+            F.MASS > 1750 * MeV,
+            F.MASS < 1990 * MeV,
+            F.MAXSDOCACUT(200 * um),
+            F.PT > 1.1 * GeV,
+            F.P > 11 * GeV,
+            F.SUM(F.PT) > 1.4 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 1770 * MeV,
+            F.MASS < 1970 * MeV,
+            F.PT > 1.2 * GeV,
+            F.P > 12 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > 1 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_ds_to_kkpi():
+    kaons = _make_long_kaons_for_d()
+    pvs = make_pvs()
+    return ParticleCombiner(
+        [kaons, kaons, _make_long_pions_for_d()],
+        DecayDescriptor="[D_s+ -> K- K+ pi+]cc",
         name="Charm_Hyperons_DspToKmKpPip",
-        doca12_max=200 * um,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        comb12_m_max=1950 * MeV,
-        comb_m_min=1750 * MeV,
-        comb_m_max=2090 * MeV,
-        m_min=1770 * MeV,
-        m_max=2070 * MeV,
-        comb_pt_min=1.1 * GeV,
-        pt_min=1.2 * GeV,
-        sum_pt_min=1.4 * GeV,
-        comb_p_min=11 * GeV,
-        p_min=12 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=1 * mm,
-        bpvfdchi2_min=24.)
-
-
-#################################################################
-## global functions for bachelor particles used at least twice ##
-#################################################################
-def _make_loose_pi_from_c():
-    return filter_particles(
+        Combination12Cut=require_all(
+            F.MAXSDOCACUT(150 * um),
+            F.MASS < 1950 * MeV,
+        ),
+        CombinationCut=require_all(
+            F.MAXSDOCACUT(200 * um),
+            F.MASS > 1750 * MeV,
+            F.MASS < 2090 * MeV,
+            F.PT > 1.1 * GeV,
+            F.P > 11 * GeV,
+            F.SUM(F.PT) > 1.4 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 1770 * MeV,
+            F.MASS < 2070 * MeV,
+            F.PT > 1.2 * GeV,
+            F.P > 12 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > 1 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+#########################################################
+## Local bachelor particle filters used at least twice ##
+#########################################################
+def _make_loose_pions_for_charm():
+    return ParticleFilter(
         make_has_rich_long_pions(),
-        pvs=make_pvs(),
-        pt_min=250 * MeV,
-        p_min=2 * GeV,
-        mipchi2_min=3.,
-        dllk_max=5.)
+        F.FILTER(
+            require_all(F.PT > 250 * MeV, F.P > 2 * GeV, _MIPCHI2_MIN(3.),
+                        F.PID_K < 5.), ),
+    )
 
 
-def _make_std_pi_from_c():
-    return filter_particles(
+def _make_std_pions_for_charm():
+    return ParticleFilter(
         make_has_rich_long_pions(),
-        pvs=make_pvs(),
-        pt_min=300 * MeV,
-        p_min=2 * GeV,
-        mipchi2_min=4.,
-        dllk_max=5.)
+        F.FILTER(
+            require_all(F.PT > 300 * MeV, F.P > 2 * GeV, _MIPCHI2_MIN(4.),
+                        F.PID_K < 5.), ),
+    )
 
 
-def _make_tight_pi_from_c():
-    return filter_particles(
+def _make_tight_pions_for_charm():
+    return ParticleFilter(
         make_has_rich_long_pions(),
-        pvs=make_pvs(),
-        pt_min=400 * MeV,
-        p_min=3 * GeV,
-        mipchi2_min=6.,
-        dllk_max=5.)
+        F.FILTER(
+            require_all(F.PT > 400 * MeV, F.P > 3 * GeV, _MIPCHI2_MIN(6.),
+                        F.PID_K < 5.), ),
+    )
 
 
-def _make_verytight_pi_from_c():
-    return filter_particles(
+def _make_verytight_pions_for_charm():
+    return ParticleFilter(
         make_has_rich_long_pions(),
-        pvs=make_pvs(),
-        pt_min=400 * MeV,
-        p_min=3 * GeV,
-        mipchi2_min=9.,
-        dllk_max=5.)
+        F.FILTER(
+            require_all(F.PT > 400 * MeV, F.P > 3 * GeV, _MIPCHI2_MIN(9.),
+                        F.PID_K < 5.), ),
+    )
 
 
-def _make_std_k_from_c():
-    return filter_particles(
+def _make_std_kaons_for_charm():
+    return ParticleFilter(
         make_has_rich_long_kaons(),
-        pvs=make_pvs(),
-        pt_min=400 * MeV,
-        p_min=5 * GeV,
-        mipchi2_min=3.,
-        dllk_min=0.)
+        F.FILTER(
+            require_all(F.PT > 400 * MeV, F.P > 5 * GeV, _MIPCHI2_MIN(3.),
+                        F.PID_K > 0.), ),
+    )
 
 
-def _make_tight_k_from_c():
-    return filter_particles(
+def _make_tight_kaons_for_charm():
+    return ParticleFilter(
         make_has_rich_long_kaons(),
-        pvs=make_pvs(),
-        pt_min=450 * MeV,
-        p_min=6 * GeV,
-        mipchi2_min=5.,
-        dllk_min=5.)
+        F.FILTER(
+            require_all(F.PT > 450 * MeV, F.P > 6 * GeV, _MIPCHI2_MIN(5.),
+                        F.PID_K > 5.), ),
+    )
 
 
-def _make_verytight_k_from_c():
-    return filter_particles(
+def _make_verytight_kaons_for_charm():
+    return ParticleFilter(
         make_has_rich_long_kaons(),
-        pvs=make_pvs(),
-        pt_min=500 * MeV,
-        p_min=6 * GeV,
-        mipchi2_min=7.,
-        dllk_min=5.)
+        F.FILTER(
+            require_all(F.PT > 500 * MeV, F.P > 6 * GeV, _MIPCHI2_MIN(7.),
+                        F.PID_K > 5.), ),
+    )
 
 
-def _make_long_b_tracks():
-    return filter_particles(
+def _make_long_tracks_for_beauty():
+    return ParticleFilter(
         make_long_pions(),
-        pvs=make_pvs(),
-        pt_min=500 * MeV,
-        p_min=3 * GeV,
-        mipchi2_min=9.)
-
-
-def _make_xb_to_xct(xc, t, descriptor):
-    return combine_2body(
-        xc,
-        t,
-        descriptor,
-        pvs=make_pvs(),
+        F.FILTER(
+            require_all(
+                F.PT > 500 * MeV,
+                F.P > 3 * GeV,
+                _MIPCHI2_MIN(9.),
+            ), ),
+    )
+
+
+#################################################
+## Local "for-b" combiners used at least twice ##
+#################################################
+def _make_bbaryon_to_cbaryonttrack(cbaryon, track, pvs, descriptor):
+    return ParticleCombiner(
+        [cbaryon, track],
+        DecayDescriptor=descriptor,
         name="Charm_Hyperons_XbToXcTrack",
-        comb_m_max=6.4 * GeV,
-        m_max=6.3 * GeV,
-        comb_pt_min=1.4 * GeV,
-        pt_min=1.5 * GeV,
-        sum_pt_min=3 * GeV,
-        comb_p_min=24 * GeV,
-        p_min=25 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=-1 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_xb_to_xcd(xc, d, descriptor):
-    return combine_2body(
-        xc,
-        d,
-        descriptor,
-        pvs=make_pvs(),
+        CombinationCut=require_all(
+            F.MASS < 6.4 * GeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 1.4 * GeV,
+            F.P > 24 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 6.3 * GeV,
+            F.PT > 1.5 * GeV,
+            F.SUM(F.PT) > 3 * GeV,
+            F.P > 25 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > -1 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_bbaryon_to_cbaryond(xc, d, pvs, descriptor):
+    return ParticleCombiner(
+        [xc, d],
+        DecayDescriptor=descriptor,
         name="Charm_Hyperons_XbToXcD",
-        comb_m_min=4.9 * GeV,
-        comb_m_max=6.4 * GeV,
-        m_min=5 * GeV,
-        m_max=6.3 * GeV,
-        comb_pt_min=3.8 * GeV,
-        pt_min=4 * GeV,
-        sum_pt_min=4.5 * GeV,
-        comb_p_min=28 * GeV,
-        p_min=30 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=9.,
-        dz1_min=-1 * mm,
-        dz2_min=0 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=12.,
-        bpvdira_min=0.999)
+        CombinationCut=require_all(
+            F.MASS > 4.9 * GeV,
+            F.MASS < 6.4 * GeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 3.8 * GeV,
+            F.P > 28 * GeV,
+            F.SUM(F.PT) > 4.5 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 5 * GeV,
+            F.MASS < 6.3 * GeV,
+            F.PT > 4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 9.,
+            _DZ_CHILD(1) > -1 * mm,
+            _DZ_CHILD(2) > 0 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 12.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
+
+
+def _make_detached_lc_to_lpi_ll(ll_lambdas, pions, pvs):
+    return ParticleCombiner(
+        [ll_lambdas, pions],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_DetachedLcpToL0Pip_LL",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_lc_to_lpi_dd(dd_lambdas, pions, pvs):
+    return ParticleCombiner(
+        [dd_lambdas, pions],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_DetachedLcpToL0Pip_DD",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(1 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > 0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicp_to_lpi_ll(ll_lambdas, pions, pvs):
+    return ParticleCombiner(
+        [ll_lambdas, pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_DetachedXicpToL0Pip_LL",
+        CombinationCut=require_all(
+            F.MASS > 2360 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2380 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicp_to_lpi_dd(dd_lambdas, pions, pvs):
+    return ParticleCombiner(
+        [dd_lambdas, pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_DetachedXicpToL0Pip_DD",
+        CombinationCut=require_all(
+            F.MASS > 2360 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(1 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2380 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicz_to_ximpi_lll(lll_xis, pions, pvs):
+    return ParticleCombiner(
+        [lll_xis, pions],
+        DecayDescriptor="[Xi_c0 -> Xi- pi+]cc",
+        name="Charm_Hyperons_DetachedXic0ToXimPip_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicz_to_ximpi_ddl(ddl_xis, pions, pvs):
+    return ParticleCombiner(
+        [ddl_xis, pions],
+        DecayDescriptor="[Xi_c0 -> Xi- pi+]cc",
+        name="Charm_Hyperons_DetachedXic0ToXimPip_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicz_to_ximk_lll(lll_xis, kaons, pvs):
+    return ParticleCombiner(
+        [lll_xis, kaons],
+        DecayDescriptor="[Xi_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_DetachedXic0ToXimKp_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicz_to_ximk_ddl(ddl_xis, kaons, pvs):
+    return ParticleCombiner(
+        [ddl_xis, kaons],
+        DecayDescriptor="[Xi_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_DetachedXic0ToXimKp_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_oc_to_ximk_lll(lll_xis, kaons, pvs):
+    return ParticleCombiner(
+        [lll_xis, kaons],
+        DecayDescriptor="[Omega_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_DetachedOc0ToXimKp_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_oc_to_ximk_ddl(ddl_xis, kaons, pvs):
+    return ParticleCombiner(
+        [ddl_xis, kaons],
+        DecayDescriptor="[Omega_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_DetachedOc0ToXimKp_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_oc_to_ompi_lll(lll_oms, pions, pvs):
+    return ParticleCombiner(
+        [lll_oms, pions],
+        DecayDescriptor="[Omega_c0 -> Omega- pi+]cc",
+        name="Charm_Hyperons_DetachedOc0ToOmPip_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_oc_to_ompi_ddl(ddl_oms, pions, pvs):
+    return ParticleCombiner(
+        [ddl_oms, pions],
+        DecayDescriptor="[Omega_c0 -> Omega- pi+]cc",
+        name="Charm_Hyperons_DetachedOc0ToOmPip_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 1.3 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.3 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicp_to_ximpipi_lll(lll_xis, pions, pvs):
+    return ParticleCombiner(
+        [lll_xis, pions, pions],
+        DecayDescriptor="[Xi_c+ -> Xi- pi+ pi+]cc",
+        name="Charm_Hyperons_DetachedXicpToXimPipPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 250 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicp_to_ximpipi_ddl(ddl_xis, pions, pvs):
+    return ParticleCombiner(
+        [ddl_xis, pions, pions],
+        DecayDescriptor="[Xi_c+ -> Xi- pi+ pi+]cc",
+        name="Charm_Hyperons_DetachedXicpToXimPipPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 1.2 * mm,
+            F.DOCA(2, 3) < 400 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.9 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicz_to_lkpi_ll(ll_lambdas, kaons, pions, pvs):
+    return ParticleCombiner(
+        [ll_lambdas, kaons, pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 K- pi+]cc",
+        name="Charm_Hyperons_DetachedXic0ToL0KmPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2360 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2380 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+
+
+def _make_detached_xicz_to_lkpi_dd(dd_lambdas, kaons, pions, pvs):
+    return ParticleCombiner(
+        [dd_lambdas, kaons, pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 K- pi+]cc",
+        name="Charm_Hyperons_DetachedXic0ToL0KmPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(800 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 1 * mm,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2360 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2380 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
 
 
 ###################
@@ -671,1557 +1184,1618 @@ all_lines = {}
 # Lc -> L pi and partially reconstructed Lc -> Sigma0 pi. Expected rate 6.2 kHz
 @register_line_builder(all_lines)
 def lc_to_lpi_ll_line(name="Hlt2Charm_LcpToL0Pip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_lc_pions = _make_tight_pi_from_c()
-    lc_LL = combine_2body(
-        lambda_ll,
-        long_lc_pions,
-        "[Lambda_c+ -> Lambda0 pi+]cc",
-        make_pvs(),
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.998)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, lc_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    lcs = ParticleCombiner(
+        [ll_lambdas, _make_tight_pions_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_LcpToL0Pip_LL",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_lpi_dd_line(name="Hlt2Charm_LcpToL0Pip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_lc_pions = _make_tight_pi_from_c()
-    lc_DD = combine_2body(
-        lambda_dd,
-        long_lc_pions,
-        "[Lambda_c+ -> Lambda0 pi+]cc",
-        make_pvs(),
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=1 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.998)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, lc_DD])
-
-
-def _make_detached_lc_to_lpi_ll():
-    lambda_ll = _make_lambda_ll_from_c()
-    long_lc_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        lambda_ll,
-        long_lc_pions,
-        "[Lambda_c+ -> Lambda0 pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedLcpToL0Pip_LL",
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,  # TODO: tighten. see Lc -> L K
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_lc_to_lpi_dd():
-    lambda_dd = _make_lambda_dd()
-    long_lc_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        lambda_dd,
-        long_lc_pions,
-        "[Lambda_c+ -> Lambda0 pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedLcpToL0Pip_DD",
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=1 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    lcs = ParticleCombiner(
+        [dd_lambdas, _make_tight_pions_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_LcpToL0Pip_DD",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(1 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_lpi_llinclb_line(name="Hlt2Charm_LcpToL0Pip_LL_Inclb_PR_Line"):
-    lc_ll = _make_detached_lc_to_lpi_ll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_lch = _make_xb_to_xct(lc_ll, long_b_tracks,
-                               "[Lambda_b0 -> Lambda_c+ pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    lcs = _make_detached_lc_to_lpi_ll(ll_lambdas,
+                                      _make_verytight_pions_for_charm(), pvs)
+    b_to_lch = _make_bbaryon_to_cbaryonttrack(
+        lcs, _make_long_tracks_for_beauty(), pvs,
+        "[Lambda_b0 -> Lambda_c+ pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lc_ll, b_to_lch],
+        algs=charm_prefilters() + [ll_lambdas, lcs, b_to_lch],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def lc_to_lpi_ddinclb_line(name="Hlt2Charm_LcpToL0Pip_DD_Inclb_PR_Line"):
-    lc_dd = _make_detached_lc_to_lpi_dd()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_lch = _make_xb_to_xct(lc_dd, long_b_tracks,
-                               "[Lambda_b0 -> Lambda_c+ pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    lc_dd = _make_detached_lc_to_lpi_dd(dd_lambdas,
+                                        _make_verytight_pions_for_charm(), pvs)
+    b_to_lch = _make_bbaryon_to_cbaryonttrack(
+        lc_dd, _make_long_tracks_for_beauty(), pvs,
+        "[Lambda_b0 -> Lambda_c+ pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lc_dd, b_to_lch],
+        algs=charm_prefilters() + [dd_lambdas, lc_dd, b_to_lch],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
-def lc_to_lk_ll_line(name="Hlt2Charm_LcpToL0Kp_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_lc_kaons = _make_tight_k_from_c()
-    lc_LL = combine_2body(
-        lambda_ll,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 K+]cc",
-        make_pvs(),
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.998)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, lc_LL])
+def lb_to_lcdm_lc_to_lpi_ll_line(
+        name="Hlt2Charm_Lb0ToLcpDm_LcpToL0Pip_DmToKpPimPim_LL_Line"):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    lcs = _make_detached_lc_to_lpi_ll(ll_lambdas,
+                                      _make_verytight_pions_for_charm(), pvs)
+    dm = _make_d_to_kpipi()
+    b_to_lch = _make_bbaryon_to_cbaryond(lcs, dm, pvs,
+                                         "[Lambda_b0 -> Lambda_c+ D-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lcs, b_to_lch])
 
 
 @register_line_builder(all_lines)
-def lc_to_lk_dd_line(name="Hlt2Charm_LcpToL0Kp_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_lc_kaons = _make_tight_k_from_c()
-    lc_DD = combine_2body(
-        lambda_dd,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 K+]cc",
-        make_pvs(),
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=1 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.998)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, lc_DD])
-
-
-def _make_detached_lc_to_lk_ll():
-    lambda_ll = _make_lambda_ll_from_c()
-    long_lc_kaons = _make_verytight_k_from_c()
-    return combine_2body(
-        lambda_ll,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 K+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedLcpToL0Kp_LL",
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0.5 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_lc_to_lk_dd():
-    lambda_dd = _make_lambda_dd()
-    long_lc_kaons = _make_verytight_k_from_c()
-    return combine_2body(
-        lambda_dd,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 K+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedLcpToL0Kp_DD",
-        comb_m_min=2080 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2100 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=1 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=0.5 * mm,
-        bpvfdchi2_min=24.)
+def lb_to_lcdm_lc_to_lpi_dd_line(
+        name="Hlt2Charm_Lb0ToLcpDm_LcpToL0Pip_DmToKpPimPim_DD_Line"):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    lc_dd = _make_detached_lc_to_lpi_dd(dd_lambdas,
+                                        _make_verytight_pions_for_charm(), pvs)
+    dm = _make_d_to_kpipi()
+    b_to_lch = _make_bbaryon_to_cbaryond(lc_dd, dm, pvs,
+                                         "[Lambda_b0 -> Lambda_c+ D-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, lc_dd, b_to_lch])
 
 
 @register_line_builder(all_lines)
-def lc_to_lk_llinclb_line(name="Hlt2Charm_LcpToL0Kp_LL_Inclb_PR_Line"):
-    lc_ll = _make_detached_lc_to_lk_ll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_lch = _make_xb_to_xct(lc_ll, long_b_tracks,
-                               "[Lambda_b0 -> Lambda_c+ pi-]cc")
+def lb_to_lcdsm_lc_to_lpi_ll_line(
+        name="Hlt2Charm_Lb0ToLcpDsm_LcpToL0Pip_DmDsmToKmKpPim_LL_Line"):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    lcs = _make_detached_lc_to_lpi_ll(ll_lambdas,
+                                      _make_verytight_pions_for_charm(), pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_lch = _make_bbaryon_to_cbaryond(lcs, dsm, pvs,
+                                         "[Lambda_b0 -> Lambda_c+ D_s-]cc")
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lc_ll, b_to_lch],
-        persistreco=True)
+        name=name, algs=charm_prefilters() + [ll_lambdas, lcs, b_to_lch])
 
 
 @register_line_builder(all_lines)
-def lc_to_lk_ddinclb_line(name="Hlt2Charm_LcpToL0Kp_DD_Inclb_PR_Line"):
-    lc_dd = _make_detached_lc_to_lk_dd()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_lch = _make_xb_to_xct(lc_dd, long_b_tracks,
-                               "[Lambda_b0 -> Lambda_c+ pi-]cc")
+def lb_to_lcdsm_lc_to_lpi_dd_line(
+        name="Hlt2Charm_Lb0ToLcpDsm_LcpToL0Pip_DmDsmToKmKpPim_DD_Line"):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    lc_dd = _make_detached_lc_to_lpi_dd(dd_lambdas,
+                                        _make_verytight_pions_for_charm(), pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_lch = _make_bbaryon_to_cbaryond(lc_dd, dsm, pvs,
+                                         "[Lambda_b0 -> Lambda_c+ D_s-]cc")
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lc_dd, b_to_lch],
-        persistreco=True)
+        name=name, algs=charm_prefilters() + [dd_lambdas, lc_dd, b_to_lch])
 
 
 @register_line_builder(all_lines)
-def lb_to_lcdm_lc_to_lpi_ll_line(
-        name="Hlt2Charm_Lb0ToLcpDm_LcpToL0Pip_DmToKpPimPim_LL_Line"):
-    lc_ll = _make_detached_lc_to_lpi_ll()
-    dm = _make_dminus()
-    b_to_lch = _make_xb_to_xcd(lc_ll, dm, "[Lambda_b0 -> Lambda_c+ D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lc_ll, b_to_lch])
+def lc_to_lk_ll_line(name="Hlt2Charm_LcpToL0Kp_LL_Line"):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    lcs = ParticleCombiner(
+        [ll_lambdas, _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 K+]cc",
+        name="Charm_Hyperons_LcpToL0Kp_LL",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, lcs])
 
 
 @register_line_builder(all_lines)
-def lb_to_lcdm_lc_to_lpi_dd_line(
-        name="Hlt2Charm_Lb0ToLcpDm_LcpToL0Pip_DmToKpPimPim_DD_Line"):
-    lc_dd = _make_detached_lc_to_lpi_dd()
-    dm = _make_dminus()
-    b_to_lch = _make_xb_to_xcd(lc_dd, dm, "[Lambda_b0 -> Lambda_c+ D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lc_dd, b_to_lch])
+def lc_to_lk_dd_line(name="Hlt2Charm_LcpToL0Kp_DD_Line"):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    lcs = ParticleCombiner(
+        [dd_lambdas, _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 K+]cc",
+        name="Charm_Hyperons_LcpToL0Kp_DD",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(1 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, lcs])
 
 
 @register_line_builder(all_lines)
-def lb_to_lcdsm_lc_to_lpi_ll_line(
-        name="Hlt2Charm_Lb0ToLcpDsm_LcpToL0Pip_DmDsmToKmKpPim_LL_Line"):
-    lc_ll = _make_detached_lc_to_lpi_ll()
-    dsm = _make_dsminus()
-    b_to_lch = _make_xb_to_xcd(lc_ll, dsm, "[Lambda_b0 -> Lambda_c+ D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lc_ll, b_to_lch])
+def lc_to_lk_llinclb_line(name="Hlt2Charm_LcpToL0Kp_LL_Inclb_PR_Line"):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    lcs = ParticleCombiner(
+        [ll_lambdas, _make_verytight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 K+]cc",
+        name="Charm_Hyperons_DetachedLcpToL0Kp_LL",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+    b_to_lch = _make_bbaryon_to_cbaryonttrack(
+        lcs, _make_long_tracks_for_beauty(), pvs,
+        "[Lambda_b0 -> Lambda_c+ pi-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lcs, b_to_lch],
+        persistreco=True)
 
 
 @register_line_builder(all_lines)
-def lb_to_lcdsm_lc_to_lpi_dd_line(
-        name="Hlt2Charm_Lb0ToLcpDsm_LcpToL0Pip_DmDsmToKmKpPim_DD_Line"):
-    lc_dd = _make_detached_lc_to_lpi_dd()
-    dsm = _make_dsminus()
-    b_to_lch = _make_xb_to_xcd(lc_dd, dsm, "[Lambda_b0 -> Lambda_c+ D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lc_dd, b_to_lch])
+def lc_to_lk_ddinclb_line(name="Hlt2Charm_LcpToL0Kp_DD_Inclb_PR_Line"):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    lcs = ParticleCombiner(
+        [dd_lambdas, _make_verytight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 K+]cc",
+        name="Charm_Hyperons_DetachedLcpToL0Kp_DD",
+        CombinationCut=require_all(
+            F.MASS > 2080 * MeV,
+            F.MASS < 2405 * MeV,
+            F.MAXDOCACUT(1 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2100 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > 0.5 * mm,
+            F.BPVFDCHI2(pvs) > 24.,
+        ),
+    )
+    b_to_lch = _make_bbaryon_to_cbaryonttrack(
+        lcs, _make_long_tracks_for_beauty(), pvs,
+        "[Lambda_b0 -> Lambda_c+ pi-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [lcs, b_to_lch], persistreco=True)
 
 
 # Xic+ -> L pi and partially reconstructed Xic -> Sigma0 pi. Expected rate 320 Hz + a bit of Lc -> L pi
 @register_line_builder(all_lines)
 def xicp_to_lpi_ll_line(name="Hlt2Charm_XicpToL0Pip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    xic_LL = combine_2body(
-        lambda_ll,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 pi+]cc",
-        make_pvs(),
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2380 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0.1 * mm,
-        bpvfdchi2_min=12.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.999)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, xic_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xicps = ParticleCombiner(
+        [ll_lambdas, _make_verytight_pions_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_XicpToL0Pip_LL",
+        CombinationCut=require_all(
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 1.3 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2380 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0.1 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lpi_dd_line(name="Hlt2Charm_XicpToL0Pip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    xic_DD = combine_2body(
-        lambda_dd,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 pi+]cc",
-        make_pvs(),
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2380 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.4 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=1 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=0.1 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, xic_DD])
-
-
-def _make_detached_xicp_to_lpi_ll():
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        lambda_ll,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXicpToL0Pip_LL",
-        comb_m_min=2360 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2380 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_xicp_to_lpi_dd():
-    lambda_dd = _make_lambda_dd()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        lambda_dd,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXicpToL0Pip_DD",
-        comb_m_min=2360 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2380 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=1 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_xicp_pions = _make_verytight_pions_for_charm()
+    xicps = ParticleCombiner(
+        [dd_lambdas, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 pi+]cc",
+        name="Charm_Hyperons_XicpToL0Pip_DD",
+        CombinationCut=require_all(
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(1 * mm),
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.4 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2380 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > 0.1 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lpi_llbinc_line(name="Hlt2Charm_XicpToL0Pip_LL_Inclb_PR_Line"):
-    xic_ll = _make_detached_xicp_to_lpi_ll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xic_ll, long_b_tracks,
-                                "[Xi_b0 -> Xi_c+ pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xicps = _make_detached_xicp_to_lpi_ll(ll_lambdas,
+                                          _make_verytight_pions_for_charm(),
+                                          pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xicps,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b0 -> Xi_c+ pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xic_ll, b_to_xich],
+        algs=charm_prefilters() + [ll_lambdas, xicps, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xicp_to_lpi_ddbinc_line(name="Hlt2Charm_XicpToL0Pip_DD_Inclb_PR_Line"):
-    xic_dd = _make_detached_xicp_to_lpi_dd()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xic_dd, long_b_tracks,
-                                "[Xi_b0 -> Xi_c+ pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xicps = _make_detached_xicp_to_lpi_dd(dd_lambdas,
+                                          _make_verytight_pions_for_charm(),
+                                          pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xicps,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b0 -> Xi_c+ pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xic_dd, b_to_xich],
+        algs=charm_prefilters() + [dd_lambdas, xicps, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdm_xicp_to_lpi_ll_line(
         name="Hlt2Charm_Xib0ToXicpDm_XicpToL0Pip_DmToKpPimPim_LL_Line"):
-    xic_ll = _make_detached_xicp_to_lpi_ll()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xic_ll, dm, "[Xi_b0 -> Xi_c+ D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xic_ll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xicps = _make_detached_xicp_to_lpi_ll(ll_lambdas,
+                                          _make_verytight_pions_for_charm(),
+                                          pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, xicps, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdm_xicp_to_lpi_dd_line(
         name="Hlt2Charm_Xib0ToXicpDm_XicpToL0Pip_DmToKpPimPim_DD_Line"):
-    xic_dd = _make_detached_xicp_to_lpi_dd()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xic_dd, dm, "[Xi_b0 -> Xi_c+ D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xic_dd, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xicps = _make_detached_xicp_to_lpi_dd(dd_lambdas,
+                                          _make_verytight_pions_for_charm(),
+                                          pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, xicps, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdsm_xicp_to_lpi_ll_line(
         name="Hlt2Charm_Xib0ToXicpDsm_XicpToL0Pip_DmDsmToKmKpPim_LL_Line"):
-    xic_ll = _make_detached_xicp_to_lpi_ll()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xic_ll, dsm, "[Xi_b0 -> Xi_c+ D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xic_ll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xicps = _make_detached_xicp_to_lpi_ll(ll_lambdas,
+                                          _make_verytight_pions_for_charm(),
+                                          pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dsm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D_s-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, xicps, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdsm_xicp_to_lpi_dd_line(
         name="Hlt2Charm_Xib0ToXicpDsm_XicpToL0Pip_DmDsmToKmKpPim_DD_Line"):
-    xic_dd = _make_detached_xicp_to_lpi_dd()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xic_dd, dsm, "[Xi_b0 -> Xi_c+ D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xic_dd, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xicps = _make_detached_xicp_to_lpi_dd(dd_lambdas,
+                                          _make_verytight_pions_for_charm(),
+                                          pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dsm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D_s-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, xicps, b_to_xich])
 
 
 # Xic0 -> Xi- pi+.  Expected rate 380 Hz
 @register_line_builder(all_lines)
 def xicz_to_ximpi_lll_line(name="Hlt2Charm_Xic0ToXimPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_xicz_pions = _make_loose_pi_from_c()
-    xic0_LLL = combine_2body(
-        xi_lll,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- pi+]cc",
-        make_pvs(),
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=3.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_lll, xic0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0s = ParticleCombiner(
+        [lll_xis, _make_loose_pions_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimPip_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 3.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximpi_ddl_line(name="Hlt2Charm_Xic0ToXimPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_xicz_pions = _make_loose_pi_from_c()
-    xic0_DDL = combine_2body(
-        xi_ddl,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- pi+]cc",
-        make_pvs(),
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=3.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_ddl, xic0_DDL])
-
-
-def _make_detached_xicz_to_ximpi_lll():
-    xi_lll = _make_xi_lll()
-    long_xicz_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        xi_lll,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXic0ToXimPip_LLL",
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_xicz_to_ximpi_ddl():
-    xi_ddl = _make_xi_ddl()
-    long_xicz_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        xi_ddl,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXic0ToXimPip_DDL",
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    long_xicz_pions = _make_loose_pions_for_charm()
+    xic0s = ParticleCombiner(
+        [ddl_xis, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Xi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimPip_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 3.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximpi_lllinclb_line(
         name="Hlt2Charm_Xic0ToXimPip_LLL_Inclb_PR_Line"):
-    xicz_lll = _make_detached_xicz_to_ximpi_lll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xicz_lll, long_b_tracks,
-                                "[Xi_b- -> Xi_c0 pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximpi_lll(
+        lll_xis, _make_verytight_pions_for_charm(), pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xic0sl,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b- -> Xi_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xicz_lll, b_to_xich],
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0sl, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximpi_ddlinclb_line(
         name="Hlt2Charm_Xic0ToXimPip_DDL_Inclb_PR_Line"):
-    xicz_ddl = _make_detached_xicz_to_ximpi_ddl()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xicz_ddl, long_b_tracks,
-                                "[Xi_b- -> Xi_c0 pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximpi_ddl(
+        ddl_xis, _make_verytight_pions_for_charm(), pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xic0sl,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b- -> Xi_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xicz_ddl, b_to_xich],
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0sl, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdm_xicz_to_ximpi_lll_line(
         name="Hlt2Charm_XibmToXic0Dm_Xic0ToXimPip_DmToKpPimPim_LLL_Line"):
-    xicz_lll = _make_detached_xicz_to_ximpi_lll()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicz_lll, dm, "[Xi_b- -> Xi_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_lll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximpi_lll(
+        lll_xis, _make_verytight_pions_for_charm(), pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dm, pvs,
+                                          "[Xi_b- -> Xi_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0sl, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdm_xicz_to_ximpi_ddl_line(
         name="Hlt2Charm_XibmToXic0Dm_Xic0ToXimPip_DmToKpPimPim_DDL_Line"):
-    xicz_ddl = _make_detached_xicz_to_ximpi_ddl()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicz_ddl, dm, "[Xi_b- -> Xi_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_ddl, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximpi_ddl(
+        ddl_xis, _make_verytight_pions_for_charm(), pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dm, pvs,
+                                          "[Xi_b- -> Xi_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0sl, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdsm_xicz_to_ximpi_lll_line(
         name="Hlt2Charm_XibmToXic0Dsm_Xic0ToXimPip_DmDsmToKmKpPim_LLL_Line"):
-    xicz_lll = _make_detached_xicz_to_ximpi_lll()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicz_lll, dsm, "[Xi_b- -> Xi_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_lll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximpi_lll(
+        lll_xis, _make_verytight_pions_for_charm(), pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dsm, pvs,
+                                          "[Xi_b- -> Xi_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0sl, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdsm_xicz_to_ximpi_ddl_line(
         name="Hlt2Charm_XibmToXic0Dsm_Xic0ToXimPip_DmDsmToKmKpPim_DDL_Line"):
-    xicz_ddl = _make_detached_xicz_to_ximpi_lll()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicz_ddl, dsm, "[Xi_b- -> Xi_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_ddl, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximpi_ddl(
+        ddl_xis, _make_verytight_pions_for_charm(), pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dsm, pvs,
+                                          "[Xi_b- -> Xi_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0sl, b_to_xich])
 
 
 # Xic0 -> Xi- K+.  Expected rate 10 Hz
 @register_line_builder(all_lines)
 def xicz_to_ximk_lll_line(name="Hlt2Charm_Xic0ToXimKp_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_LLL = combine_2body(
-        xi_lll,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- K+]cc",
-        make_pvs(),
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=3.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_lll, xic0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0s = ParticleCombiner(
+        [lll_xis, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_Xic0ToXimKp_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 3.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximk_ddl_line(name="Hlt2Charm_Xic0ToXimKp_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_DDL = combine_2body(
-        xi_ddl,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- K+]cc",
-        make_pvs(),
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=3.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_ddl, xic0_DDL])
-
-
-def _make_detached_xicz_to_ximk_lll():
-    xi_lll = _make_xi_lll()
-    long_xicz_kaons = _make_verytight_k_from_c()
-    return combine_2body(
-        xi_lll,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- K+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXic0ToXimKp_LLL",
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_xicz_to_ximk_ddl():
-    xi_ddl = _make_xi_ddl()
-    long_xicz_kaons = _make_verytight_k_from_c()
-    return combine_2body(
-        xi_ddl,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- K+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXic0ToXimKp_DDL",
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0s = ParticleCombiner(
+        [ddl_xis, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_Xic0ToXimKp_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 3.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximk_lllinclb_line(name="Hlt2Charm_Xic0ToXimKp_LLL_Inclb_PR_Line"):
-    xicz_lll = _make_detached_xicz_to_ximk_lll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xicz_lll, long_b_tracks,
-                                "[Xi_b- -> Xi_c0 pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximk_lll(lll_xis,
+                                             _make_verytight_kaons_for_charm(),
+                                             pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xic0sl,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b- -> Xi_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xicz_lll, b_to_xich],
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0sl, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximk_ddlinclb_line(name="Hlt2Charm_Xic0ToXimKp_DDL_Inclb_PR_Line"):
-    xicz_ddl = _make_detached_xicz_to_ximk_lll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xicz_ddl, long_b_tracks,
-                                "[Xi_b- -> Xi_c0 pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximk_ddl(ddl_xis,
+                                             _make_verytight_kaons_for_charm(),
+                                             pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xic0sl,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b- -> Xi_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xicz_ddl, b_to_xich],
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0sl, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdm_xicz_to_ximkm_lll_line(
         name="Hlt2Charm_XibmToXic0Dm_Xic0ToXimKp_DmToKpPimPim_LLL_Line"):
-    xicz_lll = _make_detached_xicz_to_ximk_lll()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicz_lll, dm, "[Xi_b- -> Xi_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_lll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximk_lll(lll_xis,
+                                             _make_verytight_kaons_for_charm(),
+                                             pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dm, pvs,
+                                          "[Xi_b- -> Xi_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0sl, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdm_xicz_to_ximkm_ddl_line(
         name="Hlt2Charm_XibmToXic0Dm_Xic0ToXimKp_DmToKpPimPim_DDL_Line"):
-    xicz_ddl = _make_detached_xicz_to_ximk_ddl()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicz_ddl, dm, "[Xi_b- -> Xi_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_ddl, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximk_ddl(ddl_xis,
+                                             _make_verytight_kaons_for_charm(),
+                                             pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dm, pvs,
+                                          "[Xi_b- -> Xi_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0sl, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdsm_xicz_to_ximkm_lll_line(
         name="Hlt2Charm_XibmToXic0Dsm_Xic0ToXimKp_DmDsmToKmKpPim_LLL_Line"):
-    xicz_lll = _make_detached_xicz_to_ximk_lll()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicz_lll, dsm, "[Xi_b- -> Xi_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_lll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximk_lll(lll_xis,
+                                             _make_verytight_kaons_for_charm(),
+                                             pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dsm, pvs,
+                                          "[Xi_b- -> Xi_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0sl, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdsm_xicz_to_ximkm_ddl_line(
         name="Hlt2Charm_XibmToXic0Dsm_Xic0ToXimKp_DmDsmToKmKpPim_DDL_Line"):
-    xicz_ddl = _make_detached_xicz_to_ximk_ddl()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicz_ddl, dsm, "[Xi_b- -> Xi_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_ddl, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xic0sl = _make_detached_xicz_to_ximk_ddl(ddl_xis,
+                                             _make_verytight_kaons_for_charm(),
+                                             pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0sl, dsm, pvs,
+                                          "[Xi_b- -> Xi_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0sl, b_to_xich])
 
 
 # Xic0 -> Omega- K+. Expected rate 150 Hz
 @register_line_builder(all_lines)
 def xicz_to_omk_lll_line(name="Hlt2Charm_Xic0ToOmKp_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_LLL = combine_2body(
-        om_lll,
-        long_xicz_kaons,
-        "[Xi_c0 -> Omega- K+]cc",
-        make_pvs(),
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=3.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_lll, xic0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    xic0s = ParticleCombiner(
+        [lll_oms, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Omega- K+]cc",
+        name="Charm_Hyperons_Xic0ToOmKp_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 3.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_omk_ddl_line(name="Hlt2Charm_Xic0ToOmKp_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_oc_kaons = _make_std_k_from_c()
-    xic0_DDL = combine_2body(
-        om_ddl,
-        long_oc_kaons,
-        "[Xi_c0 -> Omega- K+]cc",
-        make_pvs(),
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=3.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_ddl, xic0_DDL])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    xic0s = ParticleCombiner(
+        [ddl_oms, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Omega- K+]cc",
+        name="Charm_Hyperons_Xic0ToOmKp_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 3.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, xic0s])
 
 
 # Xic0 -> L0 KS0 ; LLLL + DDLL + LLDD + DDDD combinations
 @register_line_builder(all_lines)
-def xicz_to_l0ks_llll_line(name="Hlt2Charm_Xic0ToL0Ks_LLLL_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    xic0_llll = combine_2body(
-        lambda_ll,
-        ks_ll,
-        "[Xi_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2370 * MeV,
-        comb_m_max=2570 * MeV,
-        m_min=2390 * MeV,
-        m_max=2550 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        dz2_min=1 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+def xicz_to_l0ll_kshortsll_line(name="Hlt2Charm_Xic0ToL0Ks_LLLL_Line",
+                                prescale=1):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xic0s = ParticleCombiner(
+        [ll_lambdas, _make_ll_kshorts()],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Xic0ToL0Ks_LLLL",
+        CombinationCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2390 * MeV,
+            F.MASS < 2550 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            _DZ_CHILD(2) > 1 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lambda_ll, xic0_llll],
+        algs=charm_prefilters() + [ll_lambdas, xic0s],
         prescale=prescale)
 
 
 @register_line_builder(all_lines)
-def xicz_to_l0ks_ddll_line(name="Hlt2Charm_Xic0ToL0Ks_DDLL_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    xic0_ddll = combine_2body(
-        lambda_dd,
-        ks_ll,
-        "[Xi_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2370 * MeV,
-        comb_m_max=2570 * MeV,
-        m_min=2390 * MeV,
-        m_max=2550 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=2 * mm,
-        vchi2dof_max=6.,
-        dz2_min=1 * mm,
-        bpvvdz_min=-5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+def xicz_to_l0dd_kshortsll_line(name="Hlt2Charm_Xic0ToL0Ks_DDLL_Line",
+                                prescale=1):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xic0s = ParticleCombiner(
+        [dd_lambdas, _make_ll_kshorts()],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Xic0ToL0Ks_DDLL",
+        CombinationCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.MAXDOCACUT(2 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2390 * MeV,
+            F.MASS < 2550 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(2) > 1 * mm,
+            F.BPVVDZ(pvs) > -5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lambda_dd, xic0_ddll],
+        algs=charm_prefilters() + [dd_lambdas, xic0s],
         prescale=prescale)
 
 
 @register_line_builder(all_lines)
-def xicz_to_l0ks_lldd_line(name="Hlt2Charm_Xic0ToL0Ks_LLDD_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_dd()
-    xic0_lldd = combine_2body(
-        lambda_ll,
-        ks_dd,
-        "[Xi_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2370 * MeV,
-        comb_m_max=2570 * MeV,
-        m_min=2390 * MeV,
-        m_max=2550 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=2 * mm,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=-5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+def xicz_to_l0ll_kshortsdd_line(name="Hlt2Charm_Xic0ToL0Ks_LLDD_Line",
+                                prescale=1):
+    pvs = make_pvs()
+    dd_kshorts = _make_dd_kshorts()
+    xic0s = ParticleCombiner(
+        [_make_ll_lambdas_for_charm(), dd_kshorts],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Xic0ToL0Ks_LLDD",
+        CombinationCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MAXDOCACUT(2 * mm),
+            F.MASS > 2390 * MeV,
+            F.MASS < 2550 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > -5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [ks_dd, xic0_lldd],
+        algs=charm_prefilters() + [dd_kshorts, xic0s],
         prescale=prescale)
 
 
 @register_line_builder(all_lines)
-def xicz_to_l0ks_dddd_line(name="Hlt2Charm_Xic0ToL0Ks_DDDD_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_dd = _make_lambda_dd()
-    ks_dd = _make_ks_dd()
-    xic0_dddd = combine_2body(
-        lambda_dd,
-        ks_dd,
-        "[Xi_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2370 * MeV,
-        comb_m_max=2570 * MeV,
-        m_min=2390 * MeV,
-        m_max=2550 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=5 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=-10 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+def xicz_to_l0dd_kshortsdd_line(name="Hlt2Charm_Xic0ToL0Ks_DDDD_Line",
+                                prescale=1):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xic0s = ParticleCombiner(
+        [dd_lambdas, _make_dd_kshorts()],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Xic0ToL0Ks_DDDD",
+        CombinationCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.MAXDOCACUT(5 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2390 * MeV,
+            F.MASS < 2550 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > -10 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lambda_dd, xic0_dddd],
+        algs=charm_prefilters() + [dd_lambdas, xic0s],
         prescale=prescale)
 
 
 # Omegac0 -> Xi- pi+. Expected rate 75 Hz
 @register_line_builder(all_lines)
-def oc_to_impi_lll_line(name="Hlt2Charm_Oc0ToXimPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_LLL = combine_2body(
-        xi_lll,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- pi+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=15 * GeV,
-        p_min=16 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_lll, omc0_LLL])
+def oc_to_ximpi_lll_line(name="Hlt2Charm_Oc0ToXimPip_LLL_Line"):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = ParticleCombiner(
+        [lll_xis, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimPip_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 15 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 16 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximpi_ddl_line(name="Hlt2Charm_Oc0ToXimPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_DDL = combine_2body(
-        xi_ddl,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- pi+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_ddl, omc0_DDL])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = ParticleCombiner(
+        [ddl_xis, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimPip_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, oc0s])
 
 
 # Omegac0 -> Xi- K+.  Expected rate 7.5 Hz
 @register_line_builder(all_lines)
 def oc_to_ximk_lll_line(name="Hlt2Charm_Oc0ToXimKp_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_oc_kaons = _make_std_k_from_c()
-    omc0_LLL = combine_2body(
-        xi_lll,
-        long_oc_kaons,
-        "[Omega_c0 -> Xi- K+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_lll, omc0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = ParticleCombiner(
+        [lll_xis, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_Oc0ToXimKp_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximk_ddl_line(name="Hlt2Charm_Oc0ToXimKp_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_oc_kaons = _make_std_k_from_c()
-    omc0_DDL = combine_2body(
-        xi_ddl,
-        long_oc_kaons,
-        "[Omega_c0 -> Xi- K+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_ddl, omc0_DDL])
-
-
-def _make_detached_oc_to_ximk_lll():
-    xi_lll = _make_xi_lll()
-    long_oc_kaons = _make_verytight_k_from_c()
-    return combine_2body(
-        xi_lll,
-        long_oc_kaons,
-        "[Omega_c0 -> Xi- K+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedOc0ToXimKp_LLL",
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_oc_to_ximk_ddl():
-    xi_ddl = _make_xi_ddl()
-    long_oc_kaons = _make_verytight_k_from_c()
-    return combine_2body(
-        xi_ddl,
-        long_oc_kaons,
-        "[Omega_c0 -> Xi- K+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedOc0ToXimKp_DDL",
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = ParticleCombiner(
+        [ddl_xis, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- K+]cc",
+        name="Charm_Hyperons_Oc0ToXimKp_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximk_lllinclb_line(name="Hlt2Charm_Oc0ToXimKp_LLL_Inclb_PR_Line"):
-    oc_lll = _make_detached_oc_to_ximk_lll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_och = _make_xb_to_xct(oc_lll, long_b_tracks,
-                               "[Omega_b- -> Omega_c0 pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    oc_lll = _make_detached_oc_to_ximk_lll(lll_xis,
+                                           _make_verytight_kaons_for_charm(),
+                                           pvs)
+    b_to_och = _make_bbaryon_to_cbaryonttrack(oc_lll,
+                                              _make_long_tracks_for_beauty(),
+                                              pvs,
+                                              "[Omega_b- -> Omega_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [oc_lll, b_to_och],
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, oc_lll, b_to_och],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def oc_to_ximk_ddlinclb_line(name="Hlt2Charm_Oc0ToXimKp_DDL_Inclb_PR_Line"):
-    oc_ddl = _make_detached_oc_to_ximk_ddl()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_och = _make_xb_to_xct(oc_ddl, long_b_tracks,
-                               "[Omega_b- -> Omega_c0 pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = _make_detached_oc_to_ximk_ddl(ddl_xis,
+                                         _make_verytight_kaons_for_charm(),
+                                         pvs)
+    b_to_och = _make_bbaryon_to_cbaryonttrack(oc0s,
+                                              _make_long_tracks_for_beauty(),
+                                              pvs,
+                                              "[Omega_b- -> Omega_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [oc_ddl, b_to_och],
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, oc0s, b_to_och],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdm_oc_to_ximkm_lll_line(
         name="Hlt2Charm_ObmToOc0Dm_Oc0ToXimKp_DmToKpPimPim_LLL_Line"):
-    oc_lll = _make_detached_oc_to_ximk_lll()
-    dm = _make_dminus()
-    b_to_och = _make_xb_to_xcd(oc_lll, dm, "[Omega_b- -> Omega_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_lll, b_to_och])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    oc_lll = _make_detached_oc_to_ximk_lll(lll_xis,
+                                           _make_verytight_kaons_for_charm(),
+                                           pvs)
+    b_to_och = _make_bbaryon_to_cbaryond(oc_lll, _make_d_to_kpipi(), pvs,
+                                         "[Omega_b- -> Omega_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, oc_lll, b_to_och])
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdm_oc_to_ximkm_ddl_line(
         name="Hlt2Charm_ObmToOc0Dm_Oc0ToXimKp_DmToKpPimPim_DDL_Line"):
-    oc_ddl = _make_detached_oc_to_ximk_ddl()
-    dm = _make_dminus()
-    b_to_och = _make_xb_to_xcd(oc_ddl, dm, "[Omega_b- -> Omega_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_ddl, b_to_och])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = _make_detached_oc_to_ximk_ddl(ddl_xis,
+                                         _make_verytight_kaons_for_charm(),
+                                         pvs)
+    b_to_och = _make_bbaryon_to_cbaryond(oc0s, _make_d_to_kpipi(), pvs,
+                                         "[Omega_b- -> Omega_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, oc0s, b_to_och])
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdsm_oc_to_ximkm_lll_line(
         name="Hlt2Charm_ObmToOc0Dsm_Oc0ToXimKp_DmDsmToKmKpPim_LLL_Line"):
-    oc_lll = _make_detached_oc_to_ximk_lll()
-    dsm = _make_dsminus()
-    b_to_och = _make_xb_to_xcd(oc_lll, dsm, "[Omega_b- -> Omega_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_lll, b_to_och])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    oc_lll = _make_detached_oc_to_ximk_lll(lll_xis,
+                                           _make_verytight_kaons_for_charm(),
+                                           pvs)
+    b_to_och = _make_bbaryon_to_cbaryond(oc_lll, _make_ds_to_kkpi(), pvs,
+                                         "[Omega_b- -> Omega_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, oc_lll, b_to_och])
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdsm_oc_to_ximkm_ddl_line(
         name="Hlt2Charm_ObmToOc0Dsm_Oc0ToXimKp_DmDsmToKmKpPim_DDL_Line"):
-    oc_ddl = _make_detached_oc_to_ximk_ddl()
-    dsm = _make_dsminus()
-    b_to_och = _make_xb_to_xcd(oc_ddl, dsm, "[Omega_b- -> Omega_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_ddl, b_to_och])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    oc0s = _make_detached_oc_to_ximk_ddl(ddl_xis,
+                                         _make_verytight_kaons_for_charm(),
+                                         pvs)
+    b_to_och = _make_bbaryon_to_cbaryond(oc0s, _make_ds_to_kkpi(), pvs,
+                                         "[Omega_b- -> Omega_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, oc0s, b_to_och])
 
 
 # Omegac0 -> Omega- pi+. Expected rate 140 Hz
 @register_line_builder(all_lines)
 def oc_to_ompi_lll_line(name="Hlt2Charm_Oc0ToOmPip_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_LLL = combine_2body(
-        om_lll,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- pi+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=16 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_lll, omc0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_oc_pions = _make_std_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [lll_oms, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Omega- pi+]cc",
+        name="Charm_Hyperons_Oc0ToOmPip_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 16 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ompi_ddl_line(name="Hlt2Charm_Oc0ToOmPip_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_DDL = combine_2body(
-        om_ddl,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- pi+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_ddl, omc0_DDL])
-
-
-def _make_detached_oc_to_ompi_lll():
-    om_lll = _make_omega_lll()
-    long_oc_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        om_lll,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedOc0ToOmPip_LLL",
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_oc_to_ompi_ddl():
-    om_ddl = _make_omega_ddl()
-    long_oc_pions = _make_verytight_pi_from_c()
-    return combine_2body(
-        om_ddl,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedOc0ToOmPip_DDL",
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.3 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc0s = ParticleCombiner(
+        [ddl_oms, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Omega- pi+]cc",
+        name="Charm_Hyperons_Oc0ToOmPip_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ompi_lllinclb_line(name="Hlt2Charm_Oc0ToOmPip_LLL_Inclb_PR_Line"):
-    oc_lll = _make_detached_oc_to_ompi_lll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_och = _make_xb_to_xct(oc_lll, long_b_tracks,
-                               "[Omega_b- -> Omega_c0 pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc_lll = _make_detached_oc_to_ompi_lll(lll_oms,
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    b_to_och = _make_bbaryon_to_cbaryonttrack(oc_lll,
+                                              _make_long_tracks_for_beauty(),
+                                              pvs,
+                                              "[Omega_b- -> Omega_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [oc_lll, b_to_och],
+        algs=charm_prefilters() + [ll_lambdas, lll_oms, oc_lll, b_to_och],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def oc_to_ompi_ddlinclb_line(name="Hlt2Charm_Oc0ToOmPip_DDL_Inclb_PR_Line"):
-    oc_ddl = _make_detached_oc_to_ompi_ddl()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_och = _make_xb_to_xct(oc_ddl, long_b_tracks,
-                               "[Omega_b- -> Omega_c0 pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc0s = _make_detached_oc_to_ompi_ddl(ddl_oms,
+                                         _make_verytight_pions_for_charm(),
+                                         pvs)
+    b_to_och = _make_bbaryon_to_cbaryonttrack(oc0s,
+                                              _make_long_tracks_for_beauty(),
+                                              pvs,
+                                              "[Omega_b- -> Omega_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [oc_ddl, b_to_och],
+        algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s, b_to_och],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdm_oc_to_opi_lll_line(
         name="Hlt2Charm_ObmToOc0Dm_Oc0ToOmPip_DmToKpPimPim_LLL_Line"):
-    oc_lll = _make_detached_oc_to_ompi_lll()
-    dm = _make_dminus()
-    b_to_och = _make_xb_to_xcd(oc_lll, dm, "[Omega_b- -> Omega_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_lll, b_to_och])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc_lll = _make_detached_oc_to_ompi_lll(lll_oms,
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    dm = _make_d_to_kpipi()
+    b_to_och = _make_bbaryon_to_cbaryond(oc_lll, dm, pvs,
+                                         "[Omega_b- -> Omega_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_oms, oc_lll, b_to_och])
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdm_oc_to_opi_ddl_line(
         name="Hlt2Charm_ObmToOc0Dm_Oc0ToOmPip_DmToKpPimPim_DDL_Line"):
-    oc_ddl = _make_detached_oc_to_ompi_ddl()
-    dm = _make_dminus()
-    b_to_och = _make_xb_to_xcd(oc_ddl, dm, "[Omega_b- -> Omega_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_ddl, b_to_och])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc0s = _make_detached_oc_to_ompi_ddl(ddl_oms,
+                                         _make_verytight_pions_for_charm(),
+                                         pvs)
+    dm = _make_d_to_kpipi()
+    b_to_och = _make_bbaryon_to_cbaryond(oc0s, dm, pvs,
+                                         "[Omega_b- -> Omega_c0 D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s, b_to_och])
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdsm_oc_to_opi_lll_line(
         name="Hlt2Charm_ObmToOc0Dsm_Oc0ToOmPip_DmDsmToKmKpPim_LLL_Line"):
-    oc_lll = _make_detached_oc_to_ompi_lll()
-    dsm = _make_dsminus()
-    b_to_och = _make_xb_to_xcd(oc_lll, dsm, "[Omega_b- -> Omega_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_lll, b_to_och])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc_lll = _make_detached_oc_to_ompi_lll(lll_oms,
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_och = _make_bbaryon_to_cbaryond(oc_lll, dsm, pvs,
+                                         "[Omega_b- -> Omega_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_oms, oc_lll, b_to_och])
 
 
 @register_line_builder(all_lines)
 def obm_to_ocdsm_oc_to_opi_ddl_line(
         name="Hlt2Charm_ObmToOc0Dsm_Oc0ToOmPip_DmDsmToKmKpPim_DDL_Line"):
-    oc_ddl = _make_detached_oc_to_ompi_ddl()
-    dsm = _make_dsminus()
-    b_to_och = _make_xb_to_xcd(oc_ddl, dsm, "[Omega_b- -> Omega_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [oc_ddl, b_to_och])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc0s = _make_detached_oc_to_ompi_ddl(ddl_oms,
+                                         _make_verytight_pions_for_charm(),
+                                         pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_och = _make_bbaryon_to_cbaryond(oc0s, dsm, pvs,
+                                         "[Omega_b- -> Omega_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s, b_to_och])
 
 
 # Omegac0 -> Omega- K+. Expected rate 7 Hz
 @register_line_builder(all_lines)
 def oc_to_omk_lll_line(name="Hlt2Charm_Oc0ToOmKp_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_oc_kaons = _make_tight_k_from_c()
-    omc0_LLL = combine_2body(
-        om_lll,
-        long_oc_kaons,
-        "[Omega_c0 -> Omega- K+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        doca_max=100 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_lll, omc0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc0s = ParticleCombiner(
+        [lll_oms, _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Omega- K+]cc",
+        name="Charm_Hyperons_Oc0ToOmKp_LLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(100 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_omk_ddl_line(name="Hlt2Charm_Oc0ToOmKp_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_oc_kaons = _make_tight_k_from_c()
-    omc0_DDL = combine_2body(
-        om_ddl,
-        long_oc_kaons,
-        "[Omega_c0 -> Omega- K+]cc",
-        make_pvs(),
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_ddl, omc0_DDL])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    oc0s = ParticleCombiner(
+        [ddl_oms, _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Omega- K+]cc",
+        name="Charm_Hyperons_Oc0ToOmKp_DDL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s])
 
 
 # Omegac0 -> L0 KS0 ; LLLL + DDLL + LLDD + DDDD combinations
 @register_line_builder(all_lines)
-def oc_to_l0ks_llll_line(name="Hlt2Charm_Oc0ToL0Ks_LLLL_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    oc_llll = combine_2body(
-        lambda_ll,
-        ks_ll,
-        "[Omega_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=200 * um,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        dz2_min=1 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+def oc_to_l0ll_kshortsll_line(name="Hlt2Charm_Oc0ToL0Ks_LLLL_Line",
+                              prescale=1):
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    oc0s = ParticleCombiner(
+        [ll_lambdas, _make_ll_kshorts()],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Oc0ToL0Ks_LLLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(200 * um),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            _DZ_CHILD(2) > 1 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lambda_ll, oc_llll],
+        algs=charm_prefilters() + [ll_lambdas, oc0s],
         prescale=prescale)
 
 
 @register_line_builder(all_lines)
-def oc_to_l0ks_ddll_line(name="Hlt2Charm_Oc0ToL0Ks_DDLL_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    oc_ddll = combine_2body(
-        lambda_dd,
-        ks_ll,
-        "[Omega_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=2 * mm,
-        vchi2dof_max=6.,
-        dz2_min=1 * mm,
-        bpvvdz_min=-5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+def oc_to_l0dd_kshortsll_line(name="Hlt2Charm_Oc0ToL0Ks_DDLL_Line",
+                              prescale=1):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    oc0s = ParticleCombiner(
+        [dd_lambdas, _make_ll_kshorts()],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Oc0ToL0Ks_DDLL",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(2 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(2) > 1 * mm,
+            F.BPVVDZ(pvs) > -5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lambda_dd, oc_ddll],
+        algs=charm_prefilters() + [dd_lambdas, oc0s],
         prescale=prescale)
 
 
 @register_line_builder(all_lines)
-def oc_to_l0ks_lldd_line(name="Hlt2Charm_Oc0ToL0Ks_LLDD_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_ll()
-    oc_lldd = combine_2body(
-        lambda_ll,
-        ks_dd,
-        "[Omega_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=2 * mm,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=-5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+def oc_to_l0ll_kshortsdd_line(name="Hlt2Charm_Oc0ToL0Ks_LLDD_Line",
+                              prescale=1):
+    pvs = make_pvs()
+    dd_kshorts = _make_ll_kshorts()
+    oc0s = ParticleCombiner(
+        [_make_ll_lambdas_for_charm(), dd_kshorts],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Oc0ToL0Ks_LLDD",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(2 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > -5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [ks_dd, oc_lldd],
+        algs=charm_prefilters() + [dd_kshorts, oc0s],
         prescale=prescale)
 
 
 @register_line_builder(all_lines)
-def oc_to_l0ks_dddd_line(name="Hlt2Charm_Oc0ToL0Ks_DDDD_Line", prescale=1):
-    pvs = make_pvs()
-    lambda_dd = _make_lambda_dd()
-    ks_dd = _make_ks_ll()
-    oc_dddd = combine_2body(
-        lambda_dd,
-        ks_dd,
-        "[Omega_c0 -> Lambda0 KS0]cc",
-        pvs,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=0.9 * GeV,
-        pt_min=1 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=23 * GeV,
-        p_min=24 * GeV,
-        doca_max=5 * mm,
-        vchi2dof_max=6.,
-        bpvvdz_min=-10 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+def oc_to_l0dd_kshortsdd_line(name="Hlt2Charm_Oc0ToL0Ks_DDDD_Line",
+                              prescale=1):
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    oc0s = ParticleCombiner(
+        [dd_lambdas, _make_ll_kshorts()],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0]cc",
+        name="Charm_Hyperons_Oc0ToL0Ks_DDDD",
+        CombinationCut=require_all(
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.MAXDOCACUT(5 * mm),
+            F.PT > 0.9 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 6.,
+            F.BPVVDZ(pvs) > -10 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [lambda_dd, oc_dddd],
+        algs=charm_prefilters() + [dd_lambdas, oc0s],
         prescale=prescale)
 
 
@@ -2231,1576 +2805,1789 @@ def oc_to_l0ks_dddd_line(name="Hlt2Charm_Oc0ToL0Ks_DDDD_Line", prescale=1):
 # Lc -> L KS K and partially reconstructed Lc -> Sigma0 KS K. Expected rate 1.2 kHz
 @register_line_builder(all_lines)
 def lc_to_lksk_ll_line(name="Hlt2Charm_LcpToL0KsKp_LLLL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    long_lc_kaons = _make_tight_k_from_c()
-    lc_LL = combine_3body(
-        lambda_ll,
-        ks_ll,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=1915 * MeV,
-        doca12_max=300 * um,
-        doca13_max=200 * um,
-        doca23_max=250 * um,
-        comb_m_max=2405 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    ll_kshorts = _make_ll_kshorts()
+    lcs = ParticleCombiner(
+        [ll_lambdas, ll_kshorts,
+         _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 KS0 K+]cc",
+        name="Charm_Hyperons_LcpToL0KsKp_LLLL",
+        Combination12Cut=require_all(
+            F.MASS < 1915 * MeV,
+            F.MAXDOCACUT(300 * um),
+        ),
+        CombinationCut=require_all(
+            F.MASS < 2405 * MeV,
+            F.MASS < 2385 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_ll, ks_ll, lc_LL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, ll_kshorts, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_lksk_dl_line(name="Hlt2Charm_LcpToL0KsKp_DDLL_Line"):
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    long_lc_kaons = _make_tight_k_from_c()
-    lc_DL = combine_3body(
-        lambda_dd,
-        ks_ll,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=1915 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=600 * um,
-        doca23_max=250 * um,
-        comb_m_max=2405 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ll_kshorts = _make_ll_kshorts()
+    lcs = ParticleCombiner(
+        [dd_lambdas, ll_kshorts,
+         _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 KS0 K+]cc",
+        name="Charm_Hyperons_LcpToL0KsKp_DDLL",
+        Combination12Cut=require_all(
+            F.MASS < 1915 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 600 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 2385 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_dd, ks_ll, lc_DL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ll_kshorts, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_lksk_ld_line(name="Hlt2Charm_LcpToL0KsKp_LLDD_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_dd()
-    long_lc_kaons = _make_tight_k_from_c()
-    lc_LD = combine_3body(
-        lambda_ll,
-        ks_dd,
-        long_lc_kaons,
-        "[Lambda_c+ -> Lambda0 KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=1915 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=200 * um,
-        doca23_max=800 * um,
-        comb_m_max=2405 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    dd_kshorts = _make_dd_kshorts()
+    lcs = ParticleCombiner(
+        [ll_lambdas, dd_kshorts,
+         _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 KS0 K+]cc",
+        name="Charm_Hyperons_LcpToL0KsKp_LLDD",
+        Combination12Cut=require_all(
+            F.MASS < 1915 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 800 * um,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 2385 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [ks_dd, lambda_ll, lc_LD])
+        name=name, algs=charm_prefilters() + [dd_kshorts, ll_lambdas, lcs])
 
 
 # Lc -> Xi K pi. Expected rate 500 Hz
 @register_line_builder(all_lines)
 def lc_to_ximkpi_lll_line(name="Hlt2Charm_LcpToXimKpPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_lc_pions = _make_std_pi_from_c()
-    long_lc_kaons = _make_std_k_from_c()
-    lc_LLL = combine_3body(
-        xi_lll,
-        long_lc_pions,
-        long_lc_kaons,
-        "[Lambda_c+ -> Xi- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2265 * MeV,
-        doca12_max=150 * um,
-        doca13_max=250 * um,
-        doca23_max=250 * um,
-        comb_m_min=2165 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2185 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    lcs = ParticleCombiner(
+        [lll_xis,
+         _make_std_kaons_for_charm(),
+         _make_std_pions_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Xi- K+ pi+]cc",
+        name="Charm_Hyperons_LcpToXimKpPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 250 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2165 * MeV,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2185 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, long_lc_kaons, lc_LLL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_ximkpi_ddl_line(name="Hlt2Charm_LcpToXimKpPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_lc_pions = _make_std_pi_from_c()
-    long_lc_kaons = _make_std_k_from_c()
-    lc_DDL = combine_3body(
-        xi_ddl,
-        long_lc_pions,
-        long_lc_kaons,
-        "[Lambda_c+ -> Xi- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2265 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=1.2 * mm,
-        doca23_max=400 * um,
-        comb_m_min=2165 * MeV,
-        comb_m_max=2405 * MeV,
-        m_min=2185 * MeV,
-        m_max=2385 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    lcs = ParticleCombiner(
+        [ddl_xis,
+         _make_std_kaons_for_charm(),
+         _make_std_pions_for_charm()],
+        DecayDescriptor="[Lambda_c+ -> Xi- K+ pi+]cc",
+        name="Charm_Hyperons_LcpToXimKpPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 1.2 * mm,
+            F.DOCA(2, 3) < 400 * um,
+            F.MASS > 2165 * MeV,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2185 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, long_lc_kaons, lc_DDL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, lcs])
 
 
 # Xic+ -> L KS pi and partially reconstructed Xic+ -> Sigma0 KS pi. Expected rate 2.9 kHz
 @register_line_builder(all_lines)
 def xicp_to_lkspi_ll_line(name="Hlt2Charm_XicpToL0KsPip_LLLL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    long_xicp_pions = _make_tight_pi_from_c()
-    xicp_LL = combine_3body(
-        lambda_ll,
-        ks_ll,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=300 * um,
-        doca13_max=200 * um,
-        doca23_max=250 * um,
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2280 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    ll_kshorts = _make_ll_kshorts()
+    xicps = ParticleCombiner(
+        [ll_lambdas, ll_kshorts,
+         _make_tight_pions_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 KS0 pi+]cc",
+        name="Charm_Hyperons_XicpToL0KsPip_LLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(300 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2280 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_ll, ks_ll, xicp_LL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, ll_kshorts, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lkspi_dl_line(name="Hlt2Charm_XicpToL0KsPip_DDLL_Line"):
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    long_xicp_pions = _make_tight_pi_from_c()
-    xicp_DL = combine_3body(
-        lambda_dd,
-        ks_ll,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=600 * um,
-        doca23_max=250 * um,
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2280 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=2 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ll_kshorts = _make_ll_kshorts()
+    xicps = ParticleCombiner(
+        [dd_lambdas, ll_kshorts,
+         _make_tight_pions_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 KS0 pi+]cc",
+        name="Charm_Hyperons_XicpToL0KsPip_DDLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 600 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2280 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 2 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_dd, ks_ll, xicp_DL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ll_kshorts, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lkspi_ld_line(name="Hlt2Charm_XicpToL0KsPip_LLDD_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_dd()
-    long_xicp_pions = _make_tight_pi_from_c()
-    xicp_LD = combine_3body(
-        lambda_ll,
-        ks_dd,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=200 * um,
-        doca23_max=800 * um,
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2280 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=2 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    dd_kshorts = _make_dd_kshorts()
+    xicps = ParticleCombiner(
+        [ll_lambdas, dd_kshorts,
+         _make_tight_pions_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 KS0 pi+]cc",
+        name="Charm_Hyperons_XicpToL0KsPip_LLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 800 * um,
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2280 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 2 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [ks_dd, lambda_ll, xicp_LD])
+        name=name, algs=charm_prefilters() + [dd_kshorts, ll_lambdas, xicps])
 
 
 # Xic+ -> L KS K and partially reconstructed Xic+ -> Sigma0 KS K. Expected rate 80 Hz
 @register_line_builder(all_lines)
 def xicp_to_lksk_ll_line(name="Hlt2Charm_XicpToL0KsKp_LLLL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_LL = combine_3body(
-        lambda_ll,
-        ks_ll,
-        long_xicp_kaons,
-        "[Xi_c+ -> Lambda0 KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=200 * um,
-        doca13_max=150 * um,
-        doca23_max=200 * um,
-        comb_m_min=2295 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2305 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=12.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    ll_kshorts = _make_ll_kshorts()
+    xicps = ParticleCombiner(
+        [ll_lambdas, ll_kshorts,
+         _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 KS0 K+]cc",
+        name="Charm_Hyperons_XicpToL0KsKp_LLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(200 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2295 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2305 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_ll, ks_ll, xicp_LL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, ll_kshorts, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lksk_dl_line(name="Hlt2Charm_XicpToL0KsKp_DDLL_Line"):
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_DL = combine_3body(
-        lambda_dd,
-        ks_ll,
-        long_xicp_kaons,
-        "[Xi_c+ -> Lambda0 KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=750 * um,
-        doca13_max=500 * um,
-        doca23_max=200 * um,
-        comb_m_min=2295 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2305 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=12.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ll_kshorts = _make_ll_kshorts()
+    xicps = ParticleCombiner(
+        [dd_lambdas, ll_kshorts,
+         _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 KS0 K+]cc",
+        name="Charm_Hyperons_XicpToL0KsKp_DDLL",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 500 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2295 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2305 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_dd, ks_ll, xicp_DL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ll_kshorts, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lksk_ld_line(name="Hlt2Charm_XicpToL0KsKp_LLDD_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_dd()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_LD = combine_3body(
-        lambda_ll,
-        ks_dd,
-        long_xicp_kaons,
-        "[Xi_c+ -> Lambda0 KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=750 * um,
-        doca13_max=150 * um,
-        doca23_max=500 * um,
-        comb_m_min=2295 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2305 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=12.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    dd_kshorts = _make_dd_kshorts()
+    xicps = ParticleCombiner(
+        [ll_lambdas, dd_kshorts,
+         _make_tight_kaons_for_charm()],
+        DecayDescriptor="[Xi_c+ -> Lambda0 KS0 K+]cc",
+        name="Charm_Hyperons_XicpToL0KsKp_LLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 500 * um,
+            F.MASS > 2295 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2305 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [ks_dd, lambda_ll, xicp_LD])
+        name=name, algs=charm_prefilters() + [dd_kshorts, ll_lambdas, xicps])
 
 
 # Xic+ -> Xi- pi+ pi+. Expected rate 800 Hz
 @register_line_builder(all_lines)
 def xicp_to_ximpipi_lll_line(name="Hlt2Charm_XicpToXimPipPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_LLL = combine_3body(
-        xi_lll,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c+ -> Xi- pi+ pi+]cc",
-        make_pvs(),
-        doca12_max=150 * um,
-        doca13_max=250 * um,
-        doca23_max=250 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.999)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_lll, xicp_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [lll_xis, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Xi- pi+ pi+]cc",
+        name="Charm_Hyperons_XicpToXimPipPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 250 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_ximpipi_ddl_line(name="Hlt2Charm_XicpToXimPipPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_DDL = combine_3body(
-        xi_ddl,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c+ -> Xi- pi+ pi+]cc",
-        make_pvs(),
-        doca12_max=1 * mm,
-        doca13_max=1.2 * mm,
-        doca23_max=400 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.9 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_ddl, xicp_DDL])
-
-
-def _make_detached_xicp_to_ximpipi_lll():
-    xi_lll = _make_xi_lll()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    return combine_3body(
-        xi_lll,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c+ -> Xi- pi+ pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXicpToXimPipPip_LLL",
-        comb12_m_max=2450 * MeV,
-        doca12_max=150 * um,
-        doca13_max=250 * um,
-        doca23_max=250 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_xicp_to_ximpipi_ddl():
-    xi_ddl = _make_xi_ddl()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    return combine_3body(
-        xi_ddl,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c+ -> Xi- pi+ pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXicpToXimPipPip_DDL",
-        comb12_m_max=2450 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=1.2 * mm,
-        doca23_max=400 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.9 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [ddl_xis, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Xi- pi+ pi+]cc",
+        name="Charm_Hyperons_XicpToXimPipPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 1.2 * mm,
+            F.DOCA(2, 3) < 400 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.9 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_ximpipi_lllinclb_line(
         name="Hlt2Charm_XicpToXimPipPip_LLL_Inclb_PR_Line"):
-    xic_lll = _make_detached_xicp_to_ximpipi_lll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xic_lll, long_b_tracks,
-                                "[Xi_b0 -> Xi_c+ pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = _make_detached_xicp_to_ximpipi_lll(
+        lll_xis, _make_verytight_pions_for_charm(), pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xicps,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b0 -> Xi_c+ pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xic_lll, b_to_xich],
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xicps, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xicp_to_ximpipi_ddlinclb_line(
         name="Hlt2Charm_XicpToXimPipPip_DDL_Inclb_PR_Line"):
-    xic_ddl = _make_detached_xicp_to_ximpipi_ddl()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xic_ddl, long_b_tracks,
-                                "[Xi_b0 -> Xi_c+ pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = _make_detached_xicp_to_ximpipi_ddl(
+        ddl_xis, _make_verytight_pions_for_charm(), pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xicps,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b0 -> Xi_c+ pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xic_ddl, b_to_xich],
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xicps, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdm_xicp_to_ximpipi_lll_line(
         name="Hlt2Charm_Xib0ToXicpDm_XicpToXimPipPip_DmToKpPimPim_LLL_Line"):
-    xicp_lll = _make_detached_xicp_to_ximpipi_lll()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicp_lll, dm, "[Xi_b0 -> Xi_c+ D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicp_lll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = _make_detached_xicp_to_ximpipi_lll(
+        lll_xis, _make_verytight_pions_for_charm(), pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xicps, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdm_xicp_to_ximpipi_ddl_line(
         name="Hlt2Charm_Xib0ToXicpDm_XicpToXimPipPip_DmToKpPimPim_DDL_Line"):
-    xicp_lll = _make_detached_xicp_to_ximpipi_ddl()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicp_lll, dm, "[Xi_b0 -> Xi_c+ D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicp_lll, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = _make_detached_xicp_to_ximpipi_ddl(
+        ddl_xis, _make_verytight_pions_for_charm(), pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xicps, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdsm_xicp_to_ximpipi_lll_line(
         name="Hlt2Charm_Xib0ToXicpDsm_XicpToXimPipPip_DmDsmToKmKpPim_LLL_Line"
 ):
-    xicp_lll = _make_detached_xicp_to_ximpipi_lll()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicp_lll, dsm, "[Xi_b0 -> Xi_c+ D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicp_lll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = _make_detached_xicp_to_ximpipi_lll(
+        lll_xis, _make_verytight_pions_for_charm(), pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dsm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, xicps, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibz_to_xicpdsm_xicp_to_ximpipi_ddl_line(
         name="Hlt2Charm_Xib0ToXicpDsm_XicpToXimPipPip_DmDsmToKmKpPim_DDL_Line"
 ):
-    xicp_ddl = _make_detached_xicp_to_ximpipi_ddl()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicp_ddl, dsm, "[Xi_b0 -> Xi_c+ D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicp_ddl, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = _make_detached_xicp_to_ximpipi_ddl(
+        ddl_xis, _make_verytight_pions_for_charm(), pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xicps, dsm, pvs,
+                                          "[Xi_b0 -> Xi_c+ D_s-]cc")
+    return Hlt2Line(
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, xicps, b_to_xich])
 
 
 # Xic+ -> Xi- K+ pi+. Expected rate 15 Hz
 @register_line_builder(all_lines)
 def xicp_to_ximkpi_lll_line(name="Hlt2Charm_XicpToXimKpPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_LLL = combine_3body(
-        xi_lll,
-        long_xicp_kaons,
-        long_xicp_pions,
-        "[Xi_c+ -> Xi- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=100 * um,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=12.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.999)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = ParticleCombiner(
+        [
+            lll_xis,
+            _make_tight_kaons_for_charm(),
+            _make_verytight_pions_for_charm()
+        ],
+        DecayDescriptor="[Xi_c+ -> Xi- K+ pi+]cc",
+        name="Charm_Hyperons_XicpToXimKpPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [xi_lll, long_xicp_kaons, xicp_LLL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_ximkpi_ddl_line(name="Hlt2Charm_XicpToXimKpPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_xicp_pions = _make_verytight_pi_from_c()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_DDL = combine_3body(
-        xi_ddl,
-        long_xicp_kaons,
-        long_xicp_pions,
-        "[Xi_c+ -> Xi- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=1.2 * mm,
-        doca23_max=400 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.4 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=6.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=12.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    xicps = ParticleCombiner(
+        [
+            ddl_xis,
+            _make_tight_kaons_for_charm(),
+            _make_verytight_pions_for_charm()
+        ],
+        DecayDescriptor="[Xi_c+ -> Xi- K+ pi+]cc",
+        name="Charm_Hyperons_XicpToXimKpPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 1.2 * mm,
+            F.DOCA(2, 3) < 400 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2.4 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 12.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [xi_ddl, long_xicp_kaons, xicp_DDL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, xicps])
 
 
 # Xic+ -> Omega- K+ pi+. Expected rate 75 Hz
 @register_line_builder(all_lines)
 def xicp_to_omkpi_lll_line(name="Hlt2Charm_XicpToOmKpPip_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_xicp_pions = _make_tight_pi_from_c()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_LLL = combine_3body(
-        om_lll,
-        long_xicp_kaons,
-        long_xicp_pions,
-        "[Xi_c+ -> Omega- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=100 * um,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=9.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.999)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    xicps = ParticleCombiner(
+        [
+            lll_oms,
+            _make_tight_kaons_for_charm(),
+            _make_tight_pions_for_charm()
+        ],
+        DecayDescriptor="[Xi_c+ -> Omega- K+ pi+]cc",
+        name="Charm_Hyperons_XicpToOmKpPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 9.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [om_lll, long_xicp_kaons, xicp_LLL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_omkpi_ddl_line(name="Hlt2Charm_XicpToOmKpPip_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_xicp_pions = _make_tight_pi_from_c()
-    long_xicp_kaons = _make_tight_k_from_c()
-    xicp_DDL = combine_3body(
-        om_ddl,
-        long_xicp_kaons,
-        long_xicp_pions,
-        "[Xi_c+ -> Omega- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=1.2 * mm,
-        doca23_max=400 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.4 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=6.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=9.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    xicps = ParticleCombiner(
+        [
+            ddl_oms,
+            _make_tight_kaons_for_charm(),
+            _make_tight_pions_for_charm()
+        ],
+        DecayDescriptor="[Xi_c+ -> Omega- K+ pi+]cc",
+        name="Charm_Hyperons_XicpToOmKpPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 1.2 * mm,
+            F.DOCA(2, 3) < 400 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2.4 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 6.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 9.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [om_ddl, long_xicp_kaons, xicp_DDL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, xicps])
 
 
 # Xic0 -> L pi- pi+ and partially reconstructed Xic0 -> Sigma0 pi- pi+. Expected rate 1.6 kHz
 @register_line_builder(all_lines)
 def xicz_to_lpipi_ll_line(name="Hlt2Charm_Xic0ToL0PimPip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicz_pions = _make_tight_pi_from_c()
-    xic0_LL = combine_3body(
-        lambda_ll,
-        long_xicz_pions,
-        long_xicz_pions,
-        "[Xi_c0 -> Lambda0 pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=100 * um,
-        doca13_max=100 * um,
-        doca23_max=200 * um,
-        comb_m_min=2250 * MeV,
-        comb_m_max=2590 * MeV,
-        max_mipchi2_min=9.,
-        m_min=2270 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=6.,
-        bpvdira_min=0.998)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, xic0_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_xicz_pions = _make_tight_pions_for_charm()
+    xic0s = ParticleCombiner(
+        [ll_lambdas, long_xicz_pions, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0PimPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 100 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2250 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.MAX(F.MINIPCHI2(pvs)) > 9.,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2270 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 6.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_lpipi_dd_line(name="Hlt2Charm_Xic0ToL0PimPip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_xicz_pions = _make_tight_pi_from_c()
-    xic0_DD = combine_3body(
-        lambda_dd,
-        long_xicz_pions,
-        long_xicz_pions,
-        "[Xi_c0 -> Lambda0 pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=800 * um,
-        doca13_max=800 * um,
-        doca23_max=150 * um,
-        comb_m_min=2250 * MeV,
-        comb_m_max=2590 * MeV,
-        max_mipchi2_min=9.,
-        m_min=2270 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=6.,
-        bpvdira_min=0.996)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, xic0_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_xicz_pions = _make_tight_pions_for_charm()
+    xic0s = ParticleCombiner(
+        [dd_lambdas, long_xicz_pions, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0PimPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(800 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 800 * um,
+            F.DOCA(2, 3) < 150 * um,
+            F.MASS > 2250 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAX(F.MINIPCHI2(pvs)) > 9.,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2270 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 6.,
+            F.BPVDIRA(pvs) > 0.996,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, xic0s])
 
 
 # Xic0 -> L K- pi+ and partially reconstructed Xic0 -> Sigma0 K- pi+. Expected rate 2.3 kHz
 @register_line_builder(all_lines)
 def xicz_to_lkpi_ll_line(name="Hlt2Charm_Xic0ToL0KmPip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicz_pions = _make_std_pi_from_c()
-    long_xicz_kaons = _make_tight_k_from_c()
-    xic0_LL = combine_3body(
-        lambda_ll,
-        long_xicz_kaons,
-        long_xicz_pions,
-        "[Xi_c0 -> Lambda0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=100 * um,
-        doca13_max=150 * um,
-        doca23_max=250 * um,
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        max_mipchi2_min=9.,
-        m_min=2280 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=6.,
-        bpvdira_min=0.998)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_ll, long_xicz_kaons, xic0_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_xicz_pions = _make_std_pions_for_charm()
+    long_xicz_kaons = _make_tight_kaons_for_charm()
+    xic0s = ParticleCombiner(
+        [ll_lambdas, long_xicz_kaons, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 K- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0KmPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.MAX(F.MINIPCHI2(pvs)) > 9.,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2280 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 6.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_lkpi_dd_line(name="Hlt2Charm_Xic0ToL0KmPip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_xicz_pions = _make_std_pi_from_c()
-    long_xicz_kaons = _make_tight_k_from_c()
-    xic0_DD = combine_3body(
-        lambda_dd,
-        long_xicz_kaons,
-        long_xicz_pions,
-        "[Xi_c0 -> Lambda0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=700 * um,
-        doca13_max=800 * um,
-        doca23_max=250 * um,
-        comb_m_min=2260 * MeV,
-        comb_m_max=2590 * MeV,
-        max_mipchi2_min=9.,
-        m_min=2280 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=6.,
-        bpvdira_min=0.996)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_dd, long_xicz_kaons, xic0_DD])
-
-
-def _make_detached_xicz_to_lkpi_ll():
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicz_pions = _make_verytight_pi_from_c()
-    long_xicz_kaons = _make_verytight_k_from_c()
-    return combine_3body(
-        lambda_ll,
-        long_xicz_kaons,
-        long_xicz_pions,
-        "[Xi_c0 -> Lambda0 K- pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXic0ToL0KmPip_LL",
-        comb12_m_max=2450 * MeV,
-        doca12_max=150 * um,
-        doca13_max=200 * um,
-        doca23_max=250 * um,
-        comb_m_min=2360 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2380 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=24.)
-
-
-def _make_detached_xicz_to_lkpi_dd():
-    lambda_dd = _make_lambda_dd()
-    long_xicz_pions = _make_verytight_pi_from_c()
-    long_xicz_kaons = _make_verytight_k_from_c()
-    return combine_3body(
-        lambda_dd,
-        long_xicz_kaons,
-        long_xicz_pions,
-        "[Xi_c0 -> Lambda0 K- pi+]cc",
-        pvs=make_pvs(),
-        name="Charm_Hyperons_DetachedXic0ToL0KmPip_DD",
-        comb12_m_max=2450 * MeV,
-        doca12_max=800 * um,
-        doca13_max=1 * mm,
-        doca23_max=250 * um,
-        comb_m_min=2360 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2380 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=24.)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_xicz_pions = _make_std_pions_for_charm()
+    long_xicz_kaons = _make_tight_kaons_for_charm()
+    xic0s = ParticleCombiner(
+        [dd_lambdas, long_xicz_kaons, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 K- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0KmPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(700 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 800 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2260 * MeV,
+            F.MASS < 2590 * MeV,
+            F.MAX(F.MINIPCHI2(pvs)) > 9.,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2280 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 6.,
+            F.BPVDIRA(pvs) > 0.996,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_lkpi_llinclb_line(name="Hlt2Charm_Xic0ToL0KmPip_LL_Inclb_PR_Line"):
-    xicz_ll = _make_detached_xicz_to_lkpi_ll()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xicz_ll, long_b_tracks,
-                                "[Xi_b- -> Xi_c0 pi-]cc")
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xic0s = _make_detached_xicz_to_lkpi_ll(ll_lambdas,
+                                           _make_verytight_kaons_for_charm(),
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xic0s,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b- -> Xi_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xicz_ll, b_to_xich],
+        algs=charm_prefilters() + [ll_lambdas, xic0s, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xicz_to_lkpi_ddinclb_line(name="Hlt2Charm_Xic0ToL0KmPip_DD_Inclb_PR_Line"):
-    xicz_dd = _make_detached_xicz_to_lkpi_dd()
-    long_b_tracks = _make_long_b_tracks()
-    b_to_xich = _make_xb_to_xct(xicz_dd, long_b_tracks,
-                                "[Xi_b- -> Xi_c0 pi-]cc")
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xic0s = _make_detached_xicz_to_lkpi_dd(dd_lambdas,
+                                           _make_verytight_kaons_for_charm(),
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    b_to_xich = _make_bbaryon_to_cbaryonttrack(xic0s,
+                                               _make_long_tracks_for_beauty(),
+                                               pvs, "[Xi_b- -> Xi_c0 pi-]cc")
     return Hlt2Line(
         name=name,
-        algs=charm_prefilters() + [xicz_dd, b_to_xich],
+        algs=charm_prefilters() + [dd_lambdas, xic0s, b_to_xich],
         persistreco=True)
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdm_xicz_to_lkpi_ll_line(
         name="Hlt2Charm_XibmToXic0Dm_Xic0ToL0KmPip_DmToKpPimPim_LL_Line"):
-    xicz_ll = _make_detached_xicz_to_lkpi_ll()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicz_ll, dm, "[Xi_b- -> Xi_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_ll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xic0s = _make_detached_xicz_to_lkpi_ll(ll_lambdas,
+                                           _make_verytight_kaons_for_charm(),
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0s, dm, pvs,
+                                          "[Xi_b- -> Xi_c0 D-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, xic0s, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdm_xicz_to_lkpi_dd_line(
         name="Hlt2Charm_XibmToXic0Dm_Xic0ToL0KmPip_DmToKpPimPim_DD_Line"):
-    xicz_dd = _make_detached_xicz_to_lkpi_dd()
-    dm = _make_dminus()
-    b_to_xich = _make_xb_to_xcd(xicz_dd, dm, "[Xi_b- -> Xi_c0 D-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_dd, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xic0s = _make_detached_xicz_to_lkpi_dd(dd_lambdas,
+                                           _make_verytight_kaons_for_charm(),
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    dm = _make_d_to_kpipi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0s, dm, pvs,
+                                          "[Xi_b- -> Xi_c0 D-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, xic0s, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdsm_xicz_to_lkpi_ll_line(
         name="Hlt2Charm_XibmToXic0Dsm_Xic0ToL0KmPip_DmDsmToKmKpPim_LL_Line"):
-    xicz_ll = _make_detached_xicz_to_lkpi_ll()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicz_ll, dsm, "[Xi_b- -> Xi_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_ll, b_to_xich])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    xic0s = _make_detached_xicz_to_lkpi_ll(ll_lambdas,
+                                           _make_verytight_kaons_for_charm(),
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0s, dsm, pvs,
+                                          "[Xi_b- -> Xi_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, xic0s, b_to_xich])
 
 
 @register_line_builder(all_lines)
 def xibm_to_xiczdsm_xicz_to_lkpi_dd_line(
         name="Hlt2Charm_XibmToXic0Dsm_Xic0ToL0KmPip_DmDsmToKmKpPim_DD_Line"):
-    xicz_dd = _make_detached_xicz_to_lkpi_dd()
-    dsm = _make_dsminus()
-    b_to_xich = _make_xb_to_xcd(xicz_dd, dsm, "[Xi_b- -> Xi_c0 D_s-]cc")
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xicz_dd, b_to_xich])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    xic0s = _make_detached_xicz_to_lkpi_dd(dd_lambdas,
+                                           _make_verytight_kaons_for_charm(),
+                                           _make_verytight_pions_for_charm(),
+                                           pvs)
+    dsm = _make_ds_to_kkpi()
+    b_to_xich = _make_bbaryon_to_cbaryond(xic0s, dsm, pvs,
+                                          "[Xi_b- -> Xi_c0 D_s-]cc")
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, xic0s, b_to_xich])
 
 
 # Xic0 -> L K K and partially reconstructed Xic0 -> Sigma0 K- K+. Expected rate 128 Hz
 @register_line_builder(all_lines)
 def xicz_to_lkk_ll_line(name="Hlt2Charm_Xic0ToL0KmKp_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicz_kaons = _make_tight_k_from_c()
-    xic0_LL = combine_3body(
-        lambda_ll,
-        long_xicz_kaons,
-        long_xicz_kaons,
-        "[Xi_c0 -> Lambda0 K- K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=100 * um,
-        doca13_max=100 * um,
-        doca23_max=200 * um,
-        comb_m_min=2280 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2300 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, xic0_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_xicz_kaons = _make_tight_kaons_for_charm()
+    xic0s = ParticleCombiner(
+        [ll_lambdas, long_xicz_kaons, long_xicz_kaons],
+        DecayDescriptor="[Xi_c0 -> Lambda0 K- K+]cc",
+        name="Charm_Hyperons_Xic0ToL0KmKp_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 100 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2280 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2300 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_lkk_dd_line(name="Hlt2Charm_Xic0ToL0KmKp_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_xicz_kaons = _make_tight_k_from_c()
-    xic0_DD = combine_3body(
-        lambda_dd,
-        long_xicz_kaons,
-        long_xicz_kaons,
-        "[Xi_c0 -> Lambda0 K- K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=750 * um,
-        doca13_max=750 * um,
-        doca23_max=250 * um,
-        comb_m_min=2280 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2300 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, xic0_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_xicz_kaons = _make_tight_kaons_for_charm()
+    xic0s = ParticleCombiner(
+        [dd_lambdas, long_xicz_kaons, long_xicz_kaons],
+        DecayDescriptor="[Xi_c0 -> Lambda0 K- K+]cc",
+        name="Charm_Hyperons_Xic0ToL0KmKp_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2280 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2300 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, xic0s])
 
 
 # Xic0 -> Xi KS pi. Expected rate 10 Hz
 @register_line_builder(all_lines)
 def xicz_to_ximkspi_ll_line(name="Hlt2Charm_Xic0ToXimKsPip_LLLLL_Line"):
-    xi_lll = _make_xi_lll()
-    ks_ll = _make_ks_ll()
-    long_xicz_pions = _make_std_pi_from_c()
-    xic0_LL = combine_3body(
-        xi_lll,
-        ks_ll,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=250 * um,
-        doca13_max=150 * um,
-        doca23_max=200 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    xic0s = ParticleCombiner(
+        [lll_xis, ll_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsPip_LLLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(250 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_ll, xic0_LL])
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, ll_kshorts, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximkspi_ld_line(name="Hlt2Charm_Xic0ToXimKsPip_LLLDD_Line"):
-    xi_lll = _make_xi_lll()
-    ks_dd = _make_ks_dd()
-    long_xicz_pions = _make_std_pi_from_c()
-    xic0_LD = combine_3body(
-        xi_lll,
-        ks_dd,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=150 * um,
-        doca23_max=1 * mm,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.1 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    long_xicz_pions = _make_std_pions_for_charm()
+    xic0s = ParticleCombiner(
+        [lll_xis, dd_kshorts, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsPip_LLLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 1 * mm,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_dd, xic0_LD])
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, dd_kshorts, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximkspi_dl_line(name="Hlt2Charm_Xic0ToXimKsPip_DDLLL_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_ll = _make_ks_ll()
-    long_xicz_pions = _make_std_pi_from_c()
-    xic0_DL = combine_3body(
-        xi_ddl,
-        ks_ll,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=750 * um,
-        doca13_max=750 * um,
-        doca23_max=200 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.1 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    xic0s = ParticleCombiner(
+        [ddl_xis, ll_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsPip_DDLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_ll, xic0_DL])
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, ll_kshorts, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximkspi_dd_line(name="Hlt2Charm_Xic0ToXimKsPip_DDLDD_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_dd = _make_ks_dd()
-    long_xicz_pions = _make_std_pi_from_c()
-    xic0_DD = combine_3body(
-        xi_ddl,
-        ks_dd,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2450 * MeV,
-        doca12_max=2 * mm,
-        doca13_max=750 * um,
-        doca23_max=1 * mm,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    xic0s = ParticleCombiner(
+        [ddl_xis, dd_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsPip_DDLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.MAXDOCACUT(2 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 1 * mm,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_dd, xic0_DD])
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, dd_kshorts, xic0s])
 
 
 # Xic0 -> Xi KS K. Expected rate 15 Hz
 @register_line_builder(all_lines)
 def xicz_to_ximksk_ll_line(name="Hlt2Charm_Xic0ToXimKsKp_LLLLL_Line"):
-    xi_lll = _make_xi_lll()
-    ks_ll = _make_ks_ll()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_LL = combine_3body(
-        xi_lll,
-        ks_ll,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=250 * um,
-        doca13_max=150 * um,
-        doca23_max=200 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    xic0s = ParticleCombiner(
+        [lll_xis, ll_kshorts, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 K+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsKp_LLLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(250 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_ll, xic0_LL])
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, ll_kshorts, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximksk_ld_line(name="Hlt2Charm_Xic0ToXimKsKp_LLLDD_Line"):
-    xi_lll = _make_xi_lll()
-    ks_dd = _make_ks_dd()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_LD = combine_3body(
-        xi_lll,
-        ks_dd,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=150 * um,
-        doca23_max=1 * mm,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.1 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    xic0s = ParticleCombiner(
+        [lll_xis, dd_kshorts, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 K+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsKp_LLLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 1 * mm,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_dd, xic0_LD])
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, dd_kshorts, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximksk_dl_line(name="Hlt2Charm_Xic0ToXimKsKp_DDLLL_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_ll = _make_ks_ll()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_DL = combine_3body(
-        xi_ddl,
-        ks_ll,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=750 * um,
-        doca13_max=750 * um,
-        doca23_max=200 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.1 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.993)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    long_xicz_kaons = _make_std_kaons_for_charm()
+    xic0s = ParticleCombiner(
+        [ddl_xis, ll_kshorts, long_xicz_kaons],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 K+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsKp_DDLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.993,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_ll, xic0_DL])
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, ll_kshorts, xic0s])
 
 
 @register_line_builder(all_lines)
 def xicz_to_ximksk_dd_line(name="Hlt2Charm_Xic0ToXimKsKp_DDLDD_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_dd = _make_ks_dd()
-    long_xicz_kaons = _make_std_k_from_c()
-    xic0_DD = combine_3body(
-        xi_ddl,
-        ks_dd,
-        long_xicz_kaons,
-        "[Xi_c0 -> Xi- KS0 K+]cc",
-        make_pvs(),
-        comb12_m_max=2100 * MeV,
-        doca12_max=2 * mm,
-        doca13_max=750 * um,
-        doca23_max=1 * mm,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.99)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    xic0s = ParticleCombiner(
+        [ddl_xis, dd_kshorts, _make_std_kaons_for_charm()],
+        DecayDescriptor="[Xi_c0 -> Xi- KS0 K+]cc",
+        name="Charm_Hyperons_Xic0ToXimKsKp_DDLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(2 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 1 * mm,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.99,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_dd, xic0_DD])
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, dd_kshorts, xic0s])
 
 
 # Oc -> L K- pi+ and partially reconstructed Oc -> Sigma0 K- pi+. Expected rate 450 Hz
 @register_line_builder(all_lines)
 def oc_to_lkpi_ll_line(name="Hlt2Charm_Oc0ToL0KmPip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_oc_pions = _make_tight_pi_from_c()
-    long_oc_kaons = _make_tight_k_from_c()
-    omc0_LL = combine_3body(
-        lambda_ll,
-        long_oc_kaons,
-        long_oc_pions,
-        "[Omega_c0 -> Lambda0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2675 * MeV,
-        doca12_max=100 * um,
-        doca13_max=150 * um,
-        doca23_max=250 * um,
-        comb_m_min=2470 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2490 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=1.8 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.999)
-
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_ll, long_oc_kaons, omc0_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    oc0s = ParticleCombiner(
+        [
+            ll_lambdas,
+            _make_tight_kaons_for_charm(),
+            _make_tight_pions_for_charm()
+        ],
+        DecayDescriptor="[Omega_c0 -> Lambda0 K- pi+]cc",
+        name="Charm_Hyperons_Oc0ToL0KmPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2470 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 1.8 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2490 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
+
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_lkpi_dd_line(name="Hlt2Charm_Oc0ToL0KmPip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_oc_pions = _make_tight_pi_from_c()
-    long_oc_kaons = _make_tight_k_from_c()
-    omc0_DD = combine_3body(
-        lambda_dd,
-        long_oc_kaons,
-        long_oc_pions,
-        "[Omega_c0 -> Lambda0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2675 * MeV,
-        doca12_max=700 * um,
-        doca13_max=800 * um,
-        doca23_max=250 * um,
-        comb_m_min=2470 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2490 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.998)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_dd, long_oc_kaons, omc0_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    oc0s = ParticleCombiner(
+        [
+            dd_lambdas,
+            _make_tight_kaons_for_charm(),
+            _make_tight_pions_for_charm()
+        ],
+        DecayDescriptor="[Omega_c0 -> Lambda0 K- pi+]cc",
+        name="Charm_Hyperons_Oc0ToL0KmPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.MAXDOCACUT(700 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 800 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2470 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2490 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, oc0s])
 
 
 # Oc -> L K K and partially reconstructed Oc -> Sigma0 K- K+. Expected rate 45 Hz
 @register_line_builder(all_lines)
 def oc_to_lkk_ll_line(name="Hlt2Charm_Oc0ToL0KmKp_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_oc_kaons = _make_tight_k_from_c()
-    omc0_LL = combine_3body(
-        lambda_ll,
-        long_oc_kaons,
-        long_oc_kaons,
-        "[Omega_c0 -> Lambda0 K- K+]cc",
-        make_pvs(),
-        comb12_m_max=2320 * MeV,
-        doca12_max=100 * um,
-        doca13_max=100 * um,
-        doca23_max=200 * um,
-        comb_m_min=2490 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2510 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.998)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, omc0_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_oc_kaons = _make_tight_kaons_for_charm()
+    oc0s = ParticleCombiner(
+        [ll_lambdas, long_oc_kaons, long_oc_kaons],
+        DecayDescriptor="[Omega_c0 -> Lambda0 K- K+]cc",
+        name="Charm_Hyperons_Oc0ToL0KmKp_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2320 * MeV,
+            F.MAXDOCACUT(100 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 100 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2490 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2510 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.998,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_lkk_dd_line(name="Hlt2Charm_Oc0ToL0KmKp_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_oc_kaons = _make_tight_k_from_c()
-    omc0_DD = combine_3body(
-        lambda_dd,
-        long_oc_kaons,
-        long_oc_kaons,
-        "[Omega_c0 -> Lambda0 K- K+]cc",
-        make_pvs(),
-        comb12_m_max=2320 * MeV,
-        doca12_max=750 * um,
-        doca13_max=750 * um,
-        doca23_max=250 * um,
-        comb_m_min=2490 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2510 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.996)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, omc0_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_oc_kaons = _make_tight_kaons_for_charm()
+    oc0s = ParticleCombiner(
+        [dd_lambdas, long_oc_kaons, long_oc_kaons],
+        DecayDescriptor="[Omega_c0 -> Lambda0 K- K+]cc",
+        name="Charm_Hyperons_Oc0ToL0KmKp_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2320 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 250 * um,
+            F.MASS > 2490 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2510 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.996,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, oc0s])
 
 
 # Oc -> Xi KS pi. Expected rate 140 Hz
 @register_line_builder(all_lines)
 def oc_to_ximkspi_ll_line(name="Hlt2Charm_Oc0ToXimKsPip_LLLLL_Line"):
-    xi_lll = _make_xi_lll()
-    ks_ll = _make_ks_ll()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_LL = combine_3body(
-        xi_lll,
-        ks_ll,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2675 * MeV,
-        doca12_max=250 * um,
-        doca13_max=150 * um,
-        doca23_max=200 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2 * GeV,
-        comb_p_min=17 * GeV,
-        p_min=18 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.996)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    oc0s = ParticleCombiner(
+        [lll_xis, ll_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimKsPip_LLLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.MAXDOCACUT(250 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 17 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 18 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.996,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_ll, omc0_LL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, ll_kshorts, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximkspi_ld_line(name="Hlt2Charm_Oc0ToXimKsPip_LLLDD_Line"):
-    xi_lll = _make_xi_lll()
-    ks_dd = _make_ks_dd()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_LD = combine_3body(
-        xi_lll,
-        ks_dd,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2675 * MeV,
-        doca12_max=1 * mm,
-        doca13_max=150 * um,
-        doca23_max=1 * mm,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.1 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.994)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    oc0s = ParticleCombiner(
+        [lll_xis, dd_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimKsPip_LLLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 1 * mm,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.994,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_dd, omc0_LD])
+        name=name, algs=charm_prefilters() + [ll_lambdas, dd_kshorts, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximkspi_dl_line(name="Hlt2Charm_Oc0ToXimKsPip_DDLLL_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_ll = _make_ks_ll()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_DL = combine_3body(
-        xi_ddl,
-        ks_ll,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2675 * MeV,
-        doca12_max=750 * um,
-        doca13_max=750 * um,
-        doca23_max=200 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.1 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.994)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    oc0s = ParticleCombiner(
+        [ddl_xis, ll_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimKsPip_DDLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 200 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.994,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_ll, omc0_DL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ll_kshorts, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximkspi_dd_line(name="Hlt2Charm_Oc0ToXimKsPip_DDLDD_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_dd = _make_ks_dd()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_DD = combine_3body(
-        xi_ddl,
-        ks_dd,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- KS0 pi+]cc",
-        make_pvs(),
-        comb12_m_max=2675 * MeV,
-        doca12_max=2 * mm,
-        doca13_max=750 * um,
-        doca23_max=1 * mm,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        m_min=2595 * MeV,
-        m_max=2795 * MeV,
-        comb_pt_min=1.3 * GeV,
-        pt_min=1.4 * GeV,
-        sum_pt_min=2.2 * GeV,
-        comb_p_min=19 * GeV,
-        p_min=20 * GeV,
-        vchi2dof_max=7.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.992)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    oc0s = ParticleCombiner(
+        [ddl_xis, dd_kshorts, _make_std_pions_for_charm()],
+        DecayDescriptor="[Omega_c0 -> Xi- KS0 pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimKsPip_DDLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.MAXDOCACUT(2 * mm),
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 1 * mm,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 19 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2595 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 20 * GeV,
+            F.CHI2DOF < 7.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.992,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_dd, omc0_DD])
+        name=name, algs=charm_prefilters() + [dd_lambdas, dd_kshorts, oc0s])
 
 
 ########################
@@ -3811,1096 +4598,1304 @@ def oc_to_ximkspi_dd_line(name="Hlt2Charm_Oc0ToXimKsPip_DDLDD_Line"):
 @register_line_builder(all_lines)
 def lc_to_l0pipipi_ll_line(name="Hlt2Charm_LcpToL0PimPipPip_LL_Line"):
     pvs = make_pvs()
-    lambda_ll = _make_lambda_ll_from_c()
-    long_lc_pions = _make_std_pi_from_c()
-    lc_LL = combine_4body(
-        particle1=lambda_ll,
-        particle2=long_lc_pions,
-        particle3=long_lc_pions,
-        particle4=long_lc_pions,
-        decay_descriptor="[Lambda_c+ -> Lambda0 pi- pi+ pi+]cc",
-        pvs=pvs,
-        comb12_m_max=2100 * MeV,
-        doca12_max=200 * um,
-        comb123_m_max=2240 * MeV,
-        doca13_max=250 * um,
-        doca23_max=200 * um,
-        comb_m_min=2201 * MeV,
-        comb_m_max=2371 * MeV,
-        # comb_pt_min=None, # 1.3 * GeV # Possible cuts for future tunning
-        # comb_p_min=None, # 28 * GeV # Possible cuts for future tunning
-        sum_pt_min=1.8 * GeV,
-        doca_max=250. * um,
-        docachi2_max=12.,
-        m_min=2211 * MeV,
-        m_max=2361 * MeV,
-        # pt_min=None, # 1.4 * GeV # Possible cuts for future tunning
-        # p_min=None, # 30 * GeV # Possible cuts for future tunning
-        vchi2dof_max=12.,
-        dz1_min=4 * mm,
-        # bpvvdz_min=None, # 0.25 * mm # Possible cuts for future tunning
-        bpvfdchi2_min=4.,
-        # bpvipchi2_max=None, # 10. # Possible cuts for future tunning
-        bpvdira_min=0.998,
-        bpvltime_min=0.1 * ps)
-
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_ll, lc_LL])
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_lc_pions = _make_std_pions_for_charm()
+    lcs = ParticleCombiner(
+        [ll_lambdas, long_lc_pions, long_lc_pions, long_lc_pions],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 pi- pi+ pi+]cc",
+        name="Charm_Hyperons_LcpToL0PimPipPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(200 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2240 * MeV,
+            F.DOCA(1, 3) < 250 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.MASS > 2201 * MeV,
+            F.MASS < 2371 * MeV,
+            # F.PT > None, # 1.3 * GeV # Possible cuts for future tunning
+            # F.P > None, # 28 * GeV # Possible cuts for future tunning
+            F.SUM(F.PT) > 1.8 * GeV,
+            F.MAXDOCACUT(250. * um),
+            F.MAXDOCACHI2CUT(12.),
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2211 * MeV,
+            F.MASS < 2361 * MeV,
+            # F.PT > None, # 1.4 * GeV # Possible cuts for future tunning
+            # F.P > None, # 30 * GeV # Possible cuts for future tunning
+            F.CHI2DOF < 12.,
+            _DZ_CHILD(1) > 4 * mm,
+            # F.BPVVDZ(pvs) > None, # 0.25 * mm # Possible cuts for future tunning
+            F.BPVFDCHI2(pvs) > 4.,
+            # F.BPVIPCHI2(pvs) < None, # 10. # Possible cuts for future tunning
+            F.BPVDIRA(pvs) > 0.998,
+            F.BPVLTIME(pvs) > 0.1 * ps,
+        ),
+    )
+
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_l0pipipi_dd_line(name="Hlt2Charm_LcpToL0PimPipPip_DD_Line"):
     pvs = make_pvs()
-    lambda_dd = _make_lambda_dd()
-    long_lc_pions = _make_std_pi_from_c()
-    lc_DD = combine_4body(
-        particle1=lambda_dd,
-        particle2=long_lc_pions,
-        particle3=long_lc_pions,
-        particle4=long_lc_pions,
-        decay_descriptor="[Lambda_c+ -> Lambda0 pi- pi+ pi+]cc",
-        pvs=pvs,
-        comb12_m_max=2100 * MeV,
-        doca12_max=2 * mm,
-        comb123_m_max=2240 * MeV,
-        doca13_max=2 * mm,
-        doca23_max=200 * um,
-        doca24_max=250 * um,
-        doca34_max=250 * um,
-        comb_m_min=2201 * MeV,
-        comb_m_max=2371 * MeV,
-        # comb_pt_min=None, # 1.3 * GeV # Possible cuts for future tunning
-        # comb_p_min=None, # 28 * GeV # Possible cuts for future tunning
-        sum_pt_min=1.8 * GeV,
-        doca_max=2 * mm,
-        docachi2_max=12.,
-        m_min=2211 * MeV,
-        m_max=2361 * MeV,
-        # pt_min=None, # 1.4 * GeV # Possible cuts for future tunning
-        # p_min=None, # 30 * GeV # Possible cuts for future tunning
-        vchi2dof_max=12,
-        # bpvvdz_min=None, # 0.25 * mm # Possible cuts for future tunning
-        bpvfdchi2_min=4.,
-        # bpvipchi2_max=None, # 10. # Possible cuts for future tunning
-        bpvdira_min=0.996,
-        bpvltime_min=0.1 * ps)
-
-    return Hlt2Line(name=name, algs=charm_prefilters() + [lambda_dd, lc_DD])
+    dd_lambdas = _make_dd_lambdas()
+    long_lc_pions = _make_std_pions_for_charm()
+    lcs = ParticleCombiner(
+        [dd_lambdas, long_lc_pions, long_lc_pions, long_lc_pions],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 pi- pi+ pi+]cc",
+        name="Charm_Hyperons_LcpToL0PimPipPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2100 * MeV,
+            F.MAXDOCACUT(2 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2240 * MeV,
+            F.DOCA(1, 3) < 2 * mm,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(2, 4) < 250 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2201 * MeV,
+            F.MASS < 2371 * MeV,
+            # F.PT > None, # 1.3 * GeV # Possible cuts for future tunning
+            # F.P > None, # 28 * GeV # Possible cuts for future tunning
+            F.SUM(F.PT) > 1.8 * GeV,
+            F.MAXDOCACUT(2 * mm),
+            F.MAXDOCACHI2CUT(12.),
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2211 * MeV,
+            F.MASS < 2361 * MeV,
+            # F.PT > None, # 1.4 * GeV # Possible cuts for future tunning
+            # F.P > None, # 30 * GeV # Possible cuts for future tunning
+            F.CHI2DOF < 12,
+            # F.BPVVDZ(pvs) > None, # 0.25 * mm # Possible cuts for future tunning
+            F.BPVFDCHI2(pvs) > 4.,
+            # F.BPVIPCHI2(pvs) < None, # 10. # Possible cuts for future tunning
+            F.BPVDIRA(pvs) > 0.996,
+            F.BPVLTIME(pvs) > 0.1 * ps,
+        ),
+    )
+
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, lcs])
 
 
 # Lc -> L K- K+ pi+. Expected rate 480 Hz
 @register_line_builder(all_lines)
 def lc_to_lkkpi_ll_line(name="Hlt2Charm_LcpToL0KmKpPip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_lc_kaons = _make_std_k_from_c()
-    long_lc_pions = _make_loose_pi_from_c()
-    lc_LL = combine_4body(
-        lambda_ll,
-        long_lc_kaons,
-        long_lc_kaons,
-        long_lc_pions,
-        "[Lambda_c+ -> Lambda0 K- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=1775 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2265 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_max=2405 * MeV,
-        comb_pt_min=1.1 * GeV,
-        comb_p_min=23 * GeV,
-        sum_pt_min=2 * GeV,
-        m_max=2385 * MeV,
-        pt_min=1.2 * GeV,
-        p_min=25 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_ll, long_lc_kaons, lc_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_lc_kaons = _make_std_kaons_for_charm()
+    lcs = ParticleCombiner(
+        [
+            ll_lambdas, long_lc_kaons, long_lc_kaons,
+            _make_loose_pions_for_charm()
+        ],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 K- K+ pi+]cc",
+        name="Charm_Hyperons_LcpToL0KmKpPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 1775 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.1 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 2385 * MeV,
+            F.PT > 1.2 * GeV,
+            F.P > 25 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_lkkpi_dd_line(name="Hlt2Charm_LcpToL0KmKpPip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_lc_kaons = _make_std_k_from_c()
-    long_lc_pions = _make_loose_pi_from_c()
-    lc_DD = combine_4body(
-        lambda_dd,
-        long_lc_kaons,
-        long_lc_kaons,
-        long_lc_pions,
-        "[Lambda_c+ -> Lambda0 K- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=1775 * MeV,
-        doca12_max=750 * um,
-        comb123_m_max=2265 * MeV,
-        doca13_max=750 * um,
-        doca23_max=200 * um,
-        doca14_max=800 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_max=2405 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=23 * GeV,
-        sum_pt_min=2 * GeV,
-        m_max=2385 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=24 * GeV,
-        vchi2dof_max=8.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_dd, long_lc_kaons, lc_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_lc_kaons = _make_std_kaons_for_charm()
+    lcs = ParticleCombiner(
+        [
+            dd_lambdas, long_lc_kaons, long_lc_kaons,
+            _make_loose_pions_for_charm()
+        ],
+        DecayDescriptor="[Lambda_c+ -> Lambda0 K- K+ pi+]cc",
+        name="Charm_Hyperons_LcpToL0KmKpPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 1775 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 800 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS < 2385 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 8.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, lcs])
 
 
 # Lc -> Xi KS pi pi. Expected rate 40 Hz
 @register_line_builder(all_lines)
 def lc_to_ximkspipi_ll_line(name="Hlt2Charm_LcpToXimKsPipPip_LLLLL_Line"):
-    xi_lll = _make_xi_lll()
-    ks_ll = _make_ks_ll()
-    long_lc_pions = _make_std_pi_from_c()
-    lc_LL = combine_4body(
-        xi_lll,
-        ks_ll,
-        long_lc_pions,
-        long_lc_pions,
-        "[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2125 * MeV,
-        doca12_max=250 * um,
-        comb123_m_max=2265 * MeV,
-        doca13_max=150 * um,
-        doca23_max=200 * um,
-        doca14_max=250 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2165 * MeV,
-        comb_m_max=2405 * MeV,
-        comb_pt_min=1.1 * GeV,
-        comb_p_min=23 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2185 * MeV,
-        m_max=2385 * MeV,
-        pt_min=1.2 * GeV,
-        p_min=24 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.996)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    long_lc_pions = _make_std_pions_for_charm()
+    lcs = ParticleCombiner(
+        [lll_xis, ll_kshorts, long_lc_pions, long_lc_pions],
+        DecayDescriptor="[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
+        name="Charm_Hyperons_LcpToXimKsPipPip_LLLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2125 * MeV,
+            F.MAXDOCACUT(250 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.DOCA(1, 3) < 150 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 250 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2165 * MeV,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.1 * GeV,
+            F.P > 23 * GeV,
+            F.SUM(F.PT) > 2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2185 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1.2 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.996,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_ll, lc_LL])
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, ll_kshorts, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_ximkspipi_ld_line(name="Hlt2Charm_LcpToXimKsPipPip_LLLDD_Line"):
-    xi_lll = _make_xi_lll()
-    ks_dd = _make_ks_dd()
-    long_lc_pions = _make_std_pi_from_c()
-    lc_LD = combine_4body(
-        xi_lll,
-        ks_dd,
-        long_lc_pions,
-        long_lc_pions,
-        "[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2125 * MeV,
-        doca12_max=1 * mm,
-        comb123_m_max=2265 * MeV,
-        doca13_max=200 * um,
-        doca23_max=1 * mm,
-        doca14_max=200 * um,
-        doca24_max=1 * mm,
-        doca34_max=250 * um,
-        comb_m_min=2165 * MeV,
-        comb_m_max=2405 * MeV,
-        comb_pt_min=1.2 * GeV,
-        comb_p_min=24 * GeV,
-        sum_pt_min=2.1 * GeV,
-        m_min=2185 * MeV,
-        m_max=2385 * MeV,
-        pt_min=1.3 * GeV,
-        p_min=26 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.994)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    long_lc_pions = _make_std_pions_for_charm()
+    lcs = ParticleCombiner(
+        [lll_xis, dd_kshorts, long_lc_pions, long_lc_pions],
+        DecayDescriptor="[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
+        name="Charm_Hyperons_LcpToXimKsPipPip_LLLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2125 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 1 * mm,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 1 * mm,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2165 * MeV,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.2 * GeV,
+            F.P > 24 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2185 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 26 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.994,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, ks_dd, lc_LD])
+        name=name,
+        algs=charm_prefilters() + [ll_lambdas, lll_xis, dd_kshorts, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_ximkspipi_dl_line(name="Hlt2Charm_LcpToXimKsPipPip_DDLLL_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_ll = _make_ks_ll()
-    long_lc_pions = _make_std_pi_from_c()
-    lc_DL = combine_4body(
-        xi_ddl,
-        ks_ll,
-        long_lc_pions,
-        long_lc_pions,
-        "[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2125 * MeV,
-        doca12_max=750 * um,
-        comb123_m_max=2265 * MeV,
-        doca13_max=800 * um,
-        doca23_max=200 * um,
-        doca14_max=800 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2165 * MeV,
-        comb_m_max=2405 * MeV,
-        comb_pt_min=1.2 * GeV,
-        comb_p_min=24 * GeV,
-        sum_pt_min=2.1 * GeV,
-        m_min=2185 * MeV,
-        m_max=2385 * MeV,
-        pt_min=1.3 * GeV,
-        p_min=26 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.994)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    ll_kshorts = _make_ll_kshorts()
+    long_lc_pions = _make_std_pions_for_charm()
+    lcs = ParticleCombiner(
+        [ddl_xis, ll_kshorts, long_lc_pions, long_lc_pions],
+        DecayDescriptor="[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
+        name="Charm_Hyperons_LcpToXimKsPipPip_DDLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2125 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.DOCA(1, 3) < 800 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 800 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2165 * MeV,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.2 * GeV,
+            F.P > 24 * GeV,
+            F.SUM(F.PT) > 2.1 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2185 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 26 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.994,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_ll, lc_DL])
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, ll_kshorts, lcs])
 
 
 @register_line_builder(all_lines)
 def lc_to_ximkspipi_dd_line(name="Hlt2Charm_LcpToXimKsPipPip_DDLDD_Line"):
-    xi_ddl = _make_xi_ddl()
-    ks_dd = _make_ks_dd()
-    long_lc_pions = _make_std_pi_from_c()
-    lc_DD = combine_4body(
-        xi_ddl,
-        ks_dd,
-        long_lc_pions,
-        long_lc_pions,
-        "[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2125 * MeV,
-        doca12_max=2 * mm,
-        comb123_m_max=2265 * MeV,
-        doca13_max=750 * um,
-        doca23_max=1 * mm,
-        doca14_max=750 * um,
-        doca24_max=1 * mm,
-        doca34_max=250 * um,
-        comb_m_min=2165 * MeV,
-        comb_m_max=2405 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2185 * MeV,
-        m_max=2385 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.992)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    dd_kshorts = _make_dd_kshorts()
+    long_lc_pions = _make_std_pions_for_charm()
+    lcs = ParticleCombiner(
+        [ddl_xis, dd_kshorts, long_lc_pions, long_lc_pions],
+        DecayDescriptor="[Lambda_c+ -> Xi- KS0 pi+ pi+]cc",
+        name="Charm_Hyperons_LcpToXimKsPipPip_DDLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2125 * MeV,
+            F.MAXDOCACUT(2 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2265 * MeV,
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 1 * mm,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 750 * um,
+            F.DOCA(2, 4) < 1 * mm,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2165 * MeV,
+            F.MASS < 2405 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+            F.SUM(F.PT) > 2.2 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.MASS > 2185 * MeV,
+            F.MASS < 2385 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.992,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, ks_dd, lc_DD])
+        name=name,
+        algs=charm_prefilters() + [dd_lambdas, ddl_xis, dd_kshorts, lcs])
 
 
 # Xic+ -> L K- K+ pi+ and partially reconstructed Xic+ -> Sigma0 K- K+ pi+. Expected rate 30 Hz
 @register_line_builder(all_lines)
 def xicp_to_lkkpi_ll_line(name="Hlt2Charm_XicpToL0KmKpPip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicp_kaons = _make_tight_k_from_c()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_LL = combine_4body(
-        lambda_ll,
-        long_xicp_kaons,
-        long_xicp_kaons,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 K- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=1957 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2300 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2320 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=6.,
-        bpvdira_min=0.999)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_ll, long_xicp_kaons, xicp_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_xicp_kaons = _make_tight_kaons_for_charm()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [ll_lambdas, long_xicp_kaons, long_xicp_kaons, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 K- K+ pi+]cc",
+        name="Charm_Hyperons_XicpToL0KmKpPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 1957 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2300 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2320 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 6.,
+            F.BPVDIRA(pvs) > 0.999,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lkkpi_dd_line(name="Hlt2Charm_XicpToL0KmKpPip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_xicp_kaons = _make_tight_k_from_c()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_DD = combine_4body(
-        lambda_dd,
-        long_xicp_kaons,
-        long_xicp_kaons,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 K- K+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=1957 * MeV,
-        doca12_max=750 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=750 * um,
-        doca23_max=200 * um,
-        doca14_max=800 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2300 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=23 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2320 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=24 * GeV,
-        vchi2dof_max=8.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=8.,
-        bpvipchi2_max=6.,
-        bpvdira_min=0.997)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_dd, long_xicp_kaons, xicp_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_xicp_kaons = _make_tight_kaons_for_charm()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicp_DD = ParticleCombiner(
+        [dd_lambdas, long_xicp_kaons, long_xicp_kaons, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 K- K+ pi+]cc",
+        name="Charm_Hyperons_XicpToL0KmKpPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 1957 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 800 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2300 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 23 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2320 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 8.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 8.,
+            F.BPVIPCHI2(pvs) < 6.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, xicp_DD])
 
 
 # Xic+ -> L K- pi+ pi+ and partially reconstructed Xic+ -> Sigma0 K- pi+ pi+. Expected rate 1.5 kHz
 @register_line_builder(all_lines)
 def xicp_to_lkpipi_ll_line(name="Hlt2Charm_XicpToL0KmPipPip_LL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    long_xicp_kaons = _make_std_k_from_c()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_LL = combine_4body(
-        lambda_ll,
-        long_xicp_kaons,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 K- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2270 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2290 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_ll, long_xicp_kaons, xicp_LL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    long_xicp_kaons = _make_std_kaons_for_charm()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [ll_lambdas, long_xicp_kaons, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 K- pi+ pi+]cc",
+        name="Charm_Hyperons_XicpToL0KmPipPip_LL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2270 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2290 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [ll_lambdas, xicps])
 
 
 @register_line_builder(all_lines)
 def xicp_to_lkpipi_dd_line(name="Hlt2Charm_XicpToL0KmPipPip_DD_Line"):
-    lambda_dd = _make_lambda_dd()
-    long_xicp_kaons = _make_std_k_from_c()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_DD = combine_4body(
-        lambda_dd,
-        long_xicp_kaons,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c+ -> Lambda0 K- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=750 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=750 * um,
-        doca23_max=200 * um,
-        doca14_max=800 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2270 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=23 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2290 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=24 * GeV,
-        vchi2dof_max=8.,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=6.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [lambda_dd, long_xicp_kaons, xicp_DD])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    long_xicp_kaons = _make_std_kaons_for_charm()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicp_DD = ParticleCombiner(
+        [dd_lambdas, long_xicp_kaons, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c+ -> Lambda0 K- pi+ pi+]cc",
+        name="Charm_Hyperons_XicpToL0KmPipPip_DD",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 750 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 800 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2270 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 23 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2290 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 24 * GeV,
+            F.CHI2DOF < 8.,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 6.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(name=name, algs=charm_prefilters() + [dd_lambdas, xicp_DD])
 
 
 # Xic0 -> L KS pi pi and partially reconstructed Xic0 -> Sigma0 KS pi pi. Expected rate 300 Hz
 @register_line_builder(all_lines)
 def xicz_to_lkspipi_ll_line(name="Hlt2Charm_Xic0ToL0KsPimPip_LLLL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_LL = combine_4body(
-        lambda_ll,
-        ks_ll,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c0 -> Lambda0 KS0 pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=300 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=200 * um,
-        doca23_max=250 * um,
-        doca14_max=200 * um,
-        doca24_max=250 * um,
-        doca34_max=250 * um,
-        comb_m_min=2270 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2290 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    ll_kshorts = _make_ll_kshorts()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [ll_lambdas, ll_kshorts, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0 pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0KsPimPip_LLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(300 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 250 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 250 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2270 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2290 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_ll, ks_ll, xicp_LL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, ll_kshorts, xicps])
 
 
 @register_line_builder(all_lines)
 def xicz_to_lkspipi_dl_line(name="Hlt2Charm_Xic0ToL0KsPimPip_DDLL_Line"):
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_DL = combine_4body(
-        lambda_dd,
-        ks_ll,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c0 -> Lambda0 KS0 pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=1 * mm,
-        comb123_m_max=2450 * MeV,
-        doca13_max=600 * um,
-        doca23_max=250 * um,
-        doca14_max=600 * um,
-        doca24_max=250 * um,
-        doca34_max=250 * um,
-        comb_m_min=2270 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.1 * GeV,
-        m_min=2290 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz2_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ll_kshorts = _make_ll_kshorts()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [dd_lambdas, ll_kshorts, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0 pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0KsPimPip_DDLL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 600 * um,
+            F.DOCA(2, 3) < 250 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 600 * um,
+            F.DOCA(2, 4) < 250 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2270 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.1 * GeV,
+            F.MASS > 2290 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_dd, ks_ll, xicp_DL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ll_kshorts, xicps])
 
 
 @register_line_builder(all_lines)
 def xicz_to_lkspipi_ld_line(name="Hlt2Charm_Xic0ToL0KsPimPip_LLDD_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_dd()
-    long_xicp_pions = _make_std_pi_from_c()
-    xicp_LD = combine_4body(
-        lambda_ll,
-        ks_dd,
-        long_xicp_pions,
-        long_xicp_pions,
-        "[Xi_c0 -> Lambda0 KS0 pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=1 * mm,
-        comb123_m_max=2450 * MeV,
-        doca13_max=200 * um,
-        doca23_max=800 * um,
-        doca14_max=200 * um,
-        doca24_max=800 * um,
-        doca34_max=250 * um,
-        comb_m_min=2270 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.1 * GeV,
-        m_min=2290 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    dd_kshorts = _make_dd_kshorts()
+    long_xicp_pions = _make_std_pions_for_charm()
+    xicps = ParticleCombiner(
+        [ll_lambdas, dd_kshorts, long_xicp_pions, long_xicp_pions],
+        DecayDescriptor="[Xi_c0 -> Lambda0 KS0 pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToL0KsPimPip_LLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 800 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 800 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2270 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.1 * GeV,
+            F.MASS > 2290 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [ks_dd, lambda_ll, xicp_LD])
+        name=name, algs=charm_prefilters() + [dd_kshorts, ll_lambdas, xicps])
 
 
 # Xic0 -> Xi- pi- pi+ pi+.  Expected rate 1.3 kHz
 @register_line_builder(all_lines)
 def xicz_to_xim3pi_lll_line(name="Hlt2Charm_Xic0ToXimPimPipPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_xicz_pions = _make_loose_pi_from_c()
-    xic0_LLL = combine_4body(
-        xi_lll,
-        long_xicz_pions,
-        long_xicz_pions,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- pi- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_lll, xic0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    long_xicz_pions = _make_loose_pions_for_charm()
+    xic0_LLL = ParticleCombiner(
+        [lll_xis, long_xicz_pions, long_xicz_pions, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Xi- pi- pi+ pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimPimPipPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, xic0_LLL])
 
 
 @register_line_builder(all_lines)
 def xicz_to_xim3pi_ddl_line(name="Hlt2Charm_Xic0ToXimPimPipPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_xicz_pions = _make_loose_pi_from_c()
-    xic0_DDL = combine_4body(
-        xi_ddl,
-        long_xicz_pions,
-        long_xicz_pions,
-        long_xicz_pions,
-        "[Xi_c0 -> Xi- pi- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=750 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=800 * um,
-        doca23_max=200 * um,
-        doca14_max=800 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2350 * MeV,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2370 * MeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [xi_ddl, xic0_DDL])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    long_xicz_pions = _make_loose_pions_for_charm()
+    xic0s = ParticleCombiner(
+        [ddl_xis, long_xicz_pions, long_xicz_pions, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Xi- pi- pi+ pi+]cc",
+        name="Charm_Hyperons_Xic0ToXimPimPipPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 800 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 800 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2350 * MeV,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.2 * GeV,
+            F.MASS > 2370 * MeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, xic0s])
 
 
 # Xic0 -> Omega- K+ pi- pi+. Expected rate 35 Hz
 @register_line_builder(all_lines)
 def xicz_to_omkppippim_lll_line(name="Hlt2Charm_Xic0ToOmKpPimPip_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_xicz_kaons = _make_std_k_from_c()
-    long_xicz_pions = _make_loose_pi_from_c()
-    xic0_LLL = combine_4body(
-        om_lll,
-        long_xicz_kaons,
-        long_xicz_pions,
-        long_xicz_pions,
-        "[Xi_c0 -> Omega- K+ pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=2 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_xicz_kaons = _make_std_kaons_for_charm()
+    long_xicz_pions = _make_loose_pions_for_charm()
+    xic0_LLL = ParticleCombiner(
+        [lll_oms, long_xicz_kaons, long_xicz_pions, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Omega- K+ pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToOmKpPimPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [om_lll, long_xicz_kaons, xic0_LLL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, xic0_LLL])
 
 
 @register_line_builder(all_lines)
 def xicz_to_omkppippim_ddl_line(name="Hlt2Charm_Xic0ToOmKpPimPip_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_xicz_kaons = _make_std_k_from_c()
-    long_xicz_pions = _make_loose_pi_from_c()
-    xic0_DDL = combine_4body(
-        om_ddl,
-        long_xicz_kaons,
-        long_xicz_pions,
-        long_xicz_pions,
-        "[Xi_c0 -> Omega- K+ pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2310 * MeV,
-        doca12_max=750 * um,
-        comb123_m_max=2450 * MeV,
-        doca13_max=800 * um,
-        doca23_max=200 * um,
-        doca14_max=800 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_max=2590 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_max=2570 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=2 * mm,
-        bpvvdz_min=-0.5 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_xicz_kaons = _make_std_kaons_for_charm()
+    long_xicz_pions = _make_loose_pions_for_charm()
+    xic0s = ParticleCombiner(
+        [ddl_oms, long_xicz_kaons, long_xicz_pions, long_xicz_pions],
+        DecayDescriptor="[Xi_c0 -> Omega- K+ pi- pi+]cc",
+        name="Charm_Hyperons_Xic0ToOmKpPimPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2310 * MeV,
+            F.MAXDOCACUT(750 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2450 * MeV,
+            F.DOCA(1, 3) < 800 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 800 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS < 2590 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS < 2570 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > -0.5 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name,
-        algs=charm_prefilters() + [om_ddl, long_xicz_kaons, xic0_DDL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, xic0s])
 
 
 # Oc -> L KS K- pi+ and partially reconstructed Oc -> Sigma0 KS K- pi+. Expected rate 400 Hz
 @register_line_builder(all_lines)
 def oc_to_lkskpi_ll_line(name="Hlt2Charm_Oc0ToL0KsKmPip_LLLL_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_ll = _make_ks_ll()
-    long_oc_kaons = _make_std_k_from_c()
-    long_oc_pions = _make_loose_pi_from_c()
-    omc0_LL = combine_4body(
-        lambda_ll,
-        ks_ll,
-        long_oc_kaons,
-        long_oc_pions,
-        "[Omega_c0 -> Lambda0 KS0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2182 * MeV,
-        doca12_max=300 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=200 * um,
-        doca23_max=250 * um,
-        doca14_max=200 * um,
-        doca24_max=250 * um,
-        doca34_max=250 * um,
-        comb_m_min=2470 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2490 * MeV,
-        m_max=2795 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    ll_kshorts = _make_ll_kshorts()
+    long_oc_kaons = _make_std_kaons_for_charm()
+    long_oc_pions = _make_loose_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [ll_lambdas, ll_kshorts, long_oc_kaons, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0 K- pi+]cc",
+        name="Charm_Hyperons_Oc0ToL0KsKmPip_LLLL",
+        Combination12Cut=require_all(
+            F.MASS < 2182 * MeV,
+            F.MAXDOCACUT(300 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 250 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 250 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2470 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2490 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_ll, ks_ll, omc0_LL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, ll_kshorts, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_lkskpi_dl_line(name="Hlt2Charm_Oc0ToL0KsKmPip_DDLL_Line"):
-    lambda_dd = _make_lambda_dd()
-    ks_ll = _make_ks_ll()
-    long_oc_kaons = _make_std_k_from_c()
-    long_oc_pions = _make_loose_pi_from_c()
-    omc0_DL = combine_4body(
-        lambda_dd,
-        ks_ll,
-        long_oc_kaons,
-        long_oc_pions,
-        "[Omega_c0 -> Lambda0 KS0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2182 * MeV,
-        doca12_max=1 * mm,
-        comb123_m_max=2675 * MeV,
-        doca13_max=600 * um,
-        doca23_max=250 * um,
-        doca14_max=600 * um,
-        doca24_max=250 * um,
-        doca34_max=250 * um,
-        comb_m_min=2470 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2490 * MeV,
-        m_max=2795 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz2_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.992)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ll_kshorts = _make_ll_kshorts()
+    long_oc_kaons = _make_std_kaons_for_charm()
+    long_oc_pions = _make_loose_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [dd_lambdas, ll_kshorts, long_oc_kaons, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0 K- pi+]cc",
+        name="Charm_Hyperons_Oc0ToL0KsKmPip_DDLL",
+        Combination12Cut=require_all(
+            F.MASS < 2182 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 600 * um,
+            F.DOCA(2, 3) < 250 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 600 * um,
+            F.DOCA(2, 4) < 250 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2470 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.2 * GeV,
+            F.MASS > 2490 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(2) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.992,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [lambda_dd, ks_ll, omc0_DL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ll_kshorts, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_lkskpi_ld_line(name="Hlt2Charm_Oc0ToL0KsKmPip_LLDD_Line"):
-    lambda_ll = _make_lambda_ll_from_c()
-    ks_dd = _make_ks_dd()
-    long_oc_kaons = _make_std_k_from_c()
-    long_oc_pions = _make_std_pi_from_c()
-    omc0_LD = combine_4body(
-        lambda_ll,
-        ks_dd,
-        long_oc_kaons,
-        long_oc_pions,
-        "[Omega_c0 -> Lambda0 KS0 K- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2182 * MeV,
-        doca12_max=1 * mm,
-        comb123_m_max=2675 * MeV,
-        doca13_max=200 * um,
-        doca23_max=800 * um,
-        doca14_max=200 * um,
-        doca24_max=800 * um,
-        doca34_max=250 * um,
-        comb_m_min=2470 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2490 * MeV,
-        m_max=2795 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=8 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.992)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_charm()
+    dd_kshorts = _make_dd_kshorts()
+    long_oc_kaons = _make_std_kaons_for_charm()
+    long_oc_pions = _make_std_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [ll_lambdas, dd_kshorts, long_oc_kaons, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Lambda0 KS0 K- pi+]cc",
+        name="Charm_Hyperons_Oc0ToL0KsKmPip_LLDD",
+        Combination12Cut=require_all(
+            F.MASS < 2182 * MeV,
+            F.MAXDOCACUT(1 * mm),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 800 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 800 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2470 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.2 * GeV,
+            F.MASS > 2490 * MeV,
+            F.MASS < 2795 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 8 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.992,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [ks_dd, lambda_ll, omc0_LD])
+        name=name, algs=charm_prefilters() + [dd_kshorts, ll_lambdas, oc0s])
 
 
 # Omegac0 -> Xi- K- pi+ pi+.  Expected rate 64 Hz
 @register_line_builder(all_lines)
 def oc_to_ximkpipi_lll_line(name="Hlt2Charm_Oc0ToXimKmPipPip_LLL_Line"):
-    xi_lll = _make_xi_lll()
-    long_oc_kaons = _make_std_k_from_c()
-    long_oc_pions = _make_loose_pi_from_c()
-    omc0_LLL = combine_4body(
-        xi_lll,
-        long_oc_kaons,
-        long_oc_pions,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- K- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2535 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2595 * MeV,
-        m_max=275 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_xis = _make_lll_xis(ll_lambdas, _make_long_pions_for_xi(), pvs)
+    long_oc_kaons = _make_std_kaons_for_charm()
+    long_oc_pions = _make_loose_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [lll_xis, long_oc_kaons, long_oc_pions, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Xi- K- pi+ pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimKmPipPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2535 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2595 * MeV,
+            F.MASS < 275 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_lll, long_oc_kaons, omc0_LLL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_xis, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_ximkpipi_ddl_line(name="Hlt2Charm_Oc0ToXimKmPipPip_DDL_Line"):
-    xi_ddl = _make_xi_ddl()
-    long_oc_kaons = _make_std_k_from_c()
-    long_oc_pions = _make_loose_pi_from_c()
-    omc0_DDL = combine_4body(
-        xi_ddl,
-        long_oc_kaons,
-        long_oc_pions,
-        long_oc_pions,
-        "[Omega_c0 -> Xi- K- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2535 * MeV,
-        doca12_max=800 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=1 * mm,
-        doca23_max=200 * um,
-        doca14_max=1 * mm,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2595 * MeV,
-        m_max=275 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=4 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_xis = _make_ddl_xis(dd_lambdas, _make_long_pions_for_xi(), pvs)
+    long_oc_kaons = _make_std_kaons_for_charm()
+    long_oc_pions = _make_loose_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [ddl_xis, long_oc_kaons, long_oc_pions, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Xi- K- pi+ pi+]cc",
+        name="Charm_Hyperons_Oc0ToXimKmPipPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2535 * MeV,
+            F.MAXDOCACUT(800 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 1 * mm,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 1 * mm,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.2 * GeV,
+            F.MASS > 2595 * MeV,
+            F.MASS < 275 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 4 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [xi_ddl, long_oc_kaons, omc0_DDL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_xis, oc0s])
 
 
 # Oc -> Omega- pi- pi+ pi+.  Expected rate 42 Hz
 @register_line_builder(all_lines)
 def oc_to_om3pi_lll_line(name="Hlt2Charm_Oc0ToOmPimPipPip_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_oc_pions = _make_loose_pi_from_c()
-    omc0_LLL = combine_4body(
-        om_lll,
-        long_oc_pions,
-        long_oc_pions,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- pi- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2515 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2595 * MeV,
-        m_max=275 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_lll, omc0_LLL])
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_oc_pions = _make_loose_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [lll_oms, long_oc_pions, long_oc_pions, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Omega- pi- pi+ pi+]cc",
+        name="Charm_Hyperons_Oc0ToOmPimPipPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2515 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2595 * MeV,
+            F.MASS < 275 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_om3pi_ddl_line(name="Hlt2Charm_Oc0ToOmPimPipPip_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_oc_pions = _make_loose_pi_from_c()
-    omc0_DDL = combine_4body(
-        om_ddl,
-        long_oc_pions,
-        long_oc_pions,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- pi- pi+ pi+]cc",
-        make_pvs(),
-        comb12_m_max=2515 * MeV,
-        doca12_max=800 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=1 * mm,
-        doca23_max=200 * um,
-        doca14_max=1 * mm,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2595 * MeV,
-        m_max=275 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
-    return Hlt2Line(name=name, algs=charm_prefilters() + [om_ddl, omc0_DDL])
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_oc_pions = _make_loose_pions_for_charm()
+    oc0s = ParticleCombiner(
+        [ddl_oms, long_oc_pions, long_oc_pions, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Omega- pi- pi+ pi+]cc",
+        name="Charm_Hyperons_Oc0ToOmPimPipPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2515 * MeV,
+            F.MAXDOCACUT(800 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 1 * mm,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 1 * mm,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.2 * GeV,
+            F.MASS > 2595 * MeV,
+            F.MASS < 275 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
+    return Hlt2Line(
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s])
 
 
 # Oc -> Omega- K+ pi- pi+.  Expected rate 7 Hz
 @register_line_builder(all_lines)
 def oc_to_omkppipi_lll_line(name="Hlt2Charm_Oc0ToOmKpPimPip_LLL_Line"):
-    om_lll = _make_omega_lll()
-    long_oc_pions = _make_loose_pi_from_c()
-    long_oc_kaons = _make_std_k_from_c()
-    omc0_LLL = combine_4body(
-        om_lll,
-        long_oc_kaons,
-        long_oc_pions,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- K+ pi- pi+ ]cc",
-        make_pvs(),
-        comb12_m_max=2515 * MeV,
-        doca12_max=150 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=200 * um,
-        doca23_max=200 * um,
-        doca14_max=200 * um,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2 * GeV,
-        m_min=2595 * MeV,
-        m_max=275 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.997)
+    pvs = make_pvs()
+    ll_lambdas = _make_ll_lambdas_for_hyperon()
+    lll_oms = _make_lll_omegas(ll_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_oc_pions = _make_loose_pions_for_charm()
+    long_oc_kaons = _make_std_kaons_for_charm()
+    oc0s = ParticleCombiner(
+        [lll_oms, long_oc_kaons, long_oc_pions, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Omega- K+ pi- pi+ ]cc",
+        name="Charm_Hyperons_Oc0ToOmKpPimPip_LLL",
+        Combination12Cut=require_all(
+            F.MASS < 2515 * MeV,
+            F.MAXDOCACUT(150 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 200 * um,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 200 * um,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2 * GeV,
+            F.MASS > 2595 * MeV,
+            F.MASS < 275 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.997,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [om_lll, long_oc_kaons, omc0_LLL])
+        name=name, algs=charm_prefilters() + [ll_lambdas, lll_oms, oc0s])
 
 
 @register_line_builder(all_lines)
 def oc_to_omkppipi_ddl_line(name="Hlt2Charm_Oc0ToOmKpPimPip_DDL_Line"):
-    om_ddl = _make_omega_ddl()
-    long_oc_pions = _make_loose_pi_from_c()
-    long_oc_kaons = _make_std_k_from_c()
-    omc0_DDL = combine_4body(
-        om_ddl,
-        long_oc_kaons,
-        long_oc_pions,
-        long_oc_pions,
-        "[Omega_c0 -> Omega- K+ pi- pi+]cc",
-        make_pvs(),
-        comb12_m_max=2515 * MeV,
-        doca12_max=800 * um,
-        comb123_m_max=2675 * MeV,
-        doca13_max=1 * mm,
-        doca23_max=200 * um,
-        doca14_max=1 * mm,
-        doca24_max=200 * um,
-        doca34_max=250 * um,
-        comb_m_min=2575 * MeV,
-        comb_m_max=2815 * MeV,
-        comb_pt_min=1.3 * GeV,
-        comb_p_min=28 * GeV,
-        sum_pt_min=2.2 * GeV,
-        m_min=2595 * MeV,
-        m_max=275 * MeV,
-        pt_min=1.4 * GeV,
-        p_min=30 * GeV,
-        vchi2dof_max=8.,
-        dz1_min=2 * mm,
-        bpvvdz_min=0 * mm,
-        bpvfdchi2_min=4.,
-        bpvipchi2_max=9.,
-        bpvdira_min=0.995)
+    pvs = make_pvs()
+    dd_lambdas = _make_dd_lambdas()
+    ddl_oms = _make_ddl_omegas(dd_lambdas, _make_long_kaons_for_omega(), pvs)
+    long_oc_pions = _make_loose_pions_for_charm()
+    long_oc_kaons = _make_std_kaons_for_charm()
+    oc0s = ParticleCombiner(
+        [ddl_oms, long_oc_kaons, long_oc_pions, long_oc_pions],
+        DecayDescriptor="[Omega_c0 -> Omega- K+ pi- pi+]cc",
+        name="Charm_Hyperons_Oc0ToOmKpPimPip_DDL",
+        Combination12Cut=require_all(
+            F.MASS < 2515 * MeV,
+            F.MAXDOCACUT(800 * um),
+        ),
+        Combination123Cut=require_all(
+            F.MASS < 2675 * MeV,
+            F.DOCA(1, 3) < 1 * mm,
+            F.DOCA(2, 3) < 200 * um,
+        ),
+        CombinationCut=require_all(
+            F.DOCA(1, 4) < 1 * mm,
+            F.DOCA(2, 4) < 200 * um,
+            F.DOCA(3, 4) < 250 * um,
+            F.MASS > 2575 * MeV,
+            F.MASS < 2815 * MeV,
+            F.PT > 1.3 * GeV,
+            F.P > 28 * GeV,
+        ),
+        CompositeCut=require_all(
+            F.SUM(F.PT) > 2.2 * GeV,
+            F.MASS > 2595 * MeV,
+            F.MASS < 275 * MeV,
+            F.PT > 1.4 * GeV,
+            F.P > 30 * GeV,
+            F.CHI2DOF < 8.,
+            _DZ_CHILD(1) > 2 * mm,
+            F.BPVVDZ(pvs) > 0 * mm,
+            F.BPVFDCHI2(pvs) > 4.,
+            F.BPVIPCHI2(pvs) < 9.,
+            F.BPVDIRA(pvs) > 0.995,
+        ),
+    )
     return Hlt2Line(
-        name=name, algs=charm_prefilters() + [om_ddl, long_oc_kaons, omc0_DDL])
+        name=name, algs=charm_prefilters() + [dd_lambdas, ddl_oms, oc0s])