From 4b7ddc2be6d4e2a43e705b686bc1c0117bf7380d Mon Sep 17 00:00:00 2001
From: Catrin Bernius <catrin.bernius@cern.ch>
Date: Wed, 5 Jun 2019 11:10:50 +0000
Subject: [PATCH] Combined chains in TMMT

---
 .../TrigUpgradeTest/share/runMenuTest.py      |   1 +
 .../HLTMenuConfig/Egamma/ElectronDef.py       |   6 +-
 .../Egamma/GenerateElectronChainDefs.py       |   4 +-
 .../Jet/JetChainConfiguration.py              |   4 +-
 .../HLTMenuConfig/MET/GenerateMETChainDefs.py |   3 +-
 .../Menu/ChainConfigurationBase.py            |  21 +++-
 .../HLTMenuConfig/Menu/ChainDefInMenu.py      |  10 +-
 .../HLTMenuConfig/Menu/ChainDictTools.py      |   6 +-
 .../python/HLTMenuConfig/Menu/ChainMerging.py | 112 ++++++++++++++++++
 .../HLTMenuConfig/Menu/DictFromChainName.py   | 101 +++++++++-------
 .../HLTMenuConfig/Menu/GenerateMenuMT.py      |  39 ++++--
 .../python/HLTMenuConfig/Menu/LS2_v1.py       |  36 ++++--
 .../HLTMenuConfig/Menu/MenuComponents.py      |   6 +-
 .../python/HLTMenuConfig/Menu/MenuUtil.py     |   2 +-
 .../HLTMenuConfig/Menu/SignatureDicts.py      |   2 +-
 .../python/HLTMenuConfig/Muon/MuonDef.py      |  18 +--
 16 files changed, 276 insertions(+), 95 deletions(-)
 create mode 100644 Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py

diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.py b/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.py
index a8fdf603faa..e884a6e6768 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/runMenuTest.py
@@ -18,6 +18,7 @@ def signaturesToGenerate():
     TriggerFlags.METSlice.setAll()
     TriggerFlags.JetSlice.setAll()
     TriggerFlags.TauSlice.setAll()
+    TriggerFlags.CombinedSlice.setAll()
 
 
 # generate the Chains from the Menu Dictionary
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py
index 2e4dbad1a17..1f751f384ed 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronDef.py
@@ -70,15 +70,15 @@ class ElectronChainConfiguration(ChainConfigurationBase):
         if stepName == "Step1_etcut":
           log.debug("Configuring step " + stepName)
           fastCalo = RecoFragmentsPool.retrieve( fastCaloSequenceCfg, None ) # the None will be used for flags in future
-          chainStep =ChainStep(stepName, [fastCalo])
+          chainStep =ChainStep(stepName, [fastCalo], self.mult)
         elif stepName == "Step2_etcut":
           log.debug("Configuring step " + stepName)
           electronReco = RecoFragmentsPool.retrieve( electronSequenceCfg, None )
-          chainStep=ChainStep(stepName, [electronReco])
+          chainStep=ChainStep(stepName, [electronReco], self.mult)
         elif stepName == "Step3_etcut":
           log.debug("Configuring step " + stepName)
           precisionReco = RecoFragmentsPool.retrieve( precisionCaloSequenceCfg, None )
-          chainStep=ChainStep(stepName, [precisionReco])
+          chainStep=ChainStep(stepName, [precisionReco], self.mult)
         else:            
           raise RuntimeError("chainStepName unknown: " + stepName )
                         
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/GenerateElectronChainDefs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/GenerateElectronChainDefs.py
index 3f6a17edb10..ad4a67d946b 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/GenerateElectronChainDefs.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/GenerateElectronChainDefs.py
@@ -2,6 +2,7 @@
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDict
 from TriggerMenuMT.HLTMenuConfig.Egamma.ElectronDef import ElectronChainConfiguration as ElectronChainConfiguration
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainMerging import mergeChainDefs
 
 
 from AthenaCommon.Logging import logging
@@ -27,8 +28,7 @@ def generateChainConfigs( chainDict ):
         
 
     if len(listOfChainDefs)>1:
-        log.warning("Implement case for multi-electron chain!!") 
-        theChainDef = listOfChainDefs[0] #needs to be implemented properly
+        theChainDef = mergeChainDefs(listOfChainDefs, chainDict)
     else:
         theChainDef = listOfChainDefs[0]
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py
index 39e0cf2c131..209aebc1913 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Jet/JetChainConfiguration.py
@@ -52,9 +52,9 @@ class JetChainConfiguration(ChainConfigurationBase):
         jetDefStr = jetRecoDictToString(self.recoDict)
 
         stepName = "Step1_jet_"+jetDefStr
-        log.debug("Configuring step " + stepName)
         jetSeq1 = RecoFragmentsPool.retrieve( jetMenuSequence, None, **self.recoDict ) # the None will be used for flags in future
