diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h
index 5a07aec0b3a51ede12c83e920784befa275713c7..7d47e60c7d9d0b470d2ed023b85da2aa596c65fc 100644
--- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h
+++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithmsDict.h
@@ -17,6 +17,7 @@
 #include <AsgAnalysisAlgorithms/AsgLeptonTrackSelectionAlg.h>
 #include <AsgAnalysisAlgorithms/AsgOriginalObjectLinkAlg.h>
 #include <AsgAnalysisAlgorithms/AsgSelectionAlg.h>
+#include <AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h>
 #include <AsgAnalysisAlgorithms/AsgViewFromSelectionAlg.h>
 #include <AsgAnalysisAlgorithms/AsgxAODNTupleMakerAlg.h>
 #include <AsgAnalysisAlgorithms/EventFlagSelectionAlg.h>
diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..40e4c81c23c2706f51a46c31b06659980a56e817
--- /dev/null
+++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// @author Tadej Novak
+
+#ifndef ASG_ANALYSIS_ALGORITHMS__UNION_SELECTION_ALG_H
+#define ASG_ANALYSIS_ALGORITHMS__UNION_SELECTION_ALG_H
+
+#include <AnaAlgorithm/AnaAlgorithm.h>
+#include <SelectionHelpers/SysReadSelectionHandle.h>
+#include <SelectionHelpers/ISelectionWriteAccessor.h>
+#include <SystematicsHandles/SysReadHandle.h>
+#include <SystematicsHandles/SysListHandle.h>
+#include <xAODBase/IParticleContainer.h>
+
+
+namespace CP
+{
+  /// \brief an algorithm for selection an union of objects that pass
+  /// at least one systematics
+
+  class AsgUnionSelectionAlg final : public EL::AnaAlgorithm
+  {
+    /// \brief the standard constructor
+  public:
+    AsgUnionSelectionAlg (const std::string& name,
+                          ISvcLocator* pSvcLocator);
+
+
+  public:
+    virtual StatusCode initialize () override;
+
+  public:
+    virtual StatusCode execute () override;
+    
+
+
+    /// \brief the systematics list we run and have containers
+  private:
+    SysListHandle m_systematicsList {this};
+
+    /// \brief the particle continer we run on
+  private:
+    SysReadHandle<xAOD::IParticleContainer> m_particlesHandle {
+      this, "particles", "", "the asg collection to run on"};
+
+    /// \brief the preselection we apply to our input
+  private:
+    SysReadSelectionHandle m_preselection {
+      this, "preselection", "", "the preselection to apply"};
+
+    /// \brief the decoration of the selection
+  private:
+    std::string m_selectionDecoration;
+
+    /// \brief the accessor for \ref m_selectionDecoration
+  private:
+    std::unique_ptr<ISelectionWriteAccessor> m_selectionAccessor;
+  };
+
+} // namespace CP
+
+#endif
diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml
index f50c3eacb3577567ba96b066bae1484eba746e64..10eea8a1ab7e2819aef7fbfe5fd410deda1385b0 100644
--- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml
+++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/AsgAnalysisAlgorithms/selection.xml
@@ -10,6 +10,7 @@
    <class name="CP::AsgLeptonTrackSelectionAlg" />
    <class name="CP::AsgOriginalObjectLinkAlg" />
    <class name="CP::AsgSelectionAlg" />
+   <class name="CP::AsgUnionSelectionAlg" />
    <class name="CP::AsgViewFromSelectionAlg" />
    <class name="CP::AsgxAODNTupleMakerAlg" />
    <class name="CP::EventFlagSelectionAlg" />
diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx
index b169e0218ff99e9df24a6bfff0c7d1e57151c53a..d62c1c6b59cff1abbf51405119d4b1d84c260b02 100644
--- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx
+++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgSelectionAlg.cxx
@@ -34,21 +34,27 @@ namespace CP
   StatusCode AsgSelectionAlg ::
   initialize ()
   {
-    ANA_CHECK (m_selectionTool.retrieve());
-    m_systematicsTool = dynamic_cast<ISystematicsTool*>(&*m_selectionTool);
-    if (m_systematicsTool)
-      ANA_CHECK (m_systematicsList.addSystematics (*m_systematicsTool));
+    if (!m_selectionTool.empty())
+    {
+      ANA_CHECK (m_selectionTool.retrieve());
+      m_systematicsTool = dynamic_cast<ISystematicsTool*>(&*m_selectionTool);
+      if (m_systematicsTool)
+        ANA_CHECK (m_systematicsList.addSystematics (*m_systematicsTool));
+    }
       
     ANA_CHECK (m_particlesHandle.initialize (m_systematicsList));
     ANA_CHECK (m_preselection.initialize (m_systematicsList, m_particlesHandle, SG::AllowEmpty));
     ANA_CHECK (m_selectionHandle.initialize (m_systematicsList, m_particlesHandle));
     ANA_CHECK (m_systematicsList.initialize());
 
-    Root::TAccept blankAccept = m_selectionTool->getTAccept();
-    // Just in case this isn't initially set up as a failure clear it this one
-    // time. This only calls reset on the bitset
-    blankAccept.clear();
-    m_setOnFail = selectionFromAccept(blankAccept);
+    if (!m_selectionTool.empty())
+    {
+      Root::TAccept blankAccept = m_selectionTool->getTAccept();
+      // Just in case this isn't initially set up as a failure clear it this one
+      // time. This only calls reset on the bitset
+      blankAccept.clear();
+      m_setOnFail = selectionFromAccept(blankAccept);
+    }
 
     return StatusCode::SUCCESS;
   }
