From 5510e31e6be06172ea62be8b2dca3fab36ab2d78 Mon Sep 17 00:00:00 2001
From: Vladimir Lyubushkin <vladimir.lyubushkin@cern.ch>
Date: Fri, 29 May 2020 16:15:33 +0000
Subject: [PATCH] TrigBphysHypo: TrigMultiTrkHypo algorithm is modified to be
 used as ComboHypo at muComb and muEFCB steps of BLS trigger chains
 (ATR-20836, ATR-21092, ATR-21112)

---
 ...nfig.py => TrigMultiTrkComboHypoConfig.py} |  63 ++--
 .../TrigMultiTrkComboHypoMonitoringConfig.py  |  39 +++
 .../TrigMultiTrkHypoMonitoringConfig.py       |  31 --
 ...iTrkHypo.cxx => TrigMultiTrkComboHypo.cxx} | 323 +++++++++++++-----
 ...MultiTrkHypo.h => TrigMultiTrkComboHypo.h} |  26 +-
 ...Tool.cxx => TrigMultiTrkComboHypoTool.cxx} |  84 ++---
 .../src/TrigMultiTrkComboHypoTool.h           |  64 ++++
 .../TrigBphysHypo/src/TrigMultiTrkHypoTool.h  |  95 ------
 .../src/components/TrigBphysHypo_entries.cxx  |   8 +-
 .../python/TrigMuonHypoMTConfig.py            |  10 +-
 .../python/TrigBphysMonitorAlgorithm.py       |   2 +-
 .../{src => DecisionHandling}/ComboHypo.h     |  18 +-
 .../ComboHypoToolBase.h                       |  13 +-
 .../IComboHypoTool.h                          |   0
 .../python/DecisionHandlingConfig.py          |   5 +
 .../DecisionHandling/src/ComboHypo.cxx        |  16 +-
 .../src/ComboHypoToolBase.cxx                 |   2 +-
 .../src/DeltaRRoIComboHypoTool.h              |   2 +-
 .../components/DecisionHandling_entries.cxx   |   4 +-
 .../share/ref_RDOtoRDOTrig_mt1_build.ref      |  35 +-
 .../share/ref_data_v1Dev_build.ref            |  21 ++
 .../TrigEDMConfig/python/TriggerEDMRun3.py    |  10 +-
 .../HLTMenuConfig/Bphysics/BphysicsDef.py     |  91 ++---
 .../Bphysics/BphysicsSequenceSetup.py         |  59 ----
 .../Bphysics/GenerateBphysicsChainDefs.py     |  36 +-
 .../Menu/ChainConfigurationBase.py            |   6 +-
 .../python/HLTMenuConfig/Menu/ChainMerging.py |   4 +-
 .../python/HLTMenuConfig/Menu/LS2_v1.py       |  13 +-
 .../HLTMenuConfig/Menu/MenuComponents.py      |  27 +-
 .../HLTMenuConfig/Menu/Physics_pp_run3_v1.py  |   7 +-
 .../HLTMenuConfig/Muon/MuonSequenceSetup.py   |   4 +-
 31 files changed, 612 insertions(+), 506 deletions(-)
 rename Trigger/TrigHypothesis/TrigBphysHypo/python/{TrigMultiTrkHypoConfig.py => TrigMultiTrkComboHypoConfig.py} (62%)
 create mode 100644 Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py
 delete mode 100644 Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoMonitoringConfig.py
 rename Trigger/TrigHypothesis/TrigBphysHypo/src/{TrigMultiTrkHypo.cxx => TrigMultiTrkComboHypo.cxx} (52%)
 rename Trigger/TrigHypothesis/TrigBphysHypo/src/{TrigMultiTrkHypo.h => TrigMultiTrkComboHypo.h} (83%)
 rename Trigger/TrigHypothesis/TrigBphysHypo/src/{TrigMultiTrkHypoTool.cxx => TrigMultiTrkComboHypoTool.cxx} (67%)
 create mode 100644 Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h
 delete mode 100644 Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.h
 rename Trigger/TrigSteer/DecisionHandling/{src => DecisionHandling}/ComboHypo.h (82%)
 rename Trigger/TrigSteer/DecisionHandling/{src => DecisionHandling}/ComboHypoToolBase.h (85%)
 rename Trigger/TrigSteer/DecisionHandling/{src => DecisionHandling}/IComboHypoTool.h (100%)

diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoConfig.py b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py
similarity index 62%
rename from Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoConfig.py
rename to Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py
index e70018acaf51..a0b39b9139ea 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoConfig.py
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py
@@ -1,29 +1,48 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
-from TrigBphysHypo.TrigBphysHypoConf import TrigMultiTrkHypo, TrigMultiTrkHypoTool
-from TrigBphysHypo.TrigMultiTrkHypoMonitoringConfig import TrigMultiTrkHypoMonitoring, TrigMultiTrkHypoToolMonitoring
+from TrigBphysHypo.TrigBphysHypoConf import TrigMultiTrkComboHypo, TrigMultiTrkComboHypoTool
+from TrigBphysHypo.TrigMultiTrkComboHypoMonitoringConfig import TrigMultiTrkComboHypoMonitoring, TrigMultiTrkComboHypoToolMonitoring
 
 from AthenaCommon.Logging import logging
-log = logging.getLogger('TrigMultiTrkHypoConfig')
-
-
-def TrigMultiTrkHypoToolFromDict(chainDict):
-    config = TrigMultiTrkHypoConfig()
-    tool = config.ConfigurationHypoTool(chainDict)
+log = logging.getLogger('TrigMultiTrkComboHypoConfig')
+
+def DimuL2ComboHypoCfg(name):
+    log.debug('DimuL2ComboHypoCfg.name = %s ', name)
+
+    config = TrigMultiTrkComboHypoConfig()
+    hypo = config.ConfigurationComboHypo(
+        trigSequenceName = 'Dimu',
+        trigLevel = 'L2',
+        trackCollection='HLT_IDTrack_Muon_FTF')
+    return hypo
+
+def DimuEFComboHypoCfg(name):
+    from TriggerMenuMT.HLTMenuConfig.Muon.MuonSetup import muonNames
+    log.debug('DimuEFComboHypoCfg.name = %s ', name)
+
+    config = TrigMultiTrkComboHypoConfig()
+    hypo = config.ConfigurationComboHypo(
+        trigSequenceName = 'Dimu',
+        trigLevel = 'EF',
+        muonCollection = muonNames().getNames('RoI').EFCBName)
+    return hypo
+
+def TrigMultiTrkComboHypoToolFromDict(chainDict):
+    config = TrigMultiTrkComboHypoConfig()
+    tool = config.ConfigurationComboHypoTool(chainDict)
     return tool
 
+class TrigMultiTrkComboHypoConfig(object):
 
-class TrigMultiTrkHypoConfig(object):
-
-    def ConfigurationHypo(self, trigSequenceName='Dimu', trigLevel='L2', trackCollection='', muonCollection=''):
+    def ConfigurationComboHypo(self, trigSequenceName='Dimu', trigLevel='L2', trackCollection='', muonCollection=''):
 
         trigLevelDict = {'L2':0, 'EF':1}
 
         try:
             value = trigLevelDict[trigLevel]
-            log.debug('TrigMultiTrkHypo.trigLevel = %s ', value)
+            log.debug('TrigMultiTrkComboHypo.trigLevel = %s ', value)
         except KeyError:
-            log.error('TrigMultiTrkHypo.trigLevel should be L2 or EF, but %s provided.', trigLevel)
+            log.error('TrigMultiTrkComboHypo.trigLevel should be L2 or EF, but %s provided.', trigLevel)
 
         from TrkExTools.AtlasExtrapolator import AtlasExtrapolator
         from TrkVKalVrtFitter.TrkVKalVrtFitterConf import Trk__TrkVKalVrtFitter
@@ -41,26 +60,29 @@ class TrigMultiTrkHypoConfig(object):
             MaxPhi    = [ 10000.,  10000.,  10000.],
             MaxChi2OfVtxEstimation = 2000.)
 
-        tool = TrigMultiTrkHypo(
-            name = trigSequenceName+'HypoAlg'+trigLevel,
+        tool = TrigMultiTrkComboHypo(
+            name = trigSequenceName+trigLevel+'ComboHypo',
             trigLevel = trigLevel,
             nTracks = 2,
             massRanges = [ (100., 20000.) ],
             TrackCollectionKey = trackCollection,
             MuonCollectionKey = muonCollection,
-            TrigBphysCollectionKey = ('TrigBphys' if trigLevel == 'L2' else 'TrigBphysEF') + trigSequenceName,
             VertexFitter = VertexFitter,
             VertexPointEstimator = VertexPointEstimator,
-            MonTool = TrigMultiTrkHypoMonitoring('TrigMultiTrkHypoMonitoring_'+trigSequenceName+trigLevel))
+            CheckMultiplicityMap = False,
+            MonTool = TrigMultiTrkComboHypoMonitoring('TrigMultiTrkComboHypoMonitoring_'+trigSequenceName+trigLevel))
+
+        if trigLevel == 'EF':
+            tool.TrigBphysCollectionKey = 'HLT_'+trigSequenceName+trigLevel
 
         return tool
 
-    def ConfigurationHypoTool(self, chainDict):
+    def ConfigurationComboHypoTool(self, chainDict):
 
         topoAlgs = chainDict['chainName']
         log.debug("Set for algorithm %s", topoAlgs)
 
-        tool = TrigMultiTrkHypoTool(topoAlgs)
+        tool = TrigMultiTrkComboHypoTool(topoAlgs)
 
         if 'nocut' in topoAlgs:
             tool.AcceptAll = True
@@ -71,7 +93,6 @@ class TrigMultiTrkHypoConfig(object):
         tool.ApplyUpperMassCut = True
         tool.ApplyChi2Cut = True
         tool.Chi2VtxCut = 20
-        tool.nBphysObjects = 1
         tool.trkPtThresholds = getBphysThresholds(chainDict)
 
         if 'bJpsimumu' in topoAlgs:
@@ -91,7 +112,7 @@ class TrigMultiTrkHypoConfig(object):
             tool.LowerMassCut =   100 #MeV
             tool.UpperMassCut = 14000 #MeV
 