-        return ChainStep(stepName, [jetSeq1])
+        return ChainStep(stepName, [jetSeq1], self.mult)
+
         
             
             
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MET/GenerateMETChainDefs.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MET/GenerateMETChainDefs.py
index dec42fa8158..ba5bbd9bee4 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MET/GenerateMETChainDefs.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MET/GenerateMETChainDefs.py
@@ -2,6 +2,7 @@
 
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDict
 from TriggerMenuMT.HLTMenuConfig.MET.METChainDef import MetChainConfiguration as MetChainConfiguration
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainMerging import mergeChainDefs
 
 
 from AthenaCommon.Logging import logging
@@ -28,7 +29,7 @@ def generateChainConfigs( chainDict ):
 
     if len(listOfChainDefs)>1:
         log.warning("Implement case for mulit-step met chain!!") 
-        theChainDef = listOfChainDefs[0] #needs to be implemented properly
+        theChainDef = mergeChainDefs(listOfChainDefs, chainDict)
     else:
         theChainDef = listOfChainDefs[0]
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py
index e20e1f2f327..9865c0e8702 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainConfigurationBase.py
@@ -1,5 +1,7 @@
 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
+from AthenaCommon.Logging import logging
+log = logging.getLogger( 'TriggerMenuMT.HLTMenuConfig.Menu.ChainConfigurationBase' )
 
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import Chain, RecoFragmentsPool
 
@@ -24,19 +26,32 @@ class ChainConfigurationBase(object):
         self.chainPartL1Item = self.chainPart['L1item']
         self.mult = int(self.chainPart['multiplicity'])
         self.chainPartName = self.chainPart['chainPartName']
+        self.chainPartNameNoMult = ''
+        self.chainPartNameNoMultwL1 = ''
+
         self.chainPartNameNoMult = self.chainPartName[1:] if self.mult > 1 else self.chainPartName
-        self.chainPartNameNoMult += "_"+self.chainL1Item
+        self.chainPartNameNoMultwL1 += "_"+self.chainL1Item
+        
+        self.L1Threshold = self.chainPartL1Item or self.chainL1Item
+        if ('L1_' in self.L1Threshold):
+            self.L1Threshold = self.L1Threshold.replace('L1_', '')
+        self.L1Threshold = self.L1Threshold.split('_')[0]
+        self.L1Threshold = self.L1Threshold[1:] if self.L1Threshold[0].isdigit() else self.L1Threshold
 
+        self.L1ItemToPass = 'L1_'+self.L1Threshold
 
     # this is the cache, hoping to be able to get rid of it in future
     def checkRecoFragmentPool(mySequenceCfg):
         mySequence = RecoFragmentsPool.retrieve(mySequenceCfg, None) # the None will be used for flags in future
         return mySequence
 
-    def buildChain(self, chainSteps):                            
+    def buildChain(self, chainSteps):   
+        log.debug("Building Chain %s with L1 seed %s, and multiplicity %s", (self.chainName, self.L1ItemToPass, str(self.mult)))
+        
         myChain = Chain(name = self.chainName, 
-                        Seed = self.chainL1Item, 
+                        Seed = self.L1ItemToPass, 
                         ChainSteps = chainSteps)
+        
         return myChain
 
         
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDefInMenu.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDefInMenu.py
index a269f70b14a..2d9c19b2c7b 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDefInMenu.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDefInMenu.py
@@ -15,7 +15,13 @@ def namedtuple_with_defaults(typename, field_names, default_values=()):
 
 # namedtuple class with some defaults set for those entries that do not require settings
 ChainProp = namedtuple_with_defaults("ChainProp", 
-                                     ['name', 'l1SeedItem', 'l1SeedThresholds', 'stream', 'groups', 'merging', 'topoStartFrom'],
-                                     {'stream':['Main'], 'l1SeedItem': '', 'l1SeedThresholds': [], 'merging':[], 'topoStartFrom': False})
+                                     ['name', 'l1SeedItem', 'l1SeedThresholds', 'stream', 'groups', 'mergingStrategy', 'mergingOrder', 'mergingOffset', 'topoStartFrom'],
+                                     {'stream':['Main'], 
+                                      'l1SeedItem': '', 
+                                      'l1SeedThresholds': [], 
+                                      'mergingStrategy':'parallel', 
+                                      'mergingOrder': [], 
+                                      'mergingOffset': -1, 
+                                      'topoStartFrom': False})
 
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py
index 326ab751031..010a52669a4 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainDictTools.py
@@ -1,8 +1,8 @@
-# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
 from copy import deepcopy
 from AthenaCommon.Logging import logging
-log = logging.getLogger( 'TriggerMenu.menu.ChainDictTools' )
+log = logging.getLogger( 'TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools' )
 
 
 def splitInterSignatureChainDict(chainDict):
@@ -98,7 +98,6 @@ def splitChainDict(chainDict):
 
 
 def setupTopoStartFrom(topoThresholds, theChainDef):
-
     from TrigGenericAlgs.TrigGenericAlgsConf import MergeTopoStarts
 
     if len(topoThresholds) > 1:
@@ -106,7 +105,6 @@ def setupTopoStartFrom(topoThresholds, theChainDef):
         m = MergeTopoStartsConfig("testInstance")
         log.debug(m)
 