@@ -69,12 +75,26 @@ namespace CP
       {
         if (m_preselection.getBool (*particle, sys))
         {
-          m_selectionHandle.setBits
-            (*particle, selectionFromAccept (m_selectionTool->accept (particle)), sys);
+          if (!m_selectionTool.empty())
+          {
+            m_selectionHandle.setBits
+              (*particle, selectionFromAccept (m_selectionTool->accept (particle)), sys);
+          }
+          else
+          {
+            m_selectionHandle.setBool (*particle, true, sys);
+          }
         }
         else
         {
-          m_selectionHandle.setBits(*particle, m_setOnFail, sys);
+          if (!m_selectionTool.empty())
+          {
+            m_selectionHandle.setBits (*particle, m_setOnFail, sys);
+          }
+          else
+          {
+            m_selectionHandle.setBool (*particle, false, sys);
+          }
         }
       }
     }
diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgUnionSelectionAlg.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgUnionSelectionAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fea42a4f2f0d919dd46d86dfa7f750eb4f9254c9
--- /dev/null
+++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/Root/AsgUnionSelectionAlg.cxx
@@ -0,0 +1,94 @@
+/*
+  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+*/
+
+/// @author Tadej Novak
+
+//
+// includes
+//
+
+#include <AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h>
+
+#include <xAODBase/IParticle.h>
+
+//
+// method implementations
+//
+
+namespace CP
+{
+  AsgUnionSelectionAlg ::
+  AsgUnionSelectionAlg (const std::string& name, 
+                        ISvcLocator* pSvcLocator)
+    : AnaAlgorithm (name, pSvcLocator)
+  {
+    declareProperty ("selectionDecoration", m_selectionDecoration, "the decoration for the union selection");
+  }
+
+
+
+  StatusCode AsgUnionSelectionAlg ::
+  initialize ()
+  {
+    if (m_selectionDecoration.empty())
+    {
+      ANA_MSG_ERROR("Selection decoration can not be empty.");
+      return StatusCode::FAILURE;
+    }
+
+    ANA_CHECK (makeSelectionWriteAccessor (m_selectionDecoration, m_selectionAccessor));
+
+    ANA_CHECK (m_particlesHandle.initialize(m_systematicsList));
+    ANA_CHECK (m_preselection.initialize (m_systematicsList, m_particlesHandle));
+    ANA_CHECK (m_systematicsList.initialize());
+
+    return StatusCode::SUCCESS;
+  }
+
+
+
+  StatusCode AsgUnionSelectionAlg ::
+  execute ()
+  {
+    std::vector<bool> selections;
+
+    // first loop through systematics and define if particle passes each of them
+    for (const auto& sys : m_systematicsList.systematicsVector())
+    {
+      const xAOD::IParticleContainer *particles{};
+      ANA_CHECK (m_particlesHandle.retrieve (particles, sys));
+
+      if (selections.empty())
+      {
+        selections.resize(particles->size(), false);
+      }
+      else if (selections.size() != particles->size())
+      {
+        ANA_MSG_ERROR("All input containers should have the same size.");
+        return StatusCode::FAILURE;
+      }
+
+      for (size_t i{}; i < particles->size(); i++)
+      {
+        selections[i] = selections[i] || m_preselection.getBool (*particles->at(i), sys);
+      }
+    }
+
+    // Now decorate the selection decoration
+    // Looping over systematics is needed to ensure all containers are processed
+    for (const auto& sys : m_systematicsList.systematicsVector())
+    {
+      const xAOD::IParticleContainer *particles{};
+      ANA_CHECK (m_particlesHandle.retrieve (particles, sys));
+
+      for (size_t i{}; i < particles->size(); i++)
+      {
+        m_selectionAccessor->setBool (*particles->at(i), selections[i]);
+      }
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+} // namespace CP
diff --git a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx
index 95d84cf630e7f78a2107fb57d122767344e1a092..955469e857145ea341503afbe10f32276f0638d9 100644
--- a/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx
+++ b/PhysicsAnalysis/Algorithms/AsgAnalysisAlgorithms/src/components/AsgAnalysisAlgorithms_entries.cxx
@@ -16,6 +16,7 @@
 #include <AsgAnalysisAlgorithms/AsgLeptonTrackSelectionAlg.h>
 #include <AsgAnalysisAlgorithms/AsgOriginalObjectLinkAlg.h>
 #include <AsgAnalysisAlgorithms/AsgSelectionAlg.h>
+#include <AsgAnalysisAlgorithms/AsgUnionSelectionAlg.h>
 #include <AsgAnalysisAlgorithms/AsgViewFromSelectionAlg.h>
 #include <AsgAnalysisAlgorithms/AsgxAODNTupleMakerAlg.h>
 #include <AsgAnalysisAlgorithms/EventFlagSelectionAlg.h>
@@ -40,6 +41,7 @@ DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgEventScaleFactorAlg)
 DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgLeptonTrackSelectionAlg)
 DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgOriginalObjectLinkAlg)
 DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgSelectionAlg)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgUnionSelectionAlg)
 DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgViewFromSelectionAlg)
 DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, AsgxAODNTupleMakerAlg)
 DECLARE_NAMESPACE_ALGORITHM_FACTORY (CP, EventFlagSelectionAlg)