-        tool.MonTool = TrigMultiTrkHypoToolMonitoring('MonTool')
+        tool.MonTool = TrigMultiTrkComboHypoToolMonitoring('MonTool')
         return tool
 
 
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py
new file mode 100644
index 000000000000..c571b0e8ae18
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool, defineHistogram
+
+class TrigMultiTrkComboHypoMonitoring(GenericMonitoringTool):
+    def __init__ (self, name):
+        super(TrigMultiTrkComboHypoMonitoring, self).__init__(name)
+        if 'L2' in name:
+            self.Histograms = [
+            defineHistogram('nTrk', type='TH1F', path='EXPERT', title="number of tracks in input views", xbins=100, xmin=0, xmax=100),
+            defineHistogram('nAcceptedTrk', type='TH1F', path='EXPERT', title="number of selected input tracks", xbins=100, xmin=0, xmax=100),
+            defineHistogram('acceptance', type='TH1F',path='EXPERT', title="filter acceptance", xbins=2, xmin=0, xmax=2),
+            defineHistogram('TIME_all', type='TH1F', path='EXPERT', title='execution time; [microseconds]', xbins=100, xmin=0, xmax=1000),
+            ]
+        elif 'EF' in name:
+            self.Histograms = [
+            defineHistogram('nTrk', type='TH1F', path='EXPERT', title="number of tracks in input views", xbins=100, xmin=0, xmax=100),
+            defineHistogram('nAcceptedTrk', type='TH1F', path='EXPERT', title="number of selected input tracks", xbins=100, xmin=0, xmax=100),
+            defineHistogram('nCombination', type='TH1F',path='EXPERT', title="number of track combinations before mass preselection", xbins=100, xmin=0, xmax=100),
+            defineHistogram('nCombinationBeforeFit', type='TH1F', path='EXPERT', title="number of inputs to the vertex fitter", xbins=100, xmin=0, xmax=100),
+            defineHistogram('nBPhysObject', type='TH1F', path='EXPERT', title="number of fitted BPhysObjects", xbins=100, xmin=0, xmax=100),
+            defineHistogram('trkMassBeforeFit', type='TH1F', path='EXPERT', title="mass of track combinations BEFORE fit [GeV]", xbins=200, xmin=0, xmax=100),
+            defineHistogram('bphysChi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; fit chi2 of N selected tracks", xbins=100, xmin=0, xmax=100),
+            defineHistogram('bphysFitMass', type='TH1F', path='EXPERT', title="fit mass of N tracks; fit mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20),
+            defineHistogram('bphysMass', type='TH1F', path='EXPERT', title="mass of N tracks; mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20),
+            defineHistogram('bphysCharge', type='TH1F', path='EXPERT', title="total charge of N tracks", xbins=20, xmin=-10, xmax=10),
+            defineHistogram('TIME_all', type='TH1F', path='EXPERT', title='execution time; [microseconds]', xbins=100, xmin=0, xmax=1000),
+            ]
+
+class TrigMultiTrkComboHypoToolMonitoring(GenericMonitoringTool):
+    def __init__ (self, name):
+        super(TrigMultiTrkComboHypoToolMonitoring, self).__init__(name)
+        self.Histograms = [
+        defineHistogram('totCharge', type='TH1F', path='EXPERT', title="Total Charge of tracks", xbins=21, xmin=-10, xmax=10),
+        defineHistogram('CutCounter', type='TH1F', path='EXPERT', title="mass of track pairs; m_{#mu#mu} [GeV]", xbins=5, xmin=-0.5, xmax=4.5),
+        defineHistogram('FitChi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; fit chi2 of N selected tracks", xbins=100, xmin=0, xmax=100),
+        defineHistogram('VertexMass', type='TH1F', path='EXPERT', title="Number of tracks selected; N selected tracks", xbins=100, xmin=0, xmax=20),
+        defineHistogram('trackPts', type='TH1F', path='EXPERT', title="pair mass of N tracks; pair mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20)
+        ]
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoMonitoringConfig.py b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoMonitoringConfig.py
deleted file mode 100644
index a0950d52c046..000000000000
--- a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkHypoMonitoringConfig.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-
-from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool, defineHistogram
-
-class TrigMultiTrkHypoMonitoring(GenericMonitoringTool):
-    def __init__ (self, name):
-        super(TrigMultiTrkHypoMonitoring, self).__init__(name)
-        self.Histograms = [
-        defineHistogram('nTrk', type='TH1F', path='EXPERT', title="number of tracks in input views", xbins=100, xmin=0, xmax=100),
-        defineHistogram('nAcceptedTrk', type='TH1F', path='EXPERT', title="number of selected input tracks", xbins=100, xmin=0, xmax=100),
-        defineHistogram('nCombination', type='TH1F',path='EXPERT', title="number of track combinations before mass preselection", xbins=100, xmin=0, xmax=100),
-        defineHistogram('nCombinationBeforeFit', type='TH1F', path='EXPERT', title="number of inputs to the vertex fitter", xbins=100, xmin=0, xmax=100),
-        defineHistogram('nBPhysObject', type='TH1F', path='EXPERT', title="number of fitted BPhysObjects", xbins=100, xmin=0, xmax=100),
-        defineHistogram('trkMassBeforeFit', type='TH1F', path='EXPERT', title="mass of track combinations BEFORE fit [GeV]", xbins=200, xmin=0, xmax=100),
-        defineHistogram('bphysChi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; fit chi2 of N selected tracks", xbins=100, xmin=0, xmax=100),
-        defineHistogram('bphysFitMass', type='TH1F', path='EXPERT', title="fit mass of N tracks; fit mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20),
-        defineHistogram('bphysMass', type='TH1F', path='EXPERT', title="mass of N tracks; mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20),
-        defineHistogram('bphysCharge', type='TH1F', path='EXPERT', title="total charge of N tracks", xbins=20, xmin=-10, xmax=10),
-        defineHistogram('TIME_all', type='TH1F', path='EXPERT', title='execution time; [microseconds]', xbins=100, xmin=0, xmax=100),
-        ]
-
-class TrigMultiTrkHypoToolMonitoring(GenericMonitoringTool):
-    def __init__ (self, name):
-        super(TrigMultiTrkHypoToolMonitoring, self).__init__(name)
-        self.Histograms = [
-        defineHistogram('totCharge', type='TH1F', path='EXPERT', title="Total Charge of tracks", xbins=21, xmin=-10, xmax=10),
-        defineHistogram('CutCounter', type='TH1F', path='EXPERT', title="mass of track pairs; m_{#mu#mu} [GeV]", xbins=5, xmin=-0.5, xmax=4.5),
-        defineHistogram('FitChi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; fit chi2 of N selected tracks", xbins=100, xmin=0, xmax=100),
-        defineHistogram('VertexMass', type='TH1F', path='EXPERT', title="Number of tracks selected; N selected tracks", xbins=100, xmin=0, xmax=20),
-        defineHistogram('trackPts', type='TH1F', path='EXPERT', title="pair mass of N tracks; pair mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20)
-        ]
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypo.cxx b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx
similarity index 52%
rename from Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypo.cxx
rename to Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx
index 8b698c4b4d11..271aedb7a98c 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypo.cxx
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx
@@ -4,7 +4,7 @@
 
 /**************************************************************************
  **
- **   File: Trigger/TrigHypothesis/TrigBPhysHypo/TrigMultiTrkHypo.cxx
+ **   File: Trigger/TrigHypothesis/TrigBPhysHypo/TrigMultiTrkComboHypo.cxx
  **
  **   Description: multi-track hypothesis algorithm
  **
@@ -12,7 +12,10 @@
  **
  **************************************************************************/
 
-#include "TrigMultiTrkHypo.h"
+#include <algorithm>
+#include <numeric>
+
+#include "TrigMultiTrkComboHypo.h"
 
 #include "xAODMuon/Muon.h"
 #include "xAODTracking/TrackParticle.h"
@@ -22,6 +25,7 @@
 #include "xAODTrigBphys/TrigBphysAuxContainer.h"
 
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
+#include "TrigCompositeUtils/HLTIdentifier.h"
 #include "TrigConfHLTData/HLTUtils.h"
 
 #include "AthViews/View.h"
@@ -31,17 +35,19 @@
 
 using TrigCompositeUtils::Decision;
 using TrigCompositeUtils::DecisionContainer;
+using TrigCompositeUtils::DecisionID;
 using TrigCompositeUtils::DecisionIDContainer;
 
 
-
-TrigMultiTrkHypo::TrigMultiTrkHypo(const std::string& name, ISvcLocator* pSvcLocator)
-    : ::HypoBase(name, pSvcLocator) {}
+TrigMultiTrkComboHypo::TrigMultiTrkComboHypo(const std::string& name, ISvcLocator* pSvcLocator)
+    : ::ComboHypo(name, pSvcLocator) {}
 
 
-StatusCode TrigMultiTrkHypo::initialize() {
+StatusCode TrigMultiTrkComboHypo::initialize() {
   ATH_MSG_DEBUG( "TrigMultiTrkHypo::initialize()" );
 
+  ATH_CHECK( ::ComboHypo::initialize() );
+
   // check consistency of the properties
   if (m_trkMass.size() != m_nTrk) {
     ATH_MSG_ERROR( "Requested " << m_nTrk << " tracks per vertex, but only provided " << m_trkMass.size() << " track masses");
@@ -77,24 +83,67 @@ StatusCode TrigMultiTrkHypo::initialize() {
     ATH_CHECK( m_muonContainerKey.initialize(false) );
     ATH_CHECK( m_trackParticleContainerKey.initialize() );
     renounce(m_trackParticleContainerKey);
+    ATH_CHECK( m_trigBphysContainerKey.initialize(false) );
   }
   else if (m_trigLevelString == "EF") {
     m_trigLevel = xAOD::TrigBphys::EF;
     ATH_CHECK( m_trackParticleContainerKey.initialize(false) );
     ATH_CHECK( m_muonContainerKey.initialize() );
     renounce(m_muonContainerKey);
+    ATH_CHECK( m_trigBphysContainerKey.initialize() );
   }
   else {
     m_trigLevel = xAOD::TrigBphys::UNKOWNLEVEL;
     ATH_MSG_ERROR( "trigLevel should be L2 or EF, but " << m_trigLevelString << " provided" );
     return StatusCode::FAILURE;
   }
-  ATH_CHECK( m_trigBphysContainerKey.initialize() );
 
   ATH_CHECK( m_vertexFitter.retrieve() );
   ATH_CHECK( m_vertexPointEstimator.retrieve() );
 
-  ATH_CHECK( m_hypoTools.retrieve() );
+  // allowed IDs to filter out incoming decisions at L2 level
+  for (const auto& item : triggerMultiplicityMap()) {
+    const HLT::Identifier id = HLT::Identifier::fromToolName(item.first);
+    m_allowedIDs.insert(id.numeric());
+    if (item.second.size() > 1) {
+      for (size_t i = 0; i < item.second.size(); i++) {
+        m_allowedIDs.insert(TrigCompositeUtils::createLegName(id, i).numeric());
+      }
+    }
+  }
+  if (msgLvl(MSG::DEBUG)) {
+    ATH_MSG_DEBUG( "Allowed decisions:" );
+    for (const DecisionID& id : m_allowedIDs) {
+      ATH_MSG_DEBUG( " +++ " << HLT::Identifier(id) );
+    }
+  }
+
+  // add IDs to ComboHypoTools to check that each trigger leg fulfill TrigCompositeUtils::passed() requirement
+  for (auto& tool : hypoTools()) {
+    const HLT::Identifier id = tool->decisionId();
+    const auto itr = triggerMultiplicityMap().find(id.name());
+    if (itr == triggerMultiplicityMap().end()) {
+      ATH_MSG_ERROR( "No entry found for " << tool->name() << " in triggerMultiplicityMap" );
+    }
+    const std::vector<int>& multiplicity = itr->second;
+    std::vector<HLT::Identifier> legDecisionIds;
+    if (multiplicity.size() == 1) {
+      std::fill_n(std::back_inserter(legDecisionIds), multiplicity[0], id);
+    }
+    else {
+      size_t n = static_cast<size_t>(std::accumulate(multiplicity.begin(), multiplicity.end(), 0));
+      for (size_t i = 0; i < n; i++) {
+        legDecisionIds.push_back(TrigCompositeUtils::createLegName(id, i));
+      }
+    }
+    tool->setLegDecisionIds(legDecisionIds);
+    if (msgLvl(MSG::DEBUG)) {
+      ATH_MSG_DEBUG( "Leg decisions for tool " << tool->name() );
+      for (const auto& id : legDecisionIds) {
+        ATH_MSG_DEBUG( " +++ " << id );
+      }
+    }
+  }
 
   if (!m_monTool.empty()) {
     ATH_CHECK( m_monTool.retrieve() );
@@ -108,23 +157,155 @@ StatusCode TrigMultiTrkHypo::initialize() {
 }
 
 
-StatusCode TrigMultiTrkHypo::finalize() {
+StatusCode TrigMultiTrkComboHypo::finalize() {
   TrigConf::HLTUtils::hashes2file();
   return StatusCode::SUCCESS;
 }
 
 
-StatusCode TrigMultiTrkHypo::execute(const EventContext& context) const {
+StatusCode TrigMultiTrkComboHypo::execute(const EventContext& context) const {
 
   ATH_MSG_DEBUG( "TrigMultiTrkHypo::execute() starts" );
 
-  ATH_MSG_DEBUG( "decision input key: " << decisionInput().key() );
-  auto previousDecisionsHandle = SG::makeHandle(decisionInput(), context);
+  if (m_trigLevel == xAOD::TrigBphys::L2) {
+    ATH_CHECK( executeL2(context) );
+  }
+  else if (m_trigLevel == xAOD::TrigBphys::EF) {
+    ATH_CHECK( executeEF(context) );
+  }
+
+  ATH_MSG_DEBUG( "TrigMultiTrkHypo::execute() terminates with StatusCode::SUCCESS" );
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TrigMultiTrkComboHypo::executeL2(const EventContext& context) const {
+
+  ATH_MSG_DEBUG( "decision input key: " << decisionsInput().at(0).key() );
+  auto previousDecisionsHandle = SG::makeHandle(decisionsInput().at(0), context);
+  CHECK( previousDecisionsHandle.isValid() );
+  ATH_MSG_DEBUG( "Running with "<< previousDecisionsHandle->size() << " previous decisions" );
+
+  // create the mutable output DecisionContainer and register it to StoreGate
+  SG::WriteHandle<DecisionContainer> outputHandle = TrigCompositeUtils::createAndStore(decisionsOutput().at(0), context);
+  DecisionContainer* decisions = outputHandle.ptr();
+
+  // monitored variables
+  auto mon_nTrk = Monitored::Scalar<int>("nTrk", 0);
+  auto mon_nAcceptedTrk = Monitored::Scalar<int>("nAcceptedTrk", 0);
+  auto mon_isEventAccepted = Monitored::Scalar<int>("acceptance", 0);
+  auto mon_timer = Monitored::Timer( "TIME_all" );
+
+  auto group = Monitored::Group(m_monTool,
+    mon_nTrk, mon_nAcceptedTrk, mon_isEventAccepted,
+    mon_timer);
+
+  // combine all tracks from the event views, make overlap removal
+  std::vector<ElementLink<xAOD::TrackParticleContainer>> tracks;
+  size_t viewCounter = 0;
+  for (const Decision* previousDecision : *previousDecisionsHandle) {
+    auto viewLinkInfo = TrigCompositeUtils::findLink<ViewContainer>(previousDecision, TrigCompositeUtils::viewString(), true);
+    ATH_CHECK( viewLinkInfo.isValid() );
+    auto viewEL = viewLinkInfo.link;
+
+    std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
+    auto tracksHandle = ViewHelper::makeHandle(*viewEL, m_trackParticleContainerKey, context);
+    CHECK( tracksHandle.isValid() );
+    ATH_MSG_DEBUG( "tracks handle " << m_trackParticleContainerKey << " size: " << tracksHandle->size() );
+
+    for (size_t idx = 0; idx < tracksHandle->size(); ++idx) {
+      tracksFromView.emplace_back(ViewHelper::makeLink<xAOD::TrackParticleContainer>(*viewEL, tracksHandle, idx));
+    }
+    mon_nTrk += tracksFromView.size();
+
+    for (const auto& trackEL : tracksFromView) {
+      const xAOD::TrackParticle* track = *trackEL;
+      if (track->definingParametersCovMatrixVec().empty() || track->pt() < m_trkPt.value().back()) continue;
+
+      if (viewCounter == 0 ||
+          std::find_if(tracks.begin(), tracks.end(),
+                       [this,track = track](const auto& x){ return isIdenticalTracks(track, *x); }) == tracks.end()) {
+        tracks.emplace_back(trackEL);
+      }
+    }
+
+    viewCounter++;
+  }
+  std::sort(tracks.begin(), tracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs)->pt() > (*rhs)->pt()); });
+
+  mon_nAcceptedTrk = tracks.size();
+  ATH_MSG_DEBUG( "Select " << mon_nAcceptedTrk << " tracks and send them to vertex fitter" );
+
+  if (msgLvl(MSG::DEBUG)) {
+    ATH_MSG_DEBUG( "Dump found tracks before vertex fit: " );
+    for (const auto& x : tracks) {
+      const xAOD::TrackParticle* track = *x;
+      ATH_MSG_DEBUG( "  -- track pt/eta/phi/q: " << track->pt() << " / " << track->eta() << " / " << track->phi() << " / " << track->charge() );
+    }
+  }
+
+  mon_isEventAccepted = 0;
+  for (size_t itrk1 = 0; itrk1 < tracks.size(); ++itrk1) {
+    if (mon_isEventAccepted) break;
+    const xAOD::TrackParticle* trk1 = *tracks[itrk1];
+    auto p1 = trk1->genvecP4();
+    p1.SetM( m_trkMass[0] );
+    if (p1.Pt() < m_trkPt[0]) continue;
+
+    for (size_t itrk2 = itrk1 + 1; itrk2 < tracks.size(); ++itrk2) {
+      const xAOD::TrackParticle* trk2 = *tracks[itrk2];
+      auto p2 = trk2->genvecP4();
+      p2.SetM( m_trkMass[1] );
+      if (p2.Pt() < m_trkPt[1]) continue;
+
+      double mass = (p1 + p2).M();
+      ATH_MSG_DEBUG( "track 1: " << p1.Pt()<< " / " << p1.Eta() << " / " << p1.Phi() << " / " << trk1->charge() );
+      ATH_MSG_DEBUG( "track 2: " << p2.Pt()<< " / " << p2.Eta() << " / " << p2.Phi() << " / " << trk2->charge() );
+      ATH_MSG_DEBUG( "track pair mass: " << mass );
+
+      if (!isInMassRange(mass)) continue;
+
+      xAOD::TrigBphys* trigBphys = fit(std::vector<ElementLink<xAOD::TrackParticleContainer>>{tracks[itrk1], tracks[itrk2]});
+      if (!trigBphys) continue;
+
+      ATH_MSG_DEBUG( "Found good dimuon pair at L2 level: stop looking for dimuon pairs" );
+      mon_isEventAccepted = 1;
+      delete trigBphys;
+      break;
+    }
+  }
+
+  if (mon_isEventAccepted) {
+    ATH_MSG_DEBUG( "Copying decisions from " << decisionsInput().at(0).key() << " to " << decisionsOutput().at(0).key() );
+    for (const Decision* previousDecision : *previousDecisionsHandle) {
+      DecisionIDContainer previousDecisionIDs;
+      TrigCompositeUtils::decisionIDs(previousDecision, previousDecisionIDs);
+      DecisionIDContainer decisionIDs;
+      std::set_intersection(previousDecisionIDs.begin(), previousDecisionIDs.end(), m_allowedIDs.begin(), m_allowedIDs.end(),
+                            std::inserter(decisionIDs, decisionIDs.end()));
+
+      Decision* decision = TrigCompositeUtils::newDecisionIn(decisions);
+      TrigCompositeUtils::linkToPrevious(decision, previousDecision, context);
+      TrigCompositeUtils::insertDecisionIDs(decisionIDs, decision);
+    }
+  }
+  else {
+    ATH_MSG_DEBUG( "No dimuon pairs found: no desicions will be copied to " << decisionsOutput().at(0).key() );
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TrigMultiTrkComboHypo::executeEF(const EventContext& context) const {
+
+  ATH_MSG_DEBUG( "decision input key: " << decisionsInput().at(0).key() );
+  auto previousDecisionsHandle = SG::makeHandle(decisionsInput().at(0), context);
   CHECK( previousDecisionsHandle.isValid() );
   ATH_MSG_DEBUG( "Running with "<< previousDecisionsHandle->size() << " previous decisions" );
 
   // create the mutable output DecisionContainer and register it to StoreGate
-  SG::WriteHandle<DecisionContainer> outputHandle = TrigCompositeUtils::createAndStore(decisionOutput(), context);
+  SG::WriteHandle<DecisionContainer> outputHandle = TrigCompositeUtils::createAndStore(decisionsOutput().at(0), context);
   DecisionContainer* decisions = outputHandle.ptr();
 
   auto trigBphysHandle = SG::makeHandle(m_trigBphysContainerKey, context);
@@ -154,34 +335,26 @@ StatusCode TrigMultiTrkHypo::execute(const EventContext& context) const {
     mon_trkMassBeforeFit, mon_bphysChi2, mon_bphysFitMass, mon_bphysMass, mon_bphysCharge,
     mon_timer);
 
-  // combine all tracks/muons from the event views, make overlap removal
-  std::vector<std::pair<ElementLink<xAOD::TrackParticleContainer>, const Decision*>> tracks;
+  // combine all muons from the event views, make overlap removal
+  std::vector<std::pair<ElementLink<xAOD::TrackParticleContainer>, ElementLinkVector<TrigCompositeUtils::DecisionContainer>>> tracks;
   size_t viewCounter = 0;
   for (const Decision* previousDecision : *previousDecisionsHandle) {
-    const auto viewEL = previousDecision->objectLink<ViewContainer>(TrigCompositeUtils::viewString());
-    CHECK( viewEL.isValid() );
+    auto previousDecisionEL = TrigCompositeUtils::decisionToElementLink(previousDecision, context);
 
-    std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
-    if (m_trigLevel == xAOD::TrigBphys::L2) {
-      auto tracksHandle = ViewHelper::makeHandle(*viewEL, m_trackParticleContainerKey, context);
-      CHECK( tracksHandle.isValid() );
-      ATH_MSG_DEBUG( "tracks handle " << m_trackParticleContainerKey << " size: " << tracksHandle->size() );
+    auto viewLinkInfo = TrigCompositeUtils::findLink<ViewContainer>(previousDecision, TrigCompositeUtils::viewString(), true);
+    ATH_CHECK( viewLinkInfo.isValid() );
+    auto viewEL = viewLinkInfo.link;
 
-      for (size_t idx = 0; idx < tracksHandle->size(); ++idx) {
-        tracksFromView.emplace_back(ViewHelper::makeLink<xAOD::TrackParticleContainer>(*viewEL, tracksHandle, idx));
-      }
-    }
-    else {
-      auto muonsHandle = ViewHelper::makeHandle(*viewEL, m_muonContainerKey, context);
-      CHECK( muonsHandle.isValid() );
-      ATH_MSG_DEBUG( "muons handle " << m_muonContainerKey << " size: " << muonsHandle->size() );
-
-      for (const xAOD::Muon* muon : *muonsHandle) {
-        if (!muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) continue;
-        const ElementLink<xAOD::TrackParticleContainer> trackEL = muon->inDetTrackParticleLink();
-        CHECK( trackEL.isValid() );
-        tracksFromView.emplace_back(trackEL);
-      }
+    std::vector<ElementLink<xAOD::TrackParticleContainer>> tracksFromView;
+    auto muonsHandle = ViewHelper::makeHandle(*viewEL, m_muonContainerKey, context);
+    CHECK( muonsHandle.isValid() );
+    ATH_MSG_DEBUG( "muons handle " << m_muonContainerKey << " size: " << muonsHandle->size() );
+
+    for (const xAOD::Muon* muon : *muonsHandle) {
+      if (!muon->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle)) continue;
+      const ElementLink<xAOD::TrackParticleContainer> trackEL = muon->inDetTrackParticleLink();
+      CHECK( trackEL.isValid() );
+      tracksFromView.emplace_back(trackEL);
     }
     mon_nTrk += tracksFromView.size();
 
@@ -189,13 +362,16 @@ StatusCode TrigMultiTrkHypo::execute(const EventContext& context) const {
       const xAOD::TrackParticle* track = *trackEL;
       if (track->definingParametersCovMatrixVec().empty() || track->pt() < m_trkPt.value().back()) continue;
 
-      if (viewCounter == 0 ||
-          std::find_if(tracks.begin(), tracks.end(),
-                       [this,track = track](const auto& x){ return isIdenticalTracks(track, *x.first); }) == tracks.end()) {
-        tracks.emplace_back(std::make_pair(trackEL, previousDecision));
+      auto itr = (viewCounter ? std::find_if(tracks.begin(), tracks.end(),
+                                             [this,track = track](const auto& x){ return isIdenticalTracks(track, *x.first); })
+                              : tracks.end());
+      if (itr == tracks.end()) {
+        tracks.emplace_back(std::make_pair(trackEL, ElementLinkVector<TrigCompositeUtils::DecisionContainer>(1, previousDecisionEL)));
+      }
+      else {
+        (*itr).second.push_back(previousDecisionEL);
       }
     }
-
     viewCounter++;
   }
   std::sort(tracks.begin(), tracks.end(), [](const auto& lhs, const auto& rhs){ return ((*lhs.first)->pt() > (*rhs.first)->pt()); });
@@ -211,7 +387,7 @@ StatusCode TrigMultiTrkHypo::execute(const EventContext& context) const {
     }
   }
 
-  std::vector<std::vector<const Decision*>> trigBphysPreviousDecisions;
+  std::vector<std::vector<size_t>> trigBphysTrackIdx;
   for (size_t itrk1 = 0; itrk1 < tracks.size(); ++itrk1) {
     const xAOD::TrackParticle* trk1 = *tracks[itrk1].first;
     auto p1 = trk1->genvecP4();
@@ -242,7 +418,7 @@ StatusCode TrigMultiTrkHypo::execute(const EventContext& context) const {
       if (!trigBphys) continue;
 
       trigBphysHandle->push_back(trigBphys);
-      trigBphysPreviousDecisions.emplace_back(std::vector<const Decision*>{tracks[itrk1].second, tracks[itrk2].second});
+      trigBphysTrackIdx.emplace_back(std::vector<size_t>{itrk1, itrk2});
 
       mon_nBPhysObject++;
       bphysMass.push_back(mass * 0.001);
@@ -250,56 +426,51 @@ StatusCode TrigMultiTrkHypo::execute(const EventContext& context) const {
     }
   }
 
-  std::vector<TrigMultiTrkHypoTool::TrigMultiTrkInfo> hypoToolInput;
+  std::map<ElementLinkVector<TrigCompositeUtils::DecisionContainer>, DecisionIDContainer> legDecisionIDsMap;
+  for (const auto& leg : tracks) {
+    auto itr = legDecisionIDsMap.find( leg.second );
+    if (itr == legDecisionIDsMap.end()) {
+      DecisionIDContainer legDecisionIDs;
+      for (const ElementLink<DecisionContainer>& decisionEL : leg.second) {
+        TrigCompositeUtils::decisionIDs(*decisionEL, legDecisionIDs);
+      }
+      legDecisionIDsMap[leg.second] = legDecisionIDs;
+    }
+  }
 
   size_t idx = 0;
   for (const xAOD::TrigBphys* trigBphys : *trigBphysHandle) {
-
     ATH_MSG_DEBUG( "Found xAOD::TrigBphys: mass = " << trigBphys->mass() );
 
     // create a new output Decision object, backed by the 'decisions' container.
     Decision* decision = TrigCompositeUtils::newDecisionIn(decisions);
 
+    std::vector<DecisionIDContainer*> previousDecisionIDs;
+    for (size_t itrk : trigBphysTrackIdx[idx]) {
+      // attach all previous decisions: if the same previous decision is called twice, that's fine - internally takes care of that
+      for (const ElementLink<DecisionContainer>& previousDecisionEL : tracks[itrk].second) {
+        TrigCompositeUtils::linkToPrevious(decision, *previousDecisionEL, context);
+      }
+      auto& legDecisionIDs = legDecisionIDsMap[tracks[itrk].second];
+      previousDecisionIDs.push_back(&legDecisionIDs);
+    }
+
     // set mandatory feature ElementLink to xAOD::TrigBphys object
     decision->setObjectLink<xAOD::TrigBphysContainer>(TrigCompositeUtils::featureString(),
                                                       ElementLink<xAOD::TrigBphysContainer>(*trigBphysHandle, trigBphys->index()));
 
-    DecisionIDContainer previousDecisionIDs_trk1;
-    DecisionIDContainer previousDecisionIDs_trk2;
-    for (size_t itrk = 0; itrk < 2; ++itrk) {
-      const Decision* previousDecision = trigBphysPreviousDecisions[idx][itrk];
-
-      // if the same previous decision is called twice, that's fine - internally takes care of that
-      TrigCompositeUtils::linkToPrevious(decision, previousDecision, context);
-      if (itrk == 0) {
-        TrigCompositeUtils::decisionIDs(previousDecision, previousDecisionIDs_trk1);
-      }
-      else {
-        TrigCompositeUtils::decisionIDs(previousDecision, previousDecisionIDs_trk2);
-      }
-
+    for (const auto& tool : hypoTools()) {
+      ATH_MSG_DEBUG( "Go to " << tool );
+      ATH_CHECK( tool->decideOnSingleObject(decision, previousDecisionIDs) );
     }
-    // collect all the required information for the tool together in a handy struct
-    hypoToolInput.emplace_back(TrigMultiTrkHypoTool::TrigMultiTrkInfo{
-      decision, trigBphys, previousDecisionIDs_trk1, previousDecisionIDs_trk2});
-
     ++idx;
   }
 
-  ATH_MSG_DEBUG( "Found "<< hypoToolInput.size() << " inputs to HypoTools" );
-  for (auto& tool: m_hypoTools) {
-    ATH_MSG_DEBUG( "Go to " << tool );
-    ATH_CHECK( tool->decide(hypoToolInput) );
-  }
-
-  ATH_CHECK( hypoBaseOutputProcessing(outputHandle) );
-
-  ATH_MSG_DEBUG( "TrigMultiTrkHypo::execute() terminates with StatusCode::SUCCESS" );
   return StatusCode::SUCCESS;
 }
 
 
-xAOD::TrigBphys* TrigMultiTrkHypo::fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks) const {
+xAOD::TrigBphys* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks) const {
   xAOD::TrigBphys* result = nullptr;
 
   ATH_MSG_DEBUG( "Perform vertex fit" );
@@ -373,14 +544,14 @@ xAOD::TrigBphys* TrigMultiTrkHypo::fit(const std::vector<ElementLink<xAOD::Track
 }
 
 
-bool TrigMultiTrkHypo::isIdenticalTracks(const xAOD::TrackParticle* lhs, const xAOD::TrackParticle* rhs) const {
+bool TrigMultiTrkComboHypo::isIdenticalTracks(const xAOD::TrackParticle* lhs, const xAOD::TrackParticle* rhs) const {
 
   if (lhs->charge() * rhs->charge() < 0.) return false;
   return (ROOT::Math::VectorUtil::DeltaR(lhs->genvecP4(), rhs->genvecP4()) < m_deltaR);
 }
 
 
-bool TrigMultiTrkHypo::isInMassRange(double mass) const {
+bool TrigMultiTrkComboHypo::isInMassRange(double mass) const {
 
   bool result = false;
   for (const auto& range : m_massRange) {
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypo.h b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h
similarity index 83%
rename from Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypo.h
rename to Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h
index dbb368538d25..69a65e5abce8 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypo.h
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h
@@ -4,7 +4,7 @@
 
 /**************************************************************************
  **
- **   File: Trigger/TrigHypothesis/TrigBphysHypo/TrigMultiTrkHypo.h
+ **   File: Trigger/TrigHypothesis/TrigBphysHypo/TrigMultiTrkComboHypo.h
  **
  **   Description: multi-track hypothesis algorithm
  **
@@ -12,8 +12,8 @@
  **
  **************************************************************************/
 
-#ifndef TRIG_TrigMultiTrkHypo_H
-#define TRIG_TrigMultiTrkHypo_H
+#ifndef TRIG_TrigMultiTrkComboHypo_H
+#define TRIG_TrigMultiTrkComboHypo_H
 
 #include <string>
 #include <vector>
@@ -22,13 +22,14 @@
 #include "GaudiKernel/Property.h"
 #include "xAODTracking/TrackParticleContainer.h"
 #include "xAODMuon/MuonContainer.h"
+#include "xAODTrigger/TrigComposite.h"
 #include "xAODTrigBphys/TrigBphysContainer.h"
 
 #include "StoreGate/ReadHandleKey.h"
 #include "StoreGate/WriteHandleKey.h"
 
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
-#include "DecisionHandling/HypoBase.h"
+#include "DecisionHandling/ComboHypo.h"
 
 #include "TrkVKalVrtFitter/TrkVKalVrtFitter.h"
 #include "InDetConversionFinderTools/VertexPointEstimator.h"
@@ -36,13 +37,13 @@
 #include "AthenaMonitoringKernel/Monitored.h"
 #include "AthenaMonitoringKernel/GenericMonitoringTool.h"
 
-#include "TrigMultiTrkHypoTool.h"
+#include "TrigMultiTrkComboHypoTool.h"
 
 
-class TrigMultiTrkHypo: public ::HypoBase {
+class TrigMultiTrkComboHypo: public ::ComboHypo {
  public:
-  TrigMultiTrkHypo(const std::string& name, ISvcLocator* pSvcLocator);
-  TrigMultiTrkHypo() = delete;
+  TrigMultiTrkComboHypo(const std::string& name, ISvcLocator* pSvcLocator);
+  TrigMultiTrkComboHypo() = delete;
 
   virtual StatusCode initialize() override;
   virtual StatusCode execute(const EventContext& context) const override;
@@ -53,7 +54,8 @@ class TrigMultiTrkHypo: public ::HypoBase {
   bool isReEntrant() const override { return false; }
 
  private:
-
+  StatusCode executeL2(const EventContext& context) const;
+  StatusCode executeEF(const EventContext& context) const;
   xAOD::TrigBphys* fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& tracklist) const;
   bool isIdenticalTracks(const xAOD::TrackParticle* lhs, const xAOD::TrackParticle* rhs) const;
   bool isInMassRange(double mass) const;
@@ -61,7 +63,6 @@ class TrigMultiTrkHypo: public ::HypoBase {
   SG::ReadHandleKey<xAOD::TrackParticleContainer>
     m_trackParticleContainerKey {this, "TrackCollectionKey", "Tracks", "input TrackParticle container name"};
 
-
   SG::ReadHandleKey<xAOD::MuonContainer>
     m_muonContainerKey {this, "MuonCollectionKey", "CBCombinedMuon", "input EF Muon container name"};
 
@@ -80,9 +81,10 @@ class TrigMultiTrkHypo: public ::HypoBase {
   ToolHandle<InDet::VertexPointEstimator> m_vertexPointEstimator {this, "VertexPointEstimator", "", "tool to find starting point for the vertex fitter"};
   ToolHandle<Trk::TrkVKalVrtFitter> m_vertexFitter {this, "VertexFitter", "", "VKalVrtFitter tool to fit tracks into the common vertex"};
 
-  ToolHandleArray<TrigMultiTrkHypoTool> m_hypoTools {this, "HypoTools", {}, "tools to perform selection"};
   ToolHandle<GenericMonitoringTool> m_monTool {this, "MonTool", "", "monitoring tool"};
 
+  TrigCompositeUtils::DecisionIDContainer m_allowedIDs;
+
 };
 
-#endif  // TRIG_TrigMultiTrkHypo_H
+#endif  // TRIG_TrigMultiTrkComboHypo_H
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.cxx b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx
similarity index 67%
rename from Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.cxx
rename to Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx
index b3361019cdae..90f2295d9b17 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.cxx
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx
@@ -6,40 +6,22 @@
  **
  **   File: Trigger/TrigHypothesis/TrigBPhysHypo/TrigMultiTrkHypoTool.cxx
  **
- **   Description: Multi-track hypothesis tool for bphys triggers
+ **   Description: multi-track hypothesis tool for bphys triggers
  **
- **   Author: H. Russell
+ **   Author: Heather Russell
  **
  **************************************************************************/
 
-#include "TrigMultiTrkHypoTool.h"
+#include "TrigMultiTrkComboHypoTool.h"
 
-#include <math.h>
+#include <cmath>
 
-// additions of xAOD objects
-#include "xAODTracking/TrackParticle.h"
 
-#include "xAODTrigBphys/TrigBphys.h"
-#include "xAODTrigBphys/TrigBphysContainer.h"
+TrigMultiTrkComboHypoTool::TrigMultiTrkComboHypoTool(const std::string& type, const std::string& name, const IInterface* parent)
+    : ComboHypoToolBase(type, name, parent) {}
 
-#include "AthenaMonitoringKernel/Monitored.h"
 
-#include "TrigCompositeUtils/TrigCompositeUtils.h"
-
-class ISvcLocator;
-
-
-TrigMultiTrkHypoTool::TrigMultiTrkHypoTool(const std::string & type,
-                                     const std::string & name,
-                                     const IInterface* parent )
-   : AthAlgTool( type, name, parent ),
-     m_decisionId( HLT::Identifier::fromToolName( name ) )
-{}
-
-TrigMultiTrkHypoTool::~TrigMultiTrkHypoTool()
-{ }
-
-StatusCode TrigMultiTrkHypoTool::initialize()
+StatusCode TrigMultiTrkComboHypoTool::initialize()
 {
   ATH_MSG_DEBUG("AcceptAll            = " << (m_acceptAll==true ? "True" : "False") );
   if(m_TotChargeCut >=0)ATH_MSG_DEBUG("Total Charge Cut     = " << m_TotChargeCut);
@@ -70,8 +52,7 @@ StatusCode TrigMultiTrkHypoTool::initialize()
 }
 
 
-//-------------------------------------------------------------------------------------
-bool TrigMultiTrkHypoTool::decideOnSingleObject( const xAOD::TrigBphys* trigBphys, size_t  ) const{
+bool TrigMultiTrkComboHypoTool::passed(const xAOD::TrigBphys* trigBphys) const {
 
   using namespace Monitored;
 
@@ -125,7 +106,7 @@ bool TrigMultiTrkHypoTool::decideOnSingleObject( const xAOD::TrigBphys* trigBphy
           trackPts.push_back(tp->pt());
       }
       mon_totCharge = totq;
-      thisPassedChargeCut = m_TotChargeCut <= -1 || (std::abs(totq) !=  m_TotChargeCut);
+      thisPassedChargeCut = m_TotChargeCut <= -1 || (std::abs(totq) == m_TotChargeCut);
       if(thisPassedChargeCut){
       	ATH_MSG_DEBUG("Passed charge cut with " << totq);
       }
@@ -172,40 +153,25 @@ bool TrigMultiTrkHypoTool::decideOnSingleObject( const xAOD::TrigBphys* trigBphy
   return result;
 }
 
-StatusCode TrigMultiTrkHypoTool::inclusiveSelection(std::vector<TrigMultiTrkHypoTool::TrigMultiTrkInfo>& toolInput) const{
-
-  for ( auto& i: toolInput ) {
-   //should this be configured to do something slightly differently? maybe we don't want the previous decision to pass this way??
-   ATH_MSG_DEBUG("what is this? " << m_decisionId.numeric()); //hashing of the chain name
-
-   //Make sure that BOTH tracks come from a previous muon that passed (for this chain)
-   //How could this not happen? no idea!
-   if ( TrigCompositeUtils::passed( m_decisionId.numeric(), i.previousDecisionIDs0 ) &&
-   		TrigCompositeUtils::passed( m_decisionId.numeric(), i.previousDecisionIDs1 ) ) {
-         if ( decideOnSingleObject( i.trigBphys, 0 )==true ) {
-            ATH_MSG_DEBUG("Passed through selection, decisionID:" << m_decisionId );
-            TrigCompositeUtils::addDecisionID(m_decisionId, i.decision);
-         } else {
-            ATH_MSG_DEBUG("Didn't pass through selection, decisionID:" << m_decisionId );
-         }
-      } else {
-         ATH_MSG_DEBUG("Didn't pass previous decision, decisionID:" << m_decisionId );
-      }
-  }
-  return StatusCode::SUCCESS;
-}
 
-StatusCode TrigMultiTrkHypoTool::decide( std::vector<TrigMultiTrkHypoTool::TrigMultiTrkInfo> &input) const {
+StatusCode TrigMultiTrkComboHypoTool::decideOnSingleObject(Decision* decision, const std::vector<DecisionIDContainer*>& previousDecisionIDs) const {
+
+  ATH_CHECK( decision->hasObjectLink(TrigCompositeUtils::featureString()) );
 
-  if ( m_nBphysObjects == 1 ) {
-    return inclusiveSelection( input );
-  } else {
-    ATH_MSG_WARNING("TrigMultiTrkHypoTool is not configured to do multiple dimuon objects selection.");
-    ATH_MSG_WARNING("Clever overlap removal needed to ensure that dimuon objectss do not contain identical RoIs!");
-    ATH_MSG_WARNING("I'm returning the inclusive selection result!");
-    return inclusiveSelection( input );
+  auto trigBphysEL = decision->objectLink<xAOD::TrigBphysContainer>(TrigCompositeUtils::featureString());
+  ATH_CHECK( trigBphysEL.isValid() );
 
+  ATH_CHECK( previousDecisionIDs.size() == legDecisionIds().size() );
+  for (size_t i = 0; i < previousDecisionIDs.size(); ++i) {
+    if (!TrigCompositeUtils::passed(legDecisionId(i).numeric(), *previousDecisionIDs[i])) {
+      ATH_MSG_DEBUG( "Didn't pass previous decision: " << legDecisionId(i) );
+      return StatusCode::SUCCESS;
+    }
   }
 
-}
+  if (passed(*trigBphysEL)) {
+    TrigCompositeUtils::addDecisionID(decisionId(), decision);
+  }
 
+  return StatusCode::SUCCESS;
+}
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h
new file mode 100644
index 000000000000..d53ad64b2fc2
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**************************************************************************
+ **
+ **   File: Trigger/TrigHypothesis/TrigBphysHypo/TrigMultiTrkComboHypoTool.h
+ **
+ **   Description: multi-track hypothesis tool
+ **
+ **   Author: Heather Russell
+ **
+ **************************************************************************/
+
+#ifndef TRIG_TrigMultiTrkComboHypoTool_H
+#define TRIG_TrigMultiTrkComboHypoTool_H
+
+#include <string>
+#include <vector>
+
+#include "DecisionHandling/ComboHypoToolBase.h"
+
+#include "xAODTrigBphys/TrigBphys.h"
+#include "xAODTrigBphys/TrigBphysContainer.h"
+
+#include "TrigCompositeUtils/HLTIdentifier.h"
+#include "TrigCompositeUtils/TrigCompositeUtils.h"
+
+#include "AthenaMonitoringKernel/Monitored.h"
+#include "AthenaMonitoringKernel/GenericMonitoringTool.h"
+
+using TrigCompositeUtils::Decision;
+using TrigCompositeUtils::DecisionIDContainer;
+
+
+class TrigMultiTrkComboHypoTool: public ComboHypoToolBase {
+ public:
+  TrigMultiTrkComboHypoTool(const std::string& type, const std::string& name, const IInterface* parent);
+  virtual StatusCode initialize() override;
+  virtual StatusCode decideOnSingleObject(Decision*, const std::vector<DecisionIDContainer*>&) const override;
+
+ private:
+  bool passed(const xAOD::TrigBphys*) const;
+  virtual bool executeAlg(std::vector<LegDecision>&) const override { return true; }
+
+
+  // Mass window cuts
+  Gaudi::Property<int> m_nTrk { this, "nTrk",2,"Number of tracks in the vertex"};
+  Gaudi::Property< int > m_TotChargeCut{this, "TotChargeCut", 0, "The Magnitude of the total charge to accept, negative is none" };
+  Gaudi::Property< float > m_lowerMassCut{this, "LowerMassCut", -99. , "Lower mass cut for vertex " };
+  Gaudi::Property< float > m_upperMassCut{this, "UpperMassCut", -99. , "Upper mass cut for vertex" };
+  Gaudi::Property< bool >m_applyUpperMassCut{this, "ApplyUpperMassCut", false, "Apply the upper mass cut" };
+  Gaudi::Property< bool > m_applyChi2Cut{this, "ApplyChi2Cut", false, "Apply a chi2 cut to vertex" };
+  Gaudi::Property< float > m_chi2VtxCut{this, "Chi2VtxCut", -99. , "Chi2 cut for vertex (0 < chi2 < cut)" };
+  Gaudi::Property<std::vector<float>> m_ptTrkMin { this, "trkPtThresholds", {3650, 3650} ,"minimum track pTs (one per track, sorted descending!)"};
+
+  // to set Accept-All mode: should be done with force-accept when possible
+  Gaudi::Property< bool > m_acceptAll {this, "AcceptAll", false, "Ignore selection" };
+
+  ToolHandle<GenericMonitoringTool> m_monTool { this, "MonTool", "", "Monitoring tool" };
+
+};
+
+#endif  // TRIG_TrigMultiTrkComboHypoTool_H
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.h b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.h
deleted file mode 100644
index 96b480c48d4e..000000000000
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkHypoTool.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-*/
-
-/**************************************************************************
- **
- **   File: Trigger/TrigHypothesis/TrigBphysHypo/TrigMultiTrkHypoTool.h
- **
- **   Description: multi track hypothesis tool
- **
- **   Author: H. Russell
- **
- **************************************************************************/
-
-#ifndef TRIG_TrigMultiTrkHypoTool_H
-#define TRIG_TrigMultiTrkHypoTool_H
-
-// standard stuff
-#include <string>
-// general athena stuff
-#include "GaudiKernel/MsgStream.h"
-#include "GaudiKernel/IToolSvc.h"
-#include "GaudiKernel/StatusCode.h"
-
-#include "Constants.h"
-
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "TrigCompositeUtils/HLTIdentifier.h"
-#include "CLHEP/Units/SystemOfUnits.h"
-
-#include "xAODTrigBphys/TrigBphys.h"
-#include "xAODTrigBphys/TrigBphysContainer.h"
-
-#include "TrigCompositeUtils/TrigCompositeUtils.h"
-#include "AthenaMonitoringKernel/GenericMonitoringTool.h"
-
-#include "TrigCompositeUtils/Combinators.h"
-
-
-class TrigMultiTrkHypoTool: public ::AthAlgTool  {
-  enum { MaxNumberTools = 20 };
-  public:
-    TrigMultiTrkHypoTool(const std::string& type,
-                       const std::string & name,
-                       const IInterface* parent );
-
-    virtual ~TrigMultiTrkHypoTool();
-
-    struct TrigMultiTrkInfo {
-    TrigMultiTrkInfo( TrigCompositeUtils::Decision* d, const xAOD::TrigBphys* c,
-                     const TrigCompositeUtils::DecisionIDContainer previousDecisionIDs0,
-                     const TrigCompositeUtils::DecisionIDContainer previousDecisionIDs1 )
-    : decision( d ),
-      trigBphys( c ),
-      previousDecisionIDs0 ( previousDecisionIDs0 ),
-      previousDecisionIDs1( previousDecisionIDs1 )
-
-      {}
-
-      TrigCompositeUtils::Decision* decision;
-      const xAOD::TrigBphys* trigBphys;
-      const TrigCompositeUtils::DecisionIDContainer previousDecisionIDs0;
-      const TrigCompositeUtils::DecisionIDContainer previousDecisionIDs1;
-
-    };
-
-    virtual StatusCode initialize() override;
-    virtual StatusCode decide(std::vector<TrigMultiTrkHypoTool::TrigMultiTrkInfo>& toolInput) const;
-    bool decideOnSingleObject(const xAOD::TrigBphys* trigBphys, size_t cutIndex) const;
-    StatusCode inclusiveSelection(std::vector<TrigMultiTrkHypoTool::TrigMultiTrkInfo>& toolInput) const;
-
-  private:
-
-    HLT::Identifier m_decisionId;
-
-
-    // Mass window cuts
-    Gaudi::Property<int> m_nTrk { this, "nTrk",2,"Number of tracks in the vertex"};
-    Gaudi::Property< int > m_TotChargeCut{this, "TotChargeCut", 0, "The Magnitude of the total charge to accept, negative is none" };
-    Gaudi::Property< float > m_lowerMassCut{this, "LowerMassCut", -99. , "Lower mass cut for vertex " };
-    Gaudi::Property< float > m_upperMassCut{this, "UpperMassCut", -99. , "Upper mass cut for vertex" };
-    Gaudi::Property< bool >m_applyUpperMassCut{this, "ApplyUpperMassCut", false, "Apply the upper mass cut" };
-    Gaudi::Property< bool > m_applyChi2Cut{this, "ApplyChi2Cut", false, "Apply a chi2 cut to vertex" };
-    Gaudi::Property< float > m_chi2VtxCut{this, "Chi2VtxCut", -99. , "Chi2 cut for vertex (0 < chi2 < cut)" };
-    Gaudi::Property< int > m_nBphysObjects {this, "nBphysObjects", 1, "Number of good b-phys objects required per event" };
-    Gaudi::Property<std::vector<float>> m_ptTrkMin { this, "trkPtThresholds", {3650, 3650} ,"minimum track pTs (one per track, sorted descending!)"};
-
-    // to set Accept-All mode: should be done with force-accept when possible
-    Gaudi::Property< bool > m_acceptAll {this, "AcceptAll", false, "Ignore selection" };
-
-    ToolHandle< GenericMonitoringTool > m_monTool { this, "MonTool", "", "Monitoring tool" };
-
-};
-
-#endif  // TRIG_TrigMultiTrkHypoTool_H
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/components/TrigBphysHypo_entries.cxx b/Trigger/TrigHypothesis/TrigBphysHypo/src/components/TrigBphysHypo_entries.cxx
index 46c8d1f3b602..7f303c13b493 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/components/TrigBphysHypo_entries.cxx
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/components/TrigBphysHypo_entries.cxx
@@ -31,8 +31,8 @@
 #include "../TrigEFMultiMuFex.h"
 #include "../TrigEFTrkMassFex.h"
 
-#include "src/TrigMultiTrkHypo.h"
-#include "src/TrigMultiTrkHypoTool.h"
+#include "src/TrigMultiTrkComboHypo.h"
+#include "src/TrigMultiTrkComboHypoTool.h"
 
 //#include "../TrigBphysL1DiMuComboFex.h"
 
@@ -69,6 +69,6 @@ DECLARE_COMPONENT( TrigBphysMuonCounter )
 DECLARE_COMPONENT( TrigBphysTrackRoiMaker )
 DECLARE_COMPONENT( TrigBphysElectronCounter )
 //DECLARE_COMPONENT( TrigBphysL1DiMuComboFex )
-DECLARE_COMPONENT( TrigMultiTrkHypo )
-DECLARE_COMPONENT( TrigMultiTrkHypoTool )
+DECLARE_COMPONENT( TrigMultiTrkComboHypo )
+DECLARE_COMPONENT( TrigMultiTrkComboHypoTool )
 
diff --git a/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py b/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py
index 29aaed95227e..3cb153251df0 100755
--- a/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py
+++ b/Trigger/TrigHypothesis/TrigMuonHypoMT/python/TrigMuonHypoMTConfig.py
@@ -403,7 +403,12 @@ def TrigmuCombHypoToolFromDict( chainDict ):
     config = TrigmuCombHypoConfig()
 
     tight = False # can be probably decoded from some of the proprties of the chain, expert work
-    tool=config.ConfigurationHypoTool( chainDict['chainName'], thresholds, tight )
+
+    acceptAll = False
+    if chainDict['chainParts'][0]['signature'] == 'Bphysics':
+        acceptAll = True
+
+    tool=config.ConfigurationHypoTool( chainDict['chainName'], thresholds, tight, acceptAll )
 
     addMonitoring( tool, TrigmuCombHypoMonitoring, "TrigmuCombHypoTool", chainDict['chainName'] )
 
@@ -413,9 +418,10 @@ class TrigmuCombHypoConfig(object):
 
     log = logging.getLogger('TrigmuCombHypoConfig')
 
-    def ConfigurationHypoTool( self, thresholdHLT, thresholds, tight ):
+    def ConfigurationHypoTool( self, thresholdHLT, thresholds, tight, acceptAll ):
 
         tool = CompFactory.TrigmuCombHypoTool( thresholdHLT )
+        tool.AcceptAll = acceptAll
 
         nt = len(thresholds)
         log.debug('Set %d thresholds', nt)
diff --git a/Trigger/TrigMonitoring/TrigBphysMonitoring/python/TrigBphysMonitorAlgorithm.py b/Trigger/TrigMonitoring/TrigBphysMonitoring/python/TrigBphysMonitorAlgorithm.py
index 072cd0e8f0a0..b0b5b30958f1 100644
--- a/Trigger/TrigMonitoring/TrigBphysMonitoring/python/TrigBphysMonitorAlgorithm.py
+++ b/Trigger/TrigMonitoring/TrigBphysMonitoring/python/TrigBphysMonitorAlgorithm.py
@@ -56,7 +56,7 @@ def TrigBphysMonConfig(inputFlags):
     #trigBphysMonAlg.TriggerChain = 'HLT_mu26_ivarmedium'
     #trigBphysMonAlg.TriggerChain = 'HLT_e24_lhtight_nod0'
     monitored_chains = ['HLT_2mu10_bJpsimumu_L12MU10', 'HLT_2mu10_bUpsimumu_L12MU10']
-    monitored_containers = ['TrigBphysDimu', 'TrigBphysEFDimu']
+    monitored_containers = ['HLT_DimuEF']
     trigBphysMonAlg.MonitoredChains = monitored_chains
     trigBphysMonAlg.MonitoredContainers = monitored_containers
 
diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/ComboHypo.h
similarity index 82%
rename from Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h
rename to Trigger/TrigSteer/DecisionHandling/DecisionHandling/ComboHypo.h
index 60833c41053a..ef7151cc8476 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.h
+++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/ComboHypo.h
@@ -11,7 +11,7 @@
 // STL includes
 #include <string>
 #include <utility>  
-#include "ComboHypoToolBase.h"
+#include "DecisionHandling/ComboHypoToolBase.h"
 
 /**
  * @class ComboHypo for combined hypotheses required only counting (multiplicity requirements)
@@ -26,7 +26,7 @@
 
 
 class ComboHypo : public ::AthReentrantAlgorithm {
-public:
+ public:
   ComboHypo(const std::string& name, ISvcLocator* pSvcLocator);
   virtual ~ComboHypo() override;
 
@@ -34,7 +34,15 @@ public:
   virtual StatusCode execute(const EventContext& context) const override;
   virtual StatusCode finalize() override;
 
-private:
+ protected:
+  const SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionsInput() const { return m_inputs; }
+  const SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionsOutput() const { return m_outputs; }
+  typedef std::map<std::string, std::vector<int>> MultiplicityReqMap;
+  const MultiplicityReqMap& triggerMultiplicityMap() const { return m_multiplicitiesReqMap.value(); }
+  ToolHandleArray<ComboHypoToolBase>& hypoTools() { return m_hypoTools; }
+  const ToolHandleArray<ComboHypoToolBase>& hypoTools() const { return m_hypoTools; }
+
+ private:
 
   SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_inputs { this, "HypoInputDecisions", {}, "Input Decisions" };
   SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_outputs { this, "HypoOutputDecisions", {}, "Ouput Decisions" };
@@ -42,10 +50,12 @@ private:
   Gaudi::Property<bool> m_requireUniqueROI {this, "RequireUniqueROI", false,
     "Require each Feature in each leg of the combination to come from a unique L1 seeding ROI."};
 
-  typedef std::map<std::string, std::vector<int>> MultiplicityReqMap;
   Gaudi::Property< MultiplicityReqMap > m_multiplicitiesReqMap{this, "MultiplicitiesMap", {}, 
     "Map from the chain name to multiplicities required at each input"};
 
+  Gaudi::Property<bool> m_checkMultiplicityMap { this, "CheckMultiplicityMap", true,
+    "Perform a consistency check of the MultiplicitiesMap"};
+
   /**
   * @brief iterates over the inputs and for every object (no filtering) crates output object linked to input moving 
   * the decisions that are mentioned in the passing set
diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/ComboHypoToolBase.h
similarity index 85%
rename from Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.h
rename to Trigger/TrigSteer/DecisionHandling/DecisionHandling/ComboHypoToolBase.h
index e19ea90d4c86..a9937ad8ba42 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.h
+++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/ComboHypoToolBase.h
@@ -5,7 +5,7 @@
 #define DECISIONHANDLING_COMBOHYPOTOOLBASE_H
 
 // Package includes
-#include "IComboHypoTool.h"
+#include "DecisionHandling/IComboHypoTool.h"
 
 // Framework includes
 #include "AthenaBaseComps/AthAlgTool.h"
@@ -14,6 +14,7 @@
 
 // STL includes
 #include <string>
+#include <vector>
 
 /**
  * @class ComboHypoToolBase
@@ -34,12 +35,16 @@ public:
   **/  
   virtual StatusCode decide(LegDecisionsMap & passingLegs, const EventContext& /* ctx */ ) const override;
   
+  virtual StatusCode decideOnSingleObject(TrigCompositeUtils::Decision*, const std::vector<TrigCompositeUtils::DecisionIDContainer*>&) const { return StatusCode::SUCCESS; }
   
   /**
    * @brief retrieves this decision Id
    **/
-  virtual HLT::Identifier decisionId() const { return m_decisionId; } 
+  virtual HLT::Identifier decisionId() const { return m_decisionId; }
 
+  void setLegDecisionIds(const std::vector<HLT::Identifier>& legDecisionIds) { m_legDecisionIds = legDecisionIds; }
+  HLT::Identifier legDecisionId(size_t i) const { return m_legDecisionIds.at(i); }
+  const std::vector<HLT::Identifier>& legDecisionIds() const { return m_legDecisionIds; }
     
  protected:
 
@@ -105,8 +110,8 @@ public:
   
 private:
 
-    HLT::Identifier m_decisionId;
-    
+  HLT::Identifier m_decisionId;
+  std::vector<HLT::Identifier> m_legDecisionIds;
 
 };
 
diff --git a/Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/IComboHypoTool.h
similarity index 100%
rename from Trigger/TrigSteer/DecisionHandling/src/IComboHypoTool.h
rename to Trigger/TrigSteer/DecisionHandling/DecisionHandling/IComboHypoTool.h
diff --git a/Trigger/TrigSteer/DecisionHandling/python/DecisionHandlingConfig.py b/Trigger/TrigSteer/DecisionHandling/python/DecisionHandlingConfig.py
index f1890347b73e..8fa029189db3 100644
--- a/Trigger/TrigSteer/DecisionHandling/python/DecisionHandlingConfig.py
+++ b/Trigger/TrigSteer/DecisionHandling/python/DecisionHandlingConfig.py
@@ -26,3 +26,8 @@ def TriggerSummaryAlg( name ):
                                    xbins=100, xmin=0, xmax=3.5e3   )
     alg.MonTool = monTool
     return alg
+
+def ComboHypoCfg( name ):
+    from DecisionHandling.DecisionHandlingConf import ComboHypo
+    alg = ComboHypo( name )
+    return alg
diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx
index 68afffcdf052..88ec47e71fac 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx
+++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypo.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "ComboHypo.h"
+#include "DecisionHandling/ComboHypo.h"
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "TrigSteeringEvent/TrigRoiDescriptorCollection.h"
@@ -57,12 +57,14 @@ StatusCode ComboHypo::initialize() {
   ATH_CHECK( m_multiplicitiesReqMap.size() != 0 );
 
   bool errorOccured = false;
-  for ( const auto& m : m_multiplicitiesReqMap ) {
-    if ( m.second.size() != maxMult )  {
-      errorOccured =  true;
-      ATH_MSG_ERROR( "Chain " << m.first 
-        << " configured with input multiplicity " << m.second.size() << " like this: " <<  m.second 
-        << " which is lower than for this chain " << maxMultEl->first <<  " " << maxMult);
+  if (m_checkMultiplicityMap) {
+    for ( const auto& m : m_multiplicitiesReqMap ) {
+      if ( m.second.size() != maxMult )  {
+        errorOccured =  true;
+        ATH_MSG_ERROR( "Chain " << m.first
+          << " configured with input multiplicity " << m.second.size() << " like this: " << m.second
+          << " which is lower than for this chain " << maxMultEl->first << " " << maxMult);
+      }
     }
   }
 
diff --git a/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx b/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx
index 09dbb94a1a9d..613e380f5cf0 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx
+++ b/Trigger/TrigSteer/DecisionHandling/src/ComboHypoToolBase.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "ComboHypoToolBase.h"
+#include "DecisionHandling/ComboHypoToolBase.h"
 using namespace TrigCompositeUtils;
 
 
diff --git a/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h b/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h
index 2e55844205a3..d548f6c4b02d 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h
+++ b/Trigger/TrigSteer/DecisionHandling/src/DeltaRRoIComboHypoTool.h
@@ -9,7 +9,7 @@
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
-#include "ComboHypoToolBase.h"
+#include "DecisionHandling/ComboHypoToolBase.h"
 
 class DeltaRRoIComboHypoTool:  public ComboHypoToolBase {
 
diff --git a/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx b/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx
index e55e57d985d6..e891afb5dad9 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx
+++ b/Trigger/TrigSteer/DecisionHandling/src/components/DecisionHandling_entries.cxx
@@ -1,10 +1,10 @@
 #include "../DumpDecisions.h"
 #include "../RoRSeqFilter.h"
 #include "../TriggerSummaryAlg.h"
-#include "../ComboHypo.h"
+#include "DecisionHandling/ComboHypo.h"
 #include "../InputMakerForRoI.h"
 #include "../DeltaRRoIComboHypoTool.h"
-#include "../ComboHypoToolBase.h"
+#include "DecisionHandling/ComboHypoToolBase.h"
 
 DECLARE_COMPONENT( DumpDecisions )
 DECLARE_COMPONENT( RoRSeqFilter )
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref
index c41c2ee7def9..e7fd62710811 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref
@@ -25,12 +25,27 @@ TrigSignatureMoniMT                                INFO -- #1295975955 Features
 TrigSignatureMoniMT                                INFO HLT_2j60_L1J15 #927735533
 TrigSignatureMoniMT                                INFO -- #927735533 Events          20         20         10         -          -          -          -          -          10
 TrigSignatureMoniMT                                INFO -- #927735533 Features                              28         -          -          -          -          -
+TrigSignatureMoniMT                                INFO HLT_2mu10_bJpsimumu_L12MU10 #3498558358
+TrigSignatureMoniMT                                INFO -- #3498558358 Events         3          3          3          3          3          2          -          -          0
+TrigSignatureMoniMT                                INFO -- #3498558358 Features                             12         12         16         4          -          -
+TrigSignatureMoniMT                                INFO HLT_2mu10_bUpsimumu_L12MU10 #234102568
+TrigSignatureMoniMT                                INFO -- #234102568 Events          3          3          3          3          3          2          -          -          0
+TrigSignatureMoniMT                                INFO -- #234102568 Features                              12         12         16         4          -          -
 TrigSignatureMoniMT                                INFO HLT_2mu14_L12MU10 #2619091790
 TrigSignatureMoniMT                                INFO -- #2619091790 Events         3          3          3          1          1          1          -          -          1
 TrigSignatureMoniMT                                INFO -- #2619091790 Features                             12         4          4          4          -          -
 TrigSignatureMoniMT                                INFO HLT_2mu15_L12MU10 #557204938
 TrigSignatureMoniMT                                INFO -- #557204938 Events          3          3          3          1          1          1          -          -          1
 TrigSignatureMoniMT                                INFO -- #557204938 Features                              12         4          4          4          -          -
+TrigSignatureMoniMT                                INFO HLT_2mu4_bDimu_L12MU4 #1730084172
+TrigSignatureMoniMT                                INFO -- #1730084172 Events         4          4          4          4          4          4          -          -          1
+TrigSignatureMoniMT                                INFO -- #1730084172 Features                             16         16         24         11         -          -
+TrigSignatureMoniMT                                INFO HLT_2mu4_bJpsimumu_L12MU4 #4276347155
+TrigSignatureMoniMT                                INFO -- #4276347155 Events         4          4          4          4          4          4          -          -          1
+TrigSignatureMoniMT                                INFO -- #4276347155 Features                             16         16         24         11         -          -
+TrigSignatureMoniMT                                INFO HLT_2mu4_bUpsimumu_L12MU4 #4008168535
+TrigSignatureMoniMT                                INFO -- #4008168535 Events         4          4          4          4          4          4          -          -          0
+TrigSignatureMoniMT                                INFO -- #4008168535 Features                             16         16         24         10         -          -
 TrigSignatureMoniMT                                INFO HLT_2mu4_muonqual_L12MU4 #1584776935
 TrigSignatureMoniMT                                INFO -- #1584776935 Events         4          4          4          4          4          4          -          -          4
 TrigSignatureMoniMT                                INFO -- #1584776935 Features                             16         16         24         20         -          -
@@ -295,6 +310,12 @@ TrigSignatureMoniMT                                INFO -- #782182242 Features
 TrigSignatureMoniMT                                INFO HLT_mu10_lateMu_L1MU10 #48780310
 TrigSignatureMoniMT                                INFO -- #48780310 Events           10         10         0          0          -          -          -          -          0
 TrigSignatureMoniMT                                INFO -- #48780310 Features                               0          0          -          -          -          -
+TrigSignatureMoniMT                                INFO HLT_mu11_mu6_bJpsimumu_L1MU11_2MU6 #2504965945
+TrigSignatureMoniMT                                INFO -- #2504965945 Events         4          4          4          0          3          0          -          -          0
+TrigSignatureMoniMT                                INFO -- #2504965945 Features                             8          0          6          0          -          -
+TrigSignatureMoniMT                                INFO HLT_mu11_mu6_bUpsimumu_L1MU11_2MU6 #1171632195
+TrigSignatureMoniMT                                INFO -- #1171632195 Events         4          4          4          0          3          0          -          -          0
+TrigSignatureMoniMT                                INFO -- #1171632195 Features                             8          0          6          0          -          -
 TrigSignatureMoniMT                                INFO HLT_mu14_L1MU10 #1696906927
 TrigSignatureMoniMT                                INFO -- #1696906927 Events         10         10         10         7          7          7          -          -          7
 TrigSignatureMoniMT                                INFO -- #1696906927 Features                             13         8          8          8          -          -
@@ -473,17 +494,3 @@ TrigSignatureMoniMT                                INFO HLT_xe30_mht_L1XE10 #362
 TrigSignatureMoniMT                                INFO -- #3626903018 Events         19         19         19         -          -          -          -          -          19
 TrigSignatureMoniMT                                INFO -- #3626903018 Features                             19         -          -          -          -          -
 TrigSignatureMoniMT                                INFO HLT_xe30_pfsum_L1XE10 #998713382
-TrigSignatureMoniMT                                INFO -- #998713382 Events          19         19         14         -          -          -          -          -          14
-TrigSignatureMoniMT                                INFO -- #998713382 Features                              14         -          -          -          -          -
-TrigSignatureMoniMT                                INFO HLT_xe30_tcpufit_L1XE10 #1583719916
-TrigSignatureMoniMT                                INFO -- #1583719916 Events         19         19         15         -          -          -          -          -          15
-TrigSignatureMoniMT                                INFO -- #1583719916 Features                             15         -          -          -          -          -
-TrigSignatureMoniMT                                INFO HLT_xe30_trkmht_L1XE10 #2468872349
-TrigSignatureMoniMT                                INFO -- #2468872349 Events         19         19         17         -          -          -          -          -          17
-TrigSignatureMoniMT                                INFO -- #2468872349 Features                             17         -          -          -          -          -
-TrigSignatureMoniMT                                INFO HLT_xe65_cell_L1XE50 #531141817
-TrigSignatureMoniMT                                INFO -- #531141817 Events          10         10         7          -          -          -          -          -          7
-TrigSignatureMoniMT                                INFO -- #531141817 Features                              7          -          -          -          -          -
-TrigSignatureMoniMT                                INFO HLT_xe65_cell_xe110_tcpufit_L1XE50 #115518400
-TrigSignatureMoniMT                                INFO -- #115518400 Events          10         10         3          -          -          -          -          -          3
-TrigSignatureMoniMT                                INFO -- #115518400 Features                              3          -          -          -          -          -
diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
index b1dadbd58aa0..ee9c79c3f970 100644
--- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
@@ -25,12 +25,27 @@ TrigSignatureMoniMT                                 INFO -- #1295975955 Features
 TrigSignatureMoniMT                                 INFO HLT_2j60_L1J15 #927735533
 TrigSignatureMoniMT                                 INFO -- #927735533 Events          20         20         0          -          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #927735533 Features                              0          -          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu10_bJpsimumu_L12MU10 #3498558358
+TrigSignatureMoniMT                                 INFO -- #3498558358 Events         20         20         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #3498558358 Features                             0          0          0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu10_bUpsimumu_L12MU10 #234102568
+TrigSignatureMoniMT                                 INFO -- #234102568 Events          20         20         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #234102568 Features                              0          0          0          0          -          -          
 TrigSignatureMoniMT                                 INFO HLT_2mu14_L12MU10 #2619091790
 TrigSignatureMoniMT                                 INFO -- #2619091790 Events         20         20         0          0          0          0          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #2619091790 Features                             0          0          0          0          -          -          
 TrigSignatureMoniMT                                 INFO HLT_2mu15_L12MU10 #557204938
 TrigSignatureMoniMT                                 INFO -- #557204938 Events          20         20         0          0          0          0          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #557204938 Features                              0          0          0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu4_bDimu_L12MU4 #1730084172
+TrigSignatureMoniMT                                 INFO -- #1730084172 Events         20         20         1          1          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #1730084172 Features                             4          2          0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu4_bJpsimumu_L12MU4 #4276347155
+TrigSignatureMoniMT                                 INFO -- #4276347155 Events         20         20         1          1          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #4276347155 Features                             4          2          0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_2mu4_bUpsimumu_L12MU4 #4008168535
+TrigSignatureMoniMT                                 INFO -- #4008168535 Events         20         20         1          1          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #4008168535 Features                             4          2          0          0          -          -          
 TrigSignatureMoniMT                                 INFO HLT_2mu4_muonqual_L12MU4 #1584776935
 TrigSignatureMoniMT                                 INFO -- #1584776935 Events         20         20         1          0          0          0          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1584776935 Features                             4          0          0          0          -          -          
@@ -307,6 +322,12 @@ TrigSignatureMoniMT                                 INFO -- #782182242 Features
 TrigSignatureMoniMT                                 INFO HLT_mu10_lateMu_L1MU10 #48780310
 TrigSignatureMoniMT                                 INFO -- #48780310 Events           20         20         0          0          -          -          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #48780310 Features                               0          0          -          -          -          -          
+TrigSignatureMoniMT                                 INFO HLT_mu11_mu6_bJpsimumu_L1MU11_2MU6 #2504965945
+TrigSignatureMoniMT                                 INFO -- #2504965945 Events         20         20         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #2504965945 Features                             0          0          0          0          -          -          
+TrigSignatureMoniMT                                 INFO HLT_mu11_mu6_bUpsimumu_L1MU11_2MU6 #1171632195
+TrigSignatureMoniMT                                 INFO -- #1171632195 Events         20         20         0          0          0          0          -          -          0          
+TrigSignatureMoniMT                                 INFO -- #1171632195 Features                             0          0          0          0          -          -          
 TrigSignatureMoniMT                                 INFO HLT_mu14_L1MU10 #1696906927
 TrigSignatureMoniMT                                 INFO -- #1696906927 Events         20         20         1          1          0          0          -          -          0          
 TrigSignatureMoniMT                                 INFO -- #1696906927 Features                             1          1          0          0          -          -          
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index d906b3e35bd6..0a7c6c38b6dd 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -144,8 +144,8 @@ TriggerHLTListRun3 = [
     ('xAOD::TrackParticleContainer#HLT_IDTrack_Muon_FTF',                 'BS ESD AODFULL', 'Muon', 'inViews:MUCombViewRoIs'),
     ('xAOD::TrackParticleAuxContainer#HLT_IDTrack_Muon_FTFAux.',          'BS ESD AODFULL', 'Muon'),
 
-    ('xAOD::TrackParticleContainer#HLT_IDTrack_Muon_IDTrig',                 'BS ESD AODFULL', 'Muon', 'inViews:MUEFCBViewRoIs'),
-    ('xAOD::TrackParticleAuxContainer#HLT_IDTrack_Muon_IDTrigAux.',          'BS ESD AODFULL', 'Muon'),
+    ('xAOD::TrackParticleContainer#HLT_IDTrack_Muon_IDTrig',                 'BS ESD AODFULL AODSLIM', 'Muon', 'inViews:MUEFCBViewRoIs'),
+    ('xAOD::TrackParticleAuxContainer#HLT_IDTrack_Muon_IDTrigAux.',          'BS ESD AODFULL AODSLIM', 'Muon'),
 
     ('xAOD::TrackParticleContainer#HLT_IDTrack_MuonFS_FTF',                 'BS ESD AODFULL', 'Muon', 'inViews:MUCBFSViews'),
     ('xAOD::TrackParticleAuxContainer#HLT_IDTrack_MuonFS_FTFAux.',          'BS ESD AODFULL', 'Muon'),
@@ -167,10 +167,8 @@ TriggerHLTListRun3 = [
 
 
     # bphys
-    ('xAOD::TrigBphysContainer#TrigBphysDimu',                              'BS ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'Bphys'),
-    ('xAOD::TrigBphysAuxContainer#TrigBphysDimuAux.',                       'BS ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'Bphys'),
-    ('xAOD::TrigBphysContainer#TrigBphysEFDimu',                            'BS ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'Bphys'),
-    ('xAOD::TrigBphysAuxContainer#TrigBphysEFDimuAux.',                     'BS ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'Bphys'),
+    ('xAOD::TrigBphysContainer#HLT_DimuEF',                                 'BS ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'Bphys'),
+    ('xAOD::TrigBphysAuxContainer#HLT_DimuEFAux.',                          'BS ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'Bphys'),
 
     # xAOD muons (msonly (x2: roi+FS), combined (x3: FS+RoI (outside-in, inside-out+outside-in))
     ('xAOD::MuonContainer#HLT_Muons_RoI',                                       'BS ESD AODFULL', 'Muon', 'inViews:MUEFSAViewRoIs'),
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsDef.py
index 23a25fa3fe65..c7e74de4f0ee 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsDef.py
@@ -9,97 +9,72 @@ from AthenaCommon.Logging import logging
 logging.getLogger().info("Importing %s",__name__)
 log = logging.getLogger("TriggerMenuMT.HLTMenuConfig.Bphysics.BphysicsDef")
 
-from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase, RecoFragmentsPool
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import ChainStep
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase import ChainConfigurationBase
 from TriggerMenuMT.HLTMenuConfig.Muon.MuonDef import MuonChainConfiguration as MuonChainConfiguration
 
-from TriggerMenuMT.HLTMenuConfig.Bphysics.BphysicsSequenceSetup import dimuL2Sequence,dimuEFSequence
-
+from TriggerMenuMT.HLTMenuConfig.Muon.MuonDef import muCombSequenceCfg, muEFCBSequenceCfg
+from TrigBphysHypo.TrigMultiTrkComboHypoConfig import DimuL2ComboHypoCfg, DimuEFComboHypoCfg, TrigMultiTrkComboHypoToolFromDict
 
 #--------------------------------------------------------
 # fragments generating config will be functions in new JO
 # I have no idea what the above sentence means - copy/paste from muons...
 #--------------------------------------------------------
 
-def dimuL2SequenceCfg(flags):
-    return dimuL2Sequence()
-    
-def dimuEFSequenceCfg(flags):
-    return dimuEFSequence()
 
-############################################# 
-###  Class/function to configure muon chains 
+#############################################
+###  Class/function to configure muon chains
 #############################################
 
 class BphysicsChainConfiguration(MuonChainConfiguration):
 
     def __init__(self, chainDict):
         ChainConfigurationBase.__init__(self,chainDict)
-       
+
     # ----------------------
     # Assemble the chain depending on information from chainName
     # ----------------------
-    def assembleBphysChain(self):                            
-        chainSteps = []
+    def assembleBphysChain(self):
+
         log.debug("Assembling chain for " + self.chainName)
 
-        muonStepDictionary = self.getStepDictionary()
-        bphysStepDictionary = self.getBphysStepDictionary()
-         
-        #infrastructure cannot deal with having more than one "key" here
-        #if we have noL2Comb+extra, this needs to be defined in the muonStepDictionary
-        mu_key = 'noL2Comb'+self.chainPart['extra']+self.chainPart['isoInfo']
-        
-        bphys_key = self.getBphysKey()
-        
-        muon_steps = muonStepDictionary[mu_key]
-        bphys_steps = bphysStepDictionary[bphys_key]
-
-        for mu_step_level, bphys_step_level in zip(muon_steps, bphys_steps):
-            for step in mu_step_level:
-                chainstep = getattr(self, step)()
-                chainSteps += [chainstep]
-            for step in bphys_step_level:
-                chainSteps += [step]
-
-
-        myChain = self.buildChain(chainSteps)
-        return myChain
+        stepDictionary = self.getBphysStepDictionary()
+        key = self.getBphysKey()
+        steps=stepDictionary[key]
+
+        chainSteps = []
+        for step_level in steps:
+            for step in step_level:
+                chainStep = getattr(self, step)()
+                chainSteps+=[chainStep]
+
+        chain = self.buildChain(chainSteps)
+        return chain
 
     def getBphysStepDictionary(self):
-        
+
         stepDictionary = {
-            "dimu":[[self.getdimuL2()], [self.getdimuEF()]],
+            'dimu' : [['getmuFast', 'getDimuComb'], ['getmuEFSA', 'getDimuEFCB']],
         }
-        
         return stepDictionary
-        
+
     def getBphysKey(self):
-    
+
         if len(self.dict['topo']) > 1:
             log.warning("BphysicsChainConfiguration.getBphysKey is not setup for > 1 topo! will use the first one.")
 
         the_topo = self.dict['topo'][0]
-        
+
         topo_dict = {
             'bJpsimumu' : 'dimu',
             'bUpsimumu' : 'dimu',
             'bBmumu'    : 'dimu',
             'bDimu'     : 'dimu'
-        }   
-        
-        return topo_dict[the_topo] 
-    
-    # --------------------
-    def getdimuL2(self):
-        stepName = 'Step2_l2Dimu'
-        log.debug("Configuring step " + stepName)
-        bphySeq = RecoFragmentsPool.retrieve( dimuL2SequenceCfg, None)
-        return ChainStep(stepName, [bphySeq], multiplicity=[1])
-
-    def getdimuEF(self):
-        stepName = 'Step5_efDimu'
-        log.debug("Configuring step " + stepName)
-        bphySeq = RecoFragmentsPool.retrieve( dimuEFSequenceCfg, None)
-        return ChainStep(stepName, [bphySeq], multiplicity=[1])
+        }
+
+        return topo_dict[the_topo]
+
+    def getDimuComb(self):
+        return self.getStep(2, 'dimuComb', [muCombSequenceCfg], comboHypoCfg=DimuL2ComboHypoCfg)
 
+    def getDimuEFCB(self):
+        return self.getStep(4, 'dimuEFCB', [muEFCBSequenceCfg], comboHypoCfg=DimuEFComboHypoCfg, comboTools=[TrigMultiTrkComboHypoToolFromDict])
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py
index d20b32d7a32a..f2f0fc1b7b48 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py
@@ -1,60 +1 @@
 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
-
-from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool
-from AthenaConfiguration.AllConfigFlags import ConfigFlags
-
-
-def dimuL2Sequence(name = 'Dimu'):
-    from TriggerMenuMT.HLTMenuConfig.Muon.MuonSequenceSetup import muCombAlgSequence
-    (l2muCombSequence, l2muCombViewsMaker, sequenceOut) = RecoFragmentsPool.retrieve(muCombAlgSequence, ConfigFlags)
-
-    from TrigBphysHypo.TrigMultiTrkHypoConfig import TrigMultiTrkHypoConfig, TrigMultiTrkHypoToolFromDict
-    config = TrigMultiTrkHypoConfig()
-    DimuHypo = config.ConfigurationHypo(
-        trigSequenceName = name,
-        trigLevel = 'L2',
-        trackCollection='HLT_IDTrack_Muon_FTF')
-
-    return MenuSequence(
-        Sequence = l2muCombSequence,
-        Maker = l2muCombViewsMaker,
-        Hypo = DimuHypo,
-        HypoToolGen = TrigMultiTrkHypoToolFromDict)
-
-
-def dimuEFSequence(name = 'Dimu'):
-    from AthenaCommon import CfgMgr
-    from AthenaCommon.CFElements import parOR, seqAND
-    from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool
-    from TriggerMenuMT.HLTMenuConfig.Muon.MuonSetup import muonNames
-
-    muNames = muonNames().getNames('RoI')
-
-    dimuefRecoSequence = parOR('dimuefViewNode')
-
-    dimuefViewsMaker = EventViewCreatorAlgorithm('IMdimuef')
-    dimuefViewsMaker.ViewFallThrough = True
-    dimuefViewsMaker.RoIsLink = 'initialRoI'
-    dimuefViewsMaker.RoITool = ViewCreatorInitialROITool()
-    dimuefViewsMaker.InViewRoIs = 'DimuEFRoIs'
-    dimuefViewsMaker.Views = 'DimuEFViewRoIs'
-    dimuefViewsMaker.ViewNodeName = dimuefRecoSequence.name()
-    dimuefViewsMaker.RequireParentView = True
-
-    ViewVerifyEFCB = CfgMgr.AthViews__ViewDataVerifier('dimuefViewDataVerifier')
-    ViewVerifyEFCB.DataObjects = [('xAOD::MuonContainer', 'StoreGateSvc+'+muNames.EFCBName)]
-    dimuefRecoSequence += ViewVerifyEFCB
-    dimuefSequence = seqAND('dimuefSequence', [dimuefViewsMaker, dimuefRecoSequence])
-
-    from TrigBphysHypo.TrigMultiTrkHypoConfig import TrigMultiTrkHypoConfig, TrigMultiTrkHypoToolFromDict
-    config = TrigMultiTrkHypoConfig()
-    DimuHypo = config.ConfigurationHypo(
-        trigSequenceName = name,
-        trigLevel = 'EF',
-        muonCollection = muNames.EFCBName)
-
-    return MenuSequence(
-        Sequence = dimuefSequence,
-        Maker = dimuefViewsMaker,
-        Hypo = DimuHypo,
-        HypoToolGen = TrigMultiTrkHypoToolFromDict)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/GenerateBphysicsChainDefs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/GenerateBphysicsChainDefs.py
index 0dee4950846f..c331d4d905cc 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/GenerateBphysicsChainDefs.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/GenerateBphysicsChainDefs.py
@@ -1,39 +1,35 @@
-# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 
 ###########################################################################
 # SliceDef file for Bphysics chains
 ###########################################################################
 
 from AthenaCommon.Logging import logging
-log = logging.getLogger( 'TriggerMenuMT.HLTMenuConfig.Bphysics.generateChainConfigs' )
-logging.getLogger().info("Importing %s",__name__)
+log = logging.getLogger('TriggerMenuMT.HLTMenuConfig.Bphysics.generateChainConfigs')
+logging.getLogger().info('Importing %s', __name__)
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDict
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainMerging import mergeChainDefs
 from TriggerMenuMT.HLTMenuConfig.Bphysics.BphysicsDef import BphysicsChainConfiguration as BphysicsChainConfiguration
 
 def generateChainConfigs(chainDict):
 
-    if not chainDict["topo"]:
-         log.error( "No topo given -> not a bphysics chain...")
-             
+    if not chainDict['topo']:
+         log.error('No topo given -> not a bphysics chain...')
+
     listOfChainDicts = splitChainDict(chainDict)
-    listOfChainDefs=[]
 
+    listOfChainDefs=[]
     for subChainDict in listOfChainDicts:
-        
-        my_chain = BphysicsChainConfiguration(subChainDict).assembleBphysChain() 
+        subChain = BphysicsChainConfiguration(subChainDict).assembleBphysChain()
+        listOfChainDefs += [subChain]
 
-        listOfChainDefs += [my_chain]
-        log.debug('length of chaindefs %s', len(listOfChainDefs) )
-        
+    log.debug('length of chaindefs %s', len(listOfChainDefs))
 
-    if len(listOfChainDefs)>1:
-        log.warning("Implement case for multi-bphys object chain!!")
-        theChainDef = listOfChainDefs[0] #needs to be implemented properly
+    if len(listOfChainDefs) > 1:
+        chainDef = mergeChainDefs(listOfChainDefs, chainDict)
     else:
-        theChainDef = listOfChainDefs[0]
-
-    log.debug("theChainDef %s" , theChainDef)
-
-    return theChainDef
+        chainDef = listOfChainDefs[0]
 
+    log.debug('ChainDef %s', chainDef)
+    return chainDef
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py
index 7094f7ef2ad6..9d11cdaaae36 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py
@@ -5,7 +5,7 @@ from AthenaCommon.Logging import logging
 log = logging.getLogger(__name__)
 
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import Chain, ChainStep, RecoFragmentsPool
-
+from DecisionHandling.DecisionHandlingConfig import ComboHypoCfg
 
 #----------------------------------------------------------------
 # Base class to configure chain
@@ -43,13 +43,13 @@ class ChainConfigurationBase(object):
         mySequence = RecoFragmentsPool.retrieve(mySequenceCfg, None) # the None will be used for flags in future
         return mySequence
 
-    def getStep(self, stepID, stepPartName, sequenceCfgArray, comboTools=[]):
+    def getStep(self, stepID, stepPartName, sequenceCfgArray, comboHypoCfg=ComboHypoCfg, comboTools=[]):
         stepName = 'Step%d'%stepID + '_%d'%self.mult + stepPartName
         log.debug("Configuring step " + stepName)
         seqArray = []
         for sequenceCfg in sequenceCfgArray:
             seqArray.append( RecoFragmentsPool.retrieve( sequenceCfg, None))
-        return ChainStep(stepName, seqArray, [self.mult], [self.dict], comboToolConfs=comboTools)
+        return ChainStep(stepName, seqArray, [self.mult], [self.dict], comboHypoCfg=comboHypoCfg, comboToolConfs=comboTools)
     
     def buildChain(self, chainSteps):
         myChain = Chain(name = self.chainName,
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
index 13976b6f52a6..0147b4b9eeba 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
@@ -154,6 +154,7 @@ def makeChainSteps(steps, stepNumber, chainDefList):
     log.verbose(" steps %s ", steps)
     stepDicts = []
     comboHypoTools = []
+    comboHypo = None
 
     # this function only makes sense if we are merging steps corresponding to the chains in the chainDefList
     assert len(chainDefList)==len(steps), "makeChainSteps: Length of chain defs %d does not match length of steps to merge %d" % (len(chainDefList), len(steps))
@@ -179,6 +180,7 @@ def makeChainSteps(steps, stepNumber, chainDefList):
                 log.error("More than one menu sequence found in combined chain!!")
 
 
+            comboHypo = step.comboHypoCfg
             currentStep = step.name
 
             # the step naming for combined chains needs to be revisted!!
@@ -195,7 +197,7 @@ def makeChainSteps(steps, stepNumber, chainDefList):
         stepDicts[-1]['chainName'] = legName(stepDicts[-1]['chainName'], chain_index)
         
     comboHypoTools = list(set(comboHypoTools))
-    theChainStep = ChainStep(stepName, Sequences=stepSeq, multiplicity=stepMult, chainDicts=stepDicts, comboToolConfs=comboHypoTools) 
+    theChainStep = ChainStep(stepName, Sequences=stepSeq, multiplicity=stepMult, chainDicts=stepDicts, comboHypoCfg=comboHypo, comboToolConfs=comboHypoTools) 
     log.info("Merged step: \n %s", theChainStep)
   
     
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index fa933865a284..7828ddcdd672 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -14,9 +14,7 @@ from TriggerMenuMT.HLTMenuConfig.Menu.MenuPrescaleConfig import addSliceChainsTo
 import TriggerMenuMT.HLTMenuConfig.Menu.MC_pp_run3_v1 as mc_menu
 import TriggerMenuMT.HLTMenuConfig.Menu.PhysicsP1_pp_run3_v1 as p1_menu
 
-from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import PhysicsStream,SingleMuonGroup,MultiMuonGroup,SingleElectronGroup,MultiElectronGroup,SinglePhotonGroup,MultiPhotonGroup,SingleMETGroup,MultiMETGroup,SingleJetGroup,MultiJetGroup,SingleBjetGroup,SingleTauGroup,MinBiasGroup
-#BphysicsGroup (re-add to the preceding line when putting bphys back in)
-
+from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import PhysicsStream,SingleMuonGroup,MultiMuonGroup,SingleElectronGroup,MultiElectronGroup,SinglePhotonGroup,MultiPhotonGroup,SingleMETGroup,MultiMETGroup,SingleJetGroup,MultiJetGroup,SingleBjetGroup,SingleTauGroup,MinBiasGroup,BphysicsGroup
 
 def setupMenu():
 
@@ -218,13 +216,12 @@ def setupMenu():
         ChainProp(name="HLT_tau160_perf_tracktwoMVA_L1TAU100",groups=SingleTauGroup),
 
     ]
-    # TimM temporary disable due to !31039
     TriggerFlags.BphysicsSlice.signatures = TriggerFlags.BphysicsSlice.signatures() + [
-        #ATR 20603
-        # ChainProp(name='HLT_2mu4_bJpsimumu_L12MU4',     groups=BphysicsGroup),
-        # ChainProp(name='HLT_2mu4_bUpsimumu_L12MU4',     groups=BphysicsGroup),
+        #ATR-20603
+        ChainProp(name='HLT_2mu4_bJpsimumu_L12MU4', groups=BphysicsGroup),
+        ChainProp(name='HLT_2mu4_bUpsimumu_L12MU4', groups=BphysicsGroup),
         #ATR-20839
-        # ChainProp(name='HLT_2mu4_bDimu_L12MU4',     groups=BphysicsGroup),
+        ChainProp(name='HLT_2mu4_bDimu_L12MU4', groups=BphysicsGroup),
     ]
     TriggerFlags.CombinedSlice.signatures = TriggerFlags.CombinedSlice.signatures() + [
         # groups need to be properly assigned here later
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
index e052d7f34e47..0fd148f7f34f 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
@@ -5,6 +5,7 @@ log = logging.getLogger( __name__ )
 from collections import MutableSequence
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponentsNaming import CFNaming
 from AthenaCommon.CFElements import parOR, seqAND, compName, getProp
+from DecisionHandling.DecisionHandlingConfig import ComboHypoCfg
 from AthenaConfiguration.ComponentFactory import CompFactory
 RoRSeqFilter=CompFactory.RoRSeqFilter
 
@@ -236,18 +237,18 @@ class InputMakerNode(AlgNode):
         self.addOutput(input_maker_output)
 
 
-from DecisionHandling.DecisionHandlingConf import ComboHypo
 class ComboMaker(AlgNode):
-    def __init__(self, name, multiplicity):
+    def __init__(self, name, multiplicity, comboHypoCfg):
+        self.prop="MultiplicitiesMap"
+        self.mult=list(multiplicity)
+        self.comboHypoCfg = comboHypoCfg
         Alg = RecoFragmentsPool.retrieve( self.create, name )
         log.debug("ComboMaker init: Alg %s", name)
         AlgNode.__init__(self,  Alg, 'HypoInputDecisions', 'HypoOutputDecisions')
-        self.prop="MultiplicitiesMap"
-        self.mult=list(multiplicity)
 
     def create (self, name):
         log.debug("ComboMaker.create %s",name)
-        return ComboHypo(name)
+        return self.comboHypoCfg(name)
 
     def addChain(self, chainDict):
         chainName = chainDict['chainName']
@@ -278,8 +279,9 @@ class ComboMaker(AlgNode):
             return
         confs = [ HypoToolConf( tool ) for tool in comboToolConfs ]
         log.debug("ComboMaker.createComboHypoTools for chain %s, Alg %s with %d tools", chainDict["chainName"],self.Alg.getName(), len(comboToolConfs))        
-        self.Alg.ComboHypoTools = [conf.confAndCreate( chainDict ) for conf in confs]
-        
+        for conf in confs:
+            tools = self.Alg.ComboHypoTools
+            self.Alg.ComboHypoTools = tools + [ conf.confAndCreate( chainDict ) ]
 
 
 #########################################################
@@ -835,7 +837,7 @@ class StepComponent(object):
 
 class ChainStep(object):
     """Class to describe one step of a chain; if multiplicity is greater than 1, the step is combo/combined.  Set one multiplicity value per sequence"""
-    def __init__(self, name,  Sequences=[], multiplicity=[1], chainDicts=[], comboToolConfs=[]):
+    def __init__(self, name,  Sequences=[], multiplicity=[1], chainDicts=[], comboHypoCfg=ComboHypoCfg, comboToolConfs=[]):
 
         # sanity check on inputs
         if len(Sequences) != len(multiplicity):
@@ -846,6 +848,7 @@ class ChainStep(object):
         self.name = name
         self.sequences=Sequences
         self.multiplicity = multiplicity
+        self.comboHypoCfg=comboHypoCfg
         self.comboToolConfs=comboToolConfs
         self.isCombo=sum(multiplicity)>1
         self.combo=None
@@ -854,13 +857,13 @@ class ChainStep(object):
             self.makeCombo()
 
     def addComboHypoTools(self,  tools):
-        self.comboToolConfs=tools
+        self.comboToolConfs.append(tools)
 
     def makeCombo(self):
         if len(self.sequences)==0:
             return
         hashableMult = tuple(self.multiplicity)
-        self.combo =  RecoFragmentsPool.retrieve(createComboAlg, None, name=CFNaming.comboHypoName(self.name), multiplicity=hashableMult)
+        self.combo =  RecoFragmentsPool.retrieve(createComboAlg, None, name=CFNaming.comboHypoName(self.name), multiplicity=hashableMult, comboHypoCfg=self.comboHypoCfg)
 
     def createComboHypoTools(self, chainName):
         if self.isCombo:
@@ -881,8 +884,8 @@ class ChainStep(object):
             return "--- ChainStep %s ---\n + isCombo, multiplicity = %d  ChainDict = %s \n + MenuSequences = %s  \n + ComboHypo = %s,  ComboHypoTools = %s"%(self.name,  sum(self.multiplicity), ' '.join(map(str, [dic['chainName'] for dic in self.chainDicts])), ' '.join(map(str, [seq.name for seq in self.sequences]) ), self.combo.Alg.name(),  ' '.join(map(str, [tool.__name__ for tool in self.comboToolConfs]))) 
 
 
-def createComboAlg(dummyFlags, name, multiplicity):
-    return ComboMaker(name, multiplicity)
+def createComboAlg(dummyFlags, name, multiplicity, comboHypoCfg):
+    return ComboMaker(name, multiplicity, comboHypoCfg)
 
 
 # this is fragment for New JO
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py
index e2295d335d61..3b4f66c17170 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py
@@ -107,11 +107,12 @@ def setupMenu():
         #ATR-20049
         ChainProp(name="HLT_tau160_mediumRNN_tracktwoMVA_L1TAU100", groups=SingleTauGroup),
     ]
-    # TimM temporary disable due to !31039
     TriggerFlags.BphysicsSlice.signatures = [
         #ATR-20049
-        # ChainProp(name='HLT_2mu10_bJpsimumu_L12MU10',     groups=BphysicsGroup),
-        # ChainProp(name='HLT_2mu10_bUpsimumu_L12MU10',     groups=BphysicsGroup),
+        ChainProp(name='HLT_2mu10_bJpsimumu_L12MU10', groups=BphysicsGroup),
+        ChainProp(name='HLT_mu11_mu6_bJpsimumu_L1MU11_2MU6', groups=BphysicsGroup),
+        ChainProp(name='HLT_2mu10_bUpsimumu_L12MU10', groups=BphysicsGroup),
+        ChainProp(name='HLT_mu11_mu6_bUpsimumu_L1MU11_2MU6', groups=BphysicsGroup),
     ]
     TriggerFlags.CombinedSlice.signatures = [
         ChainProp(name='HLT_e3_etcut1step_mu6fast_L1EM8I_MU10', l1SeedThresholds=['EM8I', 'MU10'], stream=[PhysicsStream], groups=MultiElectronGroup),    #L1 item thresholds in wrong order (EM first, then MU)
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
index d2d533dd1a78..592a1ad0996a 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py
@@ -126,11 +126,11 @@ def muCombAlgSequence(ConfigFlags):
  
     #Filter algorithm to run muComb only if non-Bphysics muon chains are active
     from TrigMuonEF.TrigMuonEFConfig import MuonChainFilterAlg
+    from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponentsNaming import CFNaming
     muonChainFilter = MuonChainFilterAlg("FilterBphysChains")
     bphysChains =getBphysChainNames()
     muonChainFilter.ChainsToFilter=bphysChains
-    if hasattr(l2muCombViewsMaker, "InputMakerOutputDecisions"):
-        muonChainFilter.InputDecisions = [ l2muCombViewsMaker.InputMakerOutputDecisions ]
+    muonChainFilter.InputDecisions = [ CFNaming.inputMakerOutName(l2muCombViewsMaker.name(),"out") ]
     muonChainFilter.L2MuCombContainer = sequenceOut
 
     muCombFilterSequence = seqAND("l2muCombFilterSequence", [muonChainFilter, muCombRecoSequence])
-- 
GitLab