-
     te0 = None
     te1 = None 
     outTE = None
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
new file mode 100644
index 00000000000..8be517e129b
--- /dev/null
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/ChainMerging.py
@@ -0,0 +1,112 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+
+from AthenaCommon.Logging import logging
+log = logging.getLogger( 'TriggerMenuMT.HLTMenuConfig.Menu.ChainMerging' )
+
+from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import Chain, ChainStep
+from copy import deepcopy
+
+
+def mergeChainDefs(listOfChainDefs, chainDict, strategy="parallel", offset=-1):
+
+    log.debug("Combine by using %s merging", strategy)
+
+    if strategy=="parallel":
+        return mergeParallel(listOfChainDefs, chainDict['L1item'], offset)
+    elif strategy=="serial":
+        #return mergeSerial(listOfChainDefs,offset)
+        log.error("Serial mergin not yet implemented.")
+        return -1
+    else:
+        log.error("Merging failed for %s. Merging strategy '%s' not known.", (listOfChainDefs, strategy))
+        return -1
+
+
+
+def mergeParallel(chainDefList, chainL1Item, offset):
+
+    if offset != -1:
+        log.error("Offset for parallel merging not implemented.")
+        
+    allSteps = []
+    nSteps = []
+    chainName = ''
+    #l1Seed = ''
+    l1Seed = chainL1Item
+    combChainSteps =[]
+
+    for cConfig in chainDefList:
+        if chainName == '':
+            chainName = cConfig.name
+        elif chainName != cConfig.name:
+            log.error("Something is wrong with the combined chain name: cConfig.name = %s while chainName = %s", cConfig.name, chainName)
+            
+        if l1Seed == '':
+            l1Seed = cConfig.seed
+        elif l1Seed != cConfig.seed:
+            log.debug("Taking the overall L1 item of the chain (%s) and not the indiv set ones for the chain parts (%s)", l1Seed, cConfig.seed)
+
+        allSteps.append(cConfig.steps)
+        nSteps.append(len(cConfig.steps))
+
+    from itertools import izip_longest
+    orderedSteps = list(izip_longest(*allSteps))
+    myOrderedSteps = deepcopy(orderedSteps)
+
+    for steps in myOrderedSteps:
+        mySteps = list(steps)
+        combStep = makeChainSteps(mySteps)
+        combChainSteps.append(combStep)
+
+    # check if all chain parts have the same number of steps
+    sameNSteps = all(x==nSteps[0] for x in nSteps) 
+    if sameNSteps is True:
+        log.debug("All chain parts have the same number of steps")
+    else:
+        log.debug("Have to deal with uneven number of chain steps, there might be none's appearing in sequence list => to be fixed")
+                                  
+    combinedChainDef = Chain(chainName, l1Seed, combChainSteps)
+    for step in combinedChainDef.steps:
+        log.debug('  Step %s', step)
+
+    return combinedChainDef
+
+
+
+
+def makeChainSteps(steps):
+    stepName = ''
+    stepSeq = []
+    stepMult = 0
+    stepNumber = ''
+    log.debug(" steps %s ", steps)
+    for step in steps:
+        if step is None:
+            continue
+        if len(step.sequences) > 1:
+            log.error("More than one menu sequence found in combined chain!!")
+        seq = step.sequences[0]
+        log.debug(" step type  %s", type(step.sequences))
+        log.debug(" step.name %s", step.name)
+        log.debug(" step.seq %s", step.sequences)
+        log.debug(" step.mult %s", step.multiplicity)
+        currentStep = step.name
+        stepNameParts = currentStep.split('_')
+        if stepNumber == '':
+            stepNumber = stepNameParts[0]
+
+        # the step naming for combined chains needs to be revisted!!
+        stepName = stepNumber + '_' + stepNameParts[1]
+        stepSeq.append(seq)
+        stepMult += step.multiplicity
+        
+    log.debug(" - BB stepName %s", stepName)
+    log.debug(" - BB stepSeq %s", stepSeq)
+    log.debug(" - BB stepMult %s", stepMult)
+    
+    theChainStep = ChainStep(stepName, stepSeq, stepMult)
+    log.debug(" - BBB the chain step %s", theChainStep)
+    
+    return theChainStep
+
+
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py
index 12765c6813f..2d3c95df342 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/DictFromChainName.py
@@ -31,50 +31,62 @@ class DictFromChainName(object):
         # these if/elif/else statements are due to temporary development
         if type(chainInfo) == str:
             m_chainName = chainInfo
-            m_L1item = ''
             m_L1chainParts = []
             m_stream = ''
             m_groups = []
+            m_mergingStrategy = 'parallel'
+            m_mergingOffset = -1
+            m_mergingOrder = []
+            m_topoStartFrom = ''
 
         elif type(chainInfo) == list:
             m_chainName = chainInfo[0]
-            m_L1item = '' 
             m_L1chainParts = chainInfo[1]
             m_stream = chainInfo[2]
             m_groups = chainInfo[3]
+            m_mergingStrategy = 'parallel'
+            m_mergingOffset = -1
+            m_mergingOrder = []
+            m_topoStartFrom = ''
 
         elif 'ChainProp' in str(type(chainInfo)): 
             m_chainName = chainInfo.name