@@ -64,6 +66,7 @@ DECLARE_FACTORY_ENTRIES(AsgAnalysisAlgorithms) {
   DECLARE_NAMESPACE_ALGORITHM (CP, AsgLeptonTrackSelectionAlg)
   DECLARE_NAMESPACE_ALGORITHM (CP, AsgOriginalObjectLinkAlg)
   DECLARE_NAMESPACE_ALGORITHM (CP, AsgSelectionAlg)
+  DECLARE_NAMESPACE_ALGORITHM (CP, AsgUnionSelectionAlg)
   DECLARE_NAMESPACE_ALGORITHM (CP, AsgViewFromSelectionAlg)
   DECLARE_NAMESPACE_ALGORITHM (CP, AsgxAODNTupleMakerAlg)
   DECLARE_NAMESPACE_ALGORITHM (CP, EventFlagSelectionAlg)
diff --git a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py
index 13adb4d6b4edcc92c086fbe7a08ac0e2723c058e..3beeab478d75600470004691aa0779bcffdf70ca 100644
--- a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py
+++ b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/ElectronAnalysisSequence.py
@@ -290,7 +290,6 @@ def makeElectronWorkingPointSequence( seq, dataType, workingPoint,
     # Set up an algorithm used for decorating baseline electron selection:
     alg = createAlgorithm( 'CP::AsgSelectionAlg',
                            'ElectronSelectionSummary' + postfix )
-    addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' )
     alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char'
     seq.append( alg, inputPropName = 'particles',
                 stageName = 'selection',
diff --git a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py
index a133f1d81ad0371cee5e55155ab4b6707a7581a9..cdf64109444183846d55c1dc6fcbf72320f50279 100644
--- a/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py
+++ b/PhysicsAnalysis/Algorithms/EgammaAnalysisAlgorithms/python/PhotonAnalysisSequence.py
@@ -287,7 +287,6 @@ def makePhotonWorkingPointSequence( seq, dataType, workingPoint, postfix = '',
     # Set up an algorithm used for decorating baseline photon selection:
     alg = createAlgorithm( 'CP::AsgSelectionAlg',
                            'PhotonSelectionSummary' + postfix )
-    addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' )
     alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char'
     seq.append( alg, inputPropName = 'particles',
                 stageName = 'selection',
diff --git a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py
index 423f5d3b9d278225fb4e2f851ecd4f48165befcd..8d1f64b419fb025bbf2bdb6e84d98871bf98de44 100644
--- a/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py
+++ b/PhysicsAnalysis/Algorithms/MuonAnalysisAlgorithms/python/MuonAnalysisSequence.py
@@ -239,7 +239,6 @@ def makeMuonWorkingPointSequence( seq, dataType, workingPoint, postfix = '',
     # Set up an algorithm used for decorating baseline muon selection:
     alg = createAlgorithm( 'CP::AsgSelectionAlg',
                            'MuonSelectionSummary' + postfix )
-    addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' )
     alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char'
     seq.append( alg, inputPropName = 'particles',
                 stageName = 'selection',
diff --git a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py
index 7c970a84cce4cf3911e9f920c2a91190dd1f1d89..8b328b90c94e46d4c8b4415bb69fd7764189a052 100644
--- a/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py
+++ b/PhysicsAnalysis/Algorithms/TauAnalysisAlgorithms/python/TauAnalysisSequence.py
@@ -178,10 +178,9 @@ def makeTauWorkingPointSequence( seq, dataType, workingPoint, postfix = '',
     # Set up an algorithm used for decorating baseline tau selection:
     alg = createAlgorithm( 'CP::AsgSelectionAlg',
                            'TauSelectionSummary' + postfix )
-    addPrivateTool( alg, 'selectionTool', 'CP::AsgFlagSelectionTool' )
     alg.selectionDecoration = 'baselineSelection' + postfix + ',as_char'
     seq.append( alg, inputPropName = 'particles',
                 stageName = 'selection',
-                dynConfig = {'selectionTool.selectionFlags' : lambda meta : meta["selectionDecorNames"][:]} )
+                dynConfig = {'preselection' : lambda meta : "&&".join (meta["selectionDecorNames"])} )
 
     pass