-            m_L1item = ''
             m_L1chainParts = chainInfo.l1SeedThresholds
             m_stream = chainInfo.stream
             m_groups = chainInfo.groups
+            m_mergingStrategy = chainInfo.mergingStrategy
+            m_mergingOffset = chainInfo.mergingOffset
+            m_mergingOrder = chainInfo.mergingOrder 
+            m_topoStartFrom = chainInfo.topoStartFrom
         
         else:
             logDict.error("Format of chainInfo passed to genChainDict not known")
 
-        m_L1item = self.getOverallL1item(m_chainName)
+        m_L1item = self.getOverallL1item(m_chainName)  
 
         logDict.debug("Analysing chain with name: %s", m_chainName)
         chainDict = self.analyseShortName(m_chainName,  m_L1chainParts, m_L1item)
         logDict.debug('ChainProperties: %s', chainDict)
 
+        # setting the L1 item
+        chainDict['L1item'] = m_L1item
         chainDict['stream'] = m_stream
         chainDict['groups'] = m_groups
+        chainDict['mergingStrategy']= m_mergingStrategy
+        chainDict['mergingOffset']= m_mergingOffset
+        chainDict['mergingOrder'] = m_mergingOrder
+        chainDict['topoStartFrom']= m_topoStartFrom
 
         logDict.debug('Setting chain multiplicities')
         allChainMultiplicities = self.getChainMultFromDict(chainDict)
         chainDict['chainMultiplicities'] = allChainMultiplicities
                 
-        # setting the L1 item
-        if (chainDict['L1item']== ''): 
-            chainDict['L1item'] = m_L1item
 
         if logDict.isEnabledFor(logging.DEBUG):
             import pprint
             pp = pprint.PrettyPrinter(indent=4, depth=8)
-            logDict.debug('FINAL dictionary: %s', pp.pformat(chainDict))
-
+            logDict.debug('SUPER FINAL dictionary: %s', pp.pformat(chainDict))
+            
         return chainDict
 
 
@@ -82,24 +94,20 @@ class DictFromChainName(object):
         if '_L1' in m_chainName:
             return True
         else:
+            logDict.warning("Chain name %s not complying with naming convention: L1 item missing! PLEASE FIX THIS!!", m_chainName)
             return False
 
     def getOverallL1item(self, chainName):
         mainL1 = ''
 
-        if not self.checkL1inName(chainName):
-            logDict.warning("Chain name %s not complying with naming convention: L1 item missing! PLEASE FIX THIS!!", chainName)
+        if self.checkL1inName(chainName) is False:
+            logDict.warning("Cannot determine L1 item name for dictionary, please fix naming")
+            return mainL1
+        else:
+            # this assumes that the last string of a chain name is the overall L1 item
+            cNameParts = chainName.split("_L1") 
+            mainL1 = 'L1_' + cNameParts[-1]                            
             return mainL1
-        # this assumes that the last string of a chain name is the overall L1 item
-        cNameParts = chainName.split("_") 
-        mainL1 = cNameParts[-1]
-
-        if "L1" not in mainL1:
-            logDict.warning("Chain name not complying with naming convention: L1 item missing! PLEASE FIX THIS!!")
-            return ''
-        mainL1 = mainL1.replace("L1", "L1_")
-
-        return mainL1
         
 
     def getChainMultFromDict(self, chainDict):
@@ -165,10 +173,14 @@ class DictFromChainName(object):
         genchainDict = deepcopy(ChainDictTemplate)
         genchainDict['chainName'] = chainName
         
+        # remove the L1 item from the name
+        cName = deepcopy(chainName)
+        cName = cName.replace(L1item_main.replace("L1_", "_L1"),'')
+
         # ---- specific chain part information ----
         allChainProperties=[]
-        cparts = chainName.split("_") 
-        if 'HLT' in chainName:
+        cparts = cName.split("_") 
+        if 'HLT' in cName:
             cparts.remove('HLT')
 
            
@@ -184,7 +196,7 @@ class DictFromChainName(object):
                 topo = cpart
                 topoindex = cindex
                 toposIndexed.update({topo : topoindex})
-                chainName=chainName.replace('_'+cpart, '')
+                cName=cName.replace('_'+cpart, '')
                 topos.append(topo)
 
         genchainDict['topo'] = topos
@@ -221,19 +233,19 @@ class DictFromChainName(object):
                 m_groupdict = m.groupdict()
                 # Check whether the extra contains a special keyword
                 
-                multiChainIndices = [i for i in range(len(chainName)) if ( chainName.startswith(cpart, i) ) ]
+                multiChainIndices = [i for i in range(len(cName)) if ( cName.startswith(cpart, i) ) ]
                 logDict.debug("MultiChainIndices: %s", multiChainIndices)
                 for theMultiChainIndex in multiChainIndices:
                     # this check is necessary for the bjet chains, example: j45_bloose_3j45
                     # j45 would be found in [0, 13], and 3j45 in [12]
                     # so need to make sure the multiplicities are considered here!
-                    if (theMultiChainIndex != 0) & (chainName[theMultiChainIndex-1] != '_'): 
+                    if (theMultiChainIndex != 0) & (cName[theMultiChainIndex-1] != '_'): 
                         continue
 
                     if theMultiChainIndex not in multichainindex:
                         multichainindex.append(theMultiChainIndex)
 
-                logDict.debug("ChainName: %s", chainName)
+                logDict.debug("ChainName: %s", cName)
                 logDict.debug("cpart: %s", cpart)
                 logDict.debug("m_groupdict: %s", m_groupdict)
                 logDict.debug("multichainindex: %s", multichainindex)
@@ -248,7 +260,7 @@ class DictFromChainName(object):
 
                     
             elif cpart =='noalg':
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'Streaming', 'threshold': '', 'multiplicity': '', 
                                 'trigType': 'streamer', 'extra': ''}
                 if 'Streaming' not in signatureNames: 
@@ -258,7 +270,7 @@ class DictFromChainName(object):
 
             elif cpart=='mb': 
                 logDict.debug('Doing MB')
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'MinBias', 'threshold': '', 'multiplicity': '', 
                                'trigType': 'mb', 'extra': ''}
                 if 'MinBias' not in signatureNames:  
@@ -267,7 +279,7 @@ class DictFromChainName(object):
 
             elif cpart=='hi':
                 logDict.debug('Doing HI')
-                multichainindex.append(chainName.index(cpart))
+                multichainindex.append(cName.index(cpart))
                 m_groupdict = {'signature': 'HeavyIon', 'threshold': '', 'multiplicity': '',
                                'trigType': 'mb', 'extra': ''}
                 if 'HeavyIon' not in signatureNames:  
@@ -276,7 +288,7 @@ class DictFromChainName(object):
 
             elif cpart in AllowedCosmicChainIdentifiers:
                 logDict.debug('COSMIC CHAIN from CosmicDef.py')
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'Cosmic', 'threshold': '', 'multiplicity': '', 
                                 'trigType': 'cosmic', 'extra': ''}
                 if 'Cosmic' not in signatureNames: 
@@ -286,7 +298,7 @@ class DictFromChainName(object):
                 
             elif cpart in AllowedCalibChainIdentifiers:
                 logDict.debug('CALIB CHAIN from Calibration')
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'Calibration', 'threshold': '', 'multiplicity': '', 
                                'trigType': 'calib', 'extra': ''}
                 if 'Calibration' not in signatureNames:  
@@ -296,7 +308,7 @@ class DictFromChainName(object):
 
             elif cpart in AllowedMonitorChainIdentifiers:
                 logDict.debug('Mon CHAIN from Monitor')
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'Monitoring', 'threshold': '', 'multiplicity': '', 
                                 'trigType': 'calib', 'extra': ''}
                 if 'Monitoring' not in signatureNames:  
@@ -306,7 +318,7 @@ class DictFromChainName(object):
 
             elif cpart in AllowedBeamspotChainIdentifiers:
                 logDict.debug('Beamspot CHAIN from Beamspot')
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'Beamspot', 'threshold': '', 'multiplicity': '', 
                                 'trigType': 'beamspot', 'extra': ''}
                 if 'Beamspot' not in signatureNames:  
@@ -316,7 +328,7 @@ class DictFromChainName(object):
 
             elif cpart=='eb': 
                 logDict.debug('EnhancedBias chain')
-                multichainindex.append(chainName.index(cpart)) 
+                multichainindex.append(cName.index(cpart)) 
                 m_groupdict = {'signature': 'EnhancedBias', 'threshold': '', 'multiplicity': '', 
                                'trigType': 'eb', 'extra': ''}
                 if 'EnhancedBias' not in signatureNames:  
@@ -329,15 +341,15 @@ class DictFromChainName(object):
         # ----  ----
         multichainparts=[]
         multichainindex = sorted(multichainindex, key=int)
-        cN = chainName
+        cN = deepcopy(cName)
         for i in reversed(multichainindex):
             if i!=0:
-                logDict.debug('Appending to multichainparts (i!=0): %s', chainName[i:len(cN)])
+                logDict.debug('Appending to multichainparts (i!=0): %s', cName[i:len(cN)])
 
-                multichainparts.append(chainName[i:len(cN)])
+                multichainparts.append(cName[i:len(cN)])
                 cN = cN[0:i-1]
             else:
-                logDict.debug('Appending to multichainparts: %s', chainName[i:len(cN)])
+                logDict.debug('Appending to multichainparts: %s', cName[i:len(cN)])
                 multichainparts.append(cN)
         logDict.debug("multichainparts: %s",multichainparts)
 
@@ -391,7 +403,7 @@ class DictFromChainName(object):
                 L1index = L1index+1 # to compensate the _
                 L1itemfromChainName = chainparts[L1index:]
                 if (L1itemfromChainName[2]=='_'):
-                    raise RuntimeError('ERROR IN CHAIN NAMING: L1 items in chainNames are specified e.g. *_L1EM4, not *_L1_EM4')
+                    raise RuntimeError('ERROR IN CHAIN NAMING: L1 items in cNames are specified e.g. *_L1EM4, not *_L1_EM4')
                 else:
                     L1item = L1itemfromChainName[:2]+'_'+L1itemfromChainName[2:]
                     if (L1item[-1] == '_'): 
@@ -413,7 +425,7 @@ class DictFromChainName(object):
                 chainProperties['L1item'] = L1items_chainParts[chainindex]                
                 if (L1item !=  chainProperties['L1item']) & (L1item !=''):
                     logDict.info("L1 item in name (%s) of chain %s does not match with given L1item list (%s)!",
-                                 L1item, chainName, chainProperties['L1item'])
+                                 L1item, cName, chainProperties['L1item'])
 
             else:
                 logDict.debug('No L1 item specified in the name')
@@ -517,9 +529,12 @@ class DictFromChainName(object):
 
 
         # ---- depending on if signatures are different in this chain, break up the chainProperties dictionary ----
-        # ---- finally also taking care of the signatrue key ----
+        # ---- finally also taking care of the signature key ----
         genchainDict['chainParts'] = allChainProperties
-        genchainDict['signature'] = allChainProperties[0]['signature']
+        for cPart in allChainProperties:
+            genchainDict['signatures'] += [cPart['signature']]
+
+        #genchainDict['signature'] = allChainProperties[0]['signature']
 
         logDict.debug('genchainDict that is passed as Final dict %s', genchainDict)
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
index 7554a582b21..fbccbb4ef22 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/GenerateMenuMT.py
@@ -12,6 +12,7 @@ from TriggerMenuMT.HLTMenuConfig.Menu.HLTCFConfig import makeHLTTree
 from TriggerMenuMT.HLTMenuConfig.Menu import DictFromChainName
 from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitInterSignatureChainDict
 from TriggerMenuMT.HLTMenuConfig.Menu.MenuPrescaleConfig import MenuPrescaleConfig
+from TriggerMenuMT.HLTMenuConfig.Menu.ChainMerging import mergeChainDefs
 
 
 from AthenaCommon.Logging import logging
@@ -47,7 +48,7 @@ class GenerateMenuMT(object):
         self.signaturesToGenerate = []
         self.allSignatures = ['Egamma', 'Muon', 'Jet', 'Bjet', 'Bphysics', 'MET', 'Tau', 
                               'HeavyIon', 'Beamspot', 'Cosmic', 'EnhancedBias', 
-                              'Monitor', 'Calib', 'Streaming', ] #, AFP, 'Combined'
+                              'Monitor', 'Calib', 'Streaming', 'Combined'] #, AFP
         self.calibCosmicMonSigs = ['Beamspot', 'Cosmic', 'EnhancedBias', 'Monitor', 'Calib', 'Streaming']
 
         # flags
@@ -202,7 +203,7 @@ class GenerateMenuMT(object):
         return chains 
                                 
 
-    def generateChainConfig(self, chainDicts):
+    def generateChainConfig(self, mainChainDict):
         """
         # Assembles the chain configuration and returns a chain object with (name, L1see and list of ChainSteps)
         """
@@ -221,16 +222,19 @@ class GenerateMenuMT(object):
                         sigFolder = sig
                         subSigs = [sig]
 
-                    for ss in subSigs:                        
-                        exec('import TriggerMenuMT.HLTMenuConfig.' + sigFolder + '.Generate' + ss + 'ChainDefs')                
-                        self.availableSignatures.append(ss)
+                    for ss in subSigs: 
+                        if sigFolder == 'Combined':
+                            continue
+                        else:
+                            exec('import TriggerMenuMT.HLTMenuConfig.' + sigFolder + '.Generate' + ss + 'ChainDefs')                
+                            self.availableSignatures.append(ss)                        
 
             except ImportError:
                 log.exception('Problems when importing ChainDef generating code for %s', sig)
 
 
         # split the the chainDictionaries for each chain and print them in a pretty way
-        chainDicts = splitInterSignatureChainDict(chainDicts)  
+        chainDicts = splitInterSignatureChainDict(mainChainDict)  
 
         if log.isEnabledFor(logging.DEBUG):
             import pprint
@@ -254,7 +258,7 @@ class GenerateMenuMT(object):
             else:
                 sigFolder = currentSig
 
-            if currentSig in self.availableSignatures:
+            if currentSig in self.availableSignatures and currentSig != 'Combined':
                 try:                    
                     log.debug("Trying to get chain config for %s", currentSig)
                     functionToCall ='TriggerMenuMT.HLTMenuConfig.' + sigFolder + '.Generate' + currentSig + 'ChainDefs.generateChainConfigs(chainDict)' 
@@ -268,15 +272,26 @@ class GenerateMenuMT(object):
             log.debug('ChainConfigs  %s ', chainConfigs)
             listOfChainConfigs.append(chainConfigs)
 
+        if log.isEnabledFor(logging.DEBUG):
+            import pprint
+            pp = pprint.PrettyPrinter(indent=4, depth=8)
+            log.debug('mainChainDict dictionary: %s', pp.pformat(mainChainDict))
+
+
+        # This part is to deal with combined chains between different signatures
         if len(listOfChainConfigs) == 0:  
             log.error('No Chain Configuration found ')
             return False        
+
         elif len(listOfChainConfigs)>1:
-            if ("mergingStrategy" in chainDicts[0].keys()):
-                log.warning("Need to define merging strategy, returning only first chain part configuration")
-                theChainConfig = listOfChainConfigs[0]
-            else:
-                log.error("No merging strategy specified for combined chain %s", chainDicts[0]['chainName'])
+                log.debug("Merging strategy from dictionary: %s", mainChainDict["mergingStrategy"])
+                theChainConfig = mergeChainDefs(listOfChainConfigs, mainChainDict, mainChainDict["mergingStrategy"], mainChainDict["mergingOffset"])
+
+                # This needs to be added for topological chains - needs implementation
+                #doTopo = self.CheckIntraSignatureTopo(chainDicts) and chainDict["topo"]
+                #if doTopo:
+                # theChainDef = TriggerMenu.combined.generateCombinedChainDefs._addTopoInfo(theChainDef,chainDicts,listOfChainDefs)
+
         else:
             theChainConfig = listOfChainConfigs[0]
             
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
index e3ce86e53db..9fcadb4750b 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py
@@ -17,12 +17,13 @@ def setupMenu():
 
     PhysicsStream="Main"
     SingleMuonGroup = ['RATE:SingleMuon', 'BW:Muon']
-    #MultiMuonGroup = ['RATE:MultiMuon', 'BW:Muon']
+    MultiMuonGroup = ['RATE:MultiMuon', 'BW:Muon']
     SingleElectronGroup = ['RATE:SingleElectron', 'BW:Electron']
-    #MultiElectronGroup = ['RATE:MultiElectron', 'BW:Electron']
+    MultiElectronGroup = ['RATE:MultiElectron', 'BW:Electron']
     SinglePhotonGroup = ['RATE:SinglePhoton', 'BW:Photon']
     #MultiPhotonGroup = ['RATE:MultiPhoton', 'BW:Photon']
     SingleMETGroup = ['RATE:MET', 'BW:MET']
+    #MultiMETGroup = ['RATE:MultiMET', 'BW:MultiMET']
     SingleJetGroup = ['RATE:SingleJet', 'BW:Jet']
     MultiJetGroup = ['RATE:MultiJet', 'BW:Jet']
     SingleBjetGroup = ['RATE:SingleBJet', 'BW:BJet']
@@ -40,12 +41,14 @@ def setupMenu():
         ChainProp(name='HLT_mu6_L1MU6', groups=SingleMuonGroup),
 
         ChainProp(name='HLT_mu20_ivar_L1MU6', groups=SingleMuonGroup),
-        ChainProp(name='HLT_2mu6Comb_L1MU6', groups=SingleMuonGroup),
-        ChainProp(name='HLT_2mu6_L1MU6', groups=SingleMuonGroup),
         ChainProp(name='HLT_mu6_ivarmedium_L1MU6', groups=SingleMuonGroup),
         ChainProp(name='HLT_mu6noL1_L1MU6', groups=SingleMuonGroup),
 
         ChainProp(name='HLT_mu6_msonly_L1MU6', groups=SingleMuonGroup),
+
+        ChainProp(name='HLT_2mu6Comb_L12MU6', groups=MultiMuonGroup),
+        ChainProp(name='HLT_2mu6_L12MU6', groups=MultiMuonGroup),
+
      ]
 
     TriggerFlags.EgammaSlice.signatures = [
@@ -54,21 +57,28 @@ def setupMenu():
         ChainProp(name='HLT_e3_etcut_L1EM3', groups=SingleElectronGroup),
         ChainProp(name='HLT_e5_etcut_L1EM3', groups=SingleElectronGroup),
         ChainProp(name='HLT_e7_etcut_L1EM3', stream=[PhysicsStream, 'express'], groups=SingleElectronGroup),
-        #-------------END OF ElectronChains
+        # currently disabled, seems to be a problem with the precision calo step
+        #ChainProp(name='HLT_2e3_etcut_L12EM3', stream=[PhysicsStream], groups=MultiElectronGroup),
+        #ChainProp(name='HLT_e3_etcut_e7_etcut_L12EM3', stream=[PhysicsStream], groups=MultiElectronGroup),
+        # enabling only one step
+        #ChainProp(name='HLT_2e3_etcut1step_L12EM3', stream=[PhysicsStream], groups=MultiElectronGroup),
+        #ChainProp(name='HLT_e3_etcut1step_e7_etcut1step_L12EM3', stream=[PhysicsStream], groups=MultiElectronGroup),
+
+        #chain with asymmetric number of steps not yet working
+        #ChainProp(name='HLT_e3_etcut1step_e7_etcut_L12EM3', stream=[PhysicsStream], groups=MultiElectronGroup), 
 
         # PhotonChains------------
         ChainProp(name='HLT_g5_etcut_L1EM3', groups=SinglePhotonGroup),  
-        #-------------END OF PhotonChains
-
     ]
 
     TriggerFlags.METSlice.signatures = [
         ChainProp(name='HLT_xe30_cell_L1XE10', groups=SingleMETGroup),
         ChainProp(name='HLT_xe65_cell_L1XE50', groups=SingleMETGroup),
-#        ChainProp(name='HLT_xe30_mht_L1XE10', groups=SingleMETGroup),
+        #ChainProp(name='HLT_xe30_mht_L1XE10', groups=SingleMETGroup),
         ChainProp(name='HLT_xe30_tcpufit_L1XE10', groups=SingleMETGroup),
-        #waiting for merging strategy of chain parts
-        #ChainProp(name='HLT_xe30_cell_xe30_tcpufit_L1XE10', groups=SingleMETGroup),
+
+        # MultiMET Chain
+        #ChainProp(name='HLT_xe30_cell_xe30_tcpufit_L1XE10', groups=MultiMETGroup),
     ]
 
     TriggerFlags.JetSlice.signatures = [
@@ -99,7 +109,11 @@ def setupMenu():
         #ChainProp(name="HLT_tau25_medium1_tracktwo_L1TAU12IM", groups=SingleTauGroup),
     ]
     TriggerFlags.BphysicsSlice.signatures = [ ]
-    TriggerFlags.CombinedSlice.signatures = []
+    TriggerFlags.CombinedSlice.signatures = [ 
+        ChainProp(name='HLT_e3_etcut1step_mu6fast_L1EM8I_MU10', l1SeedThresholds=['L1_EM8I', 'L1_MU10'], stream=[PhysicsStream], groups=MultiElectronGroup),    #L1 item thresholds in wrong order (EM first, then MU)    
+        #ChainProp(name='HLT_mu8_e8_etcut_L1MU6_EM7', l1SeedThresholds=['L1_MU6', 'L1_EM7'], stream=[PhysicsStream], groups=MultiElectronGroup),    #L1 item thresholds in wrong order (EM first, then MU)    
+        #ChainProp(name='HLT_e8_etcut1step_j85_L1EM3_J20', l1SeedThresholds=['L1_EM3', 'L1_J20'], stream=[PhysicsStream], groups=MultiElectronGroup),  
+   ]
     TriggerFlags.HeavyIonSlice.signatures  = []
     TriggerFlags.BeamspotSlice.signatures  = []   
     TriggerFlags.MinBiasSlice.signatures   = []    
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
index 886b368c86a..d543db0b5e6 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py
@@ -376,7 +376,10 @@ class Chain(object):
         self.seed=Seed
         self.vseeds=[]
         vseeds = Seed.strip().split("_")
-        vseeds.pop(0) #remove first L1 string
+        if vseeds[0] == 'L1': 
+            vseeds.pop(0) #remove first L1 string
+        else:
+            log.debug('Threshol(d)s were passed')
         # split multi seeds
         for seed in vseeds:
             split=re.findall(r"(\d+)?([A-Z]+\d+)", seed)
@@ -530,6 +533,7 @@ class ChainStep(object):
     def __init__(self, name,  Sequences=[], multiplicity=1):
         self.name = name
         self.sequences=[]
+        self.multiplicity = multiplicity
         self.isCombo=multiplicity>1
         #self.isCombo=len(Sequences)>1
         self.combo=None
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuUtil.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuUtil.py
index 4a80299d726..9f283b70f0e 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuUtil.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuUtil.py
@@ -4,7 +4,7 @@ from TriggerJobOpts.TriggerFlags import TriggerFlags
 from AthenaCommon.Logging        import logging
 
 
-log = logging.getLogger('TriggerMenu.menu.MenuUtil.py')
+log = logging.getLogger('TriggerMenuMT.HLTMenuConfig.Menu.MenuUtil.py')
 
 
 
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
index 417996738b1..353f03c4ea8 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py
@@ -48,7 +48,7 @@ ChainDictTemplate = {
     'chainName'    : '',
     'L1item'        : '',
     'topo'          : '',
-    'signatures'    : '',
+    'signatures'    : [],
     'stream'        : '',
     'groups'        : [],
     'EBstep'        : '',
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py
index 80f64c23d84..655d7530f11 100755
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonDef.py
@@ -94,63 +94,63 @@ class MuonChainConfiguration(ChainConfigurationBase):
         stepName = 'Step1_mufast'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muFastSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
         
     # --------------------
     def getmuComb(self):
         stepName = 'Step1_muComb'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muCombSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     # --------------------
     def getmuEFSA(self):
         stepName = 'Step1_muEFSA'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muEFSASequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     # --------------------
     def getmuEFMS(self):
         stepName = 'Step1_muEFMS'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muEFMSSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     # --------------------
     def getmuIso(self):
         stepName = 'Step1_muIso'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muIsoSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     # --------------------
     def getmuEFCB(self):
         stepName = 'Step1_muEFCB'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muEFCBSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     # --------------------
     def getFSmuEFSA(self):
         stepName = 'Step1_FSmuEFSA'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( FSmuEFSASequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     # --------------------
     def getFSmuEFCB(self):
         stepName = 'Step1_FSmuEFCB'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( FSmuEFCBSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     #---------------------
     def getmuEFIso(self):
         stepName = 'Step1_muEFIso'
         log.debug("Configuring step " + stepName)
         muSeq = RecoFragmentsPool.retrieve( muEFIsoSequenceCfg, None)
-        return ChainStep(stepName, [muSeq])
+        return ChainStep(stepName, [muSeq], self.mult)
 
     #--------------------
     def getmuMSEmpty(self):
-- 
GitLab