From e3b4209d0b322d4025bb3b77e937bc1602ba575e Mon Sep 17 00:00:00 2001
From: erodrigu <eduardo.rodrigues@cern.ch>
Date: Thu, 25 May 2023 16:47:04 +0200
Subject: [PATCH 1/4] Add Flake8 linting in .gitlab-ci.yml

---
 .gitlab-ci.yml | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 707711d63..f75cf02e8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,5 @@
-###############################################################################
-## (c) Copyright 2023 CERN for the benefit of the LHCb Collaboration           #
+################################################################################
+## (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration      #
 ##                                                                             #
 ## This software is distributed under the terms of the GNU General Public      #
 ## Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -25,6 +25,15 @@ check-copyright:
 default:
   image: gitlab-registry.cern.ch/lhcb-core/lbdocker/centos7-build:latest
 
+python-linting:
+  stage: Lint
+  tags:
+    - cvmfs
+  script:
+    - . /cvmfs/lhcb.cern.ch/lib/LbEnv.sh
+    # TODO: get rid of ignores and run on full directory !
+    - flake8 --extend-ignore E501 $(find Phys/StrippingConf/python/StrippingConf/ -name '*.py')
+
 .setup_script_2016:
     before_script:
         - source /cvmfs/lhcb.cern.ch/lib/LbEnv
-- 
GitLab


From 7bda0744771fd97be23076c31868a83e7b826aec Mon Sep 17 00:00:00 2001
From: erodrigu <eduardo.rodrigues@cern.ch>
Date: Thu, 25 May 2023 16:47:35 +0200
Subject: [PATCH 2/4] Fix Phys/StrippingConf

---
 .../StrippingConfigurableUser.py              |   1 -
 .../python/StrippingConf/StrippingStream.py   | 307 +++++++++---------
 .../python/StrippingConf/Utils.py             |  83 +++--
 3 files changed, 216 insertions(+), 175 deletions(-)
 mode change 100755 => 100644 Phys/StrippingConf/python/StrippingConf/StrippingConfigurableUser.py
 mode change 100755 => 100644 Phys/StrippingConf/python/StrippingConf/StrippingStream.py

diff --git a/Phys/StrippingConf/python/StrippingConf/StrippingConfigurableUser.py b/Phys/StrippingConf/python/StrippingConf/StrippingConfigurableUser.py
old mode 100755
new mode 100644
index f10e7d7a0..6200459c7
--- a/Phys/StrippingConf/python/StrippingConf/StrippingConfigurableUser.py
+++ b/Phys/StrippingConf/python/StrippingConf/StrippingConfigurableUser.py
@@ -18,7 +18,6 @@ __all__ = (
     'StrippingConfigurableUser'
 )
 
-from GaudiConf.Configuration import *
 from Configurables import LHCbConfigurableUser
 
 
diff --git a/Phys/StrippingConf/python/StrippingConf/StrippingStream.py b/Phys/StrippingConf/python/StrippingConf/StrippingStream.py
old mode 100755
new mode 100644
index 69f9bd0a5..d1487d95a
--- a/Phys/StrippingConf/python/StrippingConf/StrippingStream.py
+++ b/Phys/StrippingConf/python/StrippingConf/StrippingStream.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 ###############################################################################
-# (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -14,50 +14,49 @@
 # StrippingStream
 #
 
-__all__ = ( 
-	    'StrippingStream'
-	  )
+__all__ = ('StrippingStream')
 
-from Gaudi.Configuration import *
-from Gaudi.Configuration import GaudiSequencer, Sequencer, Configurable
-from Configurables import LHCbConfigurableUser
+from Gaudi.Configuration import log, GaudiSequencer
+from Gaudi.Configuration import WARNING
 from copy import copy
 
-class StrippingStream ( object ) :
 
-    def __init__ ( self,
-                   name = 'StrippingStream',
-                   Lines =  [],                                    # List of stream lines
-                   BadEventSelection = "Override",                 # Bad event selection algo
-                                                                   # By default, it will be 
-                                                                   # overridden in StrippingConf, 
-                                                                   # but can be set to None here
-                                                                   # to cancel bad event check
-
-                   AcceptBadEvents = None,                         # If None, will be overridden 
-                                                                   # in StrippingConf
-		               MaxCandidates = "Override", 
-		               MaxCombinations = "Override", 
-		               TESPrefix = None
-                 ) :
+class StrippingStream(object):
+    def __init__(self,
+                 name='StrippingStream',
+                 Lines=[],                                    # List of stream lines
+                 BadEventSelection="Override",                # Bad event selection algo
+                                                              # By default, it will be
+                                                              # overridden in StrippingConf,
+                                                              # but can be set to None here
+                                                              # to cancel bad event check
+                 AcceptBadEvents=None,                        # If None, will be overridden
+                                                              # in StrippingConf
+                 MaxCandidates="Override",
+                 MaxCombinations="Override",
+                 TESPrefix=None
+                 ):
 
         self._name = name
 
         self.lines = []
         for line in Lines:
-          if line.prescale() > 0:
-            self.lines += [line]
-          else:
-            log.warning('Line '+line.name()+' has prescale <= 0, it will be removed from stream '+self.name())
+            if line.prescale() > 0:
+                self.lines += [line]
+            else:
+                log.warning('Line '+line.name() +
+                            ' has prescale <= 0, it will be removed from stream ' +
+                            self.name()
+                            )
 
-        for line in Lines : 
-    	    line.declareAppended()
+        for line in Lines:
+            line.declareAppended()
 
         self.algs = []
         self.seq = None
         self.streamLine = None                   # Line with OR of all stream lines, created in createConfigurables()
         self.eventSelectionLine = None           # Line to mark bad events, created in createConfigurables()
-        self.goodEventFilter    = None           # filter to reject bad events
+        self.goodEventFilter = None              # filter to reject bad events
         self.BadEventSelection = BadEventSelection
         self.AcceptBadEvents = AcceptBadEvents
         self.MaxCandidates = MaxCandidates
@@ -65,46 +64,48 @@ class StrippingStream ( object ) :
         self.TESPrefix = TESPrefix               # Prefix for DecReports location, configured when appending stream
         self.HDRLocation = 'Phys/DecReports'     # DecReports location, configured when appending to StrippingConf
 
-    def name(self) :
+    def name(self):
         return self._name
 
-    def clone(self, name) : 
-        return StrippingStream(name, Lines = copy(self.lines), 
-	                       BadEventSelection = self.BadEventSelection, 
-	                       AcceptBadEvents = self.AcceptBadEvents, 
-	                       MaxCandidates = self.MaxCandidates, 
-	                       MaxCombinations = self.MaxCombinations)
-
-    def appendLines (self, lines) : 
-        for line in lines : 
+    def clone(self, name):
+        return StrippingStream(name,
+                               Lines=copy(self.lines),
+                               BadEventSelection=self.BadEventSelection,
+                               AcceptBadEvents=self.AcceptBadEvents,
+                               MaxCandidates=self.MaxCandidates,
+                               MaxCombinations=self.MaxCombinations
+                               )
+
+    def appendLines(self, lines):
+        for line in lines:
             self.lines.append(line)
             line.declareAppended()
 
-    def createConfigurables(self) :
-        from Configurables import StrippingCheck
-
+    def createConfigurables(self):
         # Create configurables
 
-        if self.TESPrefix == None : self.TESPrefix = self._name
+        if self.TESPrefix is None:
+            self.TESPrefix = self._name
 
         from StrippingLine import StrippingLine
         # If the BadEventsSelection was not given neither in StrippingConf nor in StrippingStream
 
-        if self.BadEventSelection == "Override" :
+        if self.BadEventSelection == "Override":
             self.BadEventSelection = None
 
         # Make the line to mark bad events (those satisfying BadEventSelection)
 
-        if self.BadEventSelection != None :
+        if self.BadEventSelection is not None:
 
             # create the line that select bad events
             self.eventSelectionLine = StrippingLine("Stream"+self.name()+"BadEvent",
-                                                    checkPV = False, 
-                                                    algos = [ self.BadEventSelection ] )
-            self.eventSelectionLine.createConfigurable( self.TESPrefix, self.HDRLocation )
+                                                    checkPV=False,
+                                                    algos=[self.BadEventSelection]
+                                                    )
+            self.eventSelectionLine.createConfigurable(self.TESPrefix, self.HDRLocation)
             self.eventSelectionLine.declareAppended()
 
-            if self.AcceptBadEvents != False :
+            if self.AcceptBadEvents is not False:
 
                 # Need to think a bit more on this
                 log.error("NOT POSSIBLE TO ACCEPT BAD EVENTS WITH THE CURRENT CONFIGURATION OF STRIPPINGCONF!!!")
@@ -112,68 +113,70 @@ class StrippingStream ( object ) :
 
             else:
 
-                # Create a filter that negates the bad events (select good events). 
+                # Create a filter that negates the bad events (select good events).
                 # This filter will be inserted at the beginning of the filters run by all the lines.
                 from Configurables import LoKi__VoidFilter as Filter
-                self.goodEventFilter = Filter( "StrippingGoodEventCondition"+self.name() ,
-                                               Code      = " ALG_EXECUTED('%s') & ~ALG_PASSED('%s') "
-                                               % (self.eventSelectionLine.name(), self.eventSelectionLine.name()) ,
-                                               Preambulo = [ "from LoKiHlt.algorithms import *" ] )
-
-
-        for line in self.lines : 
-            if line.MaxCandidates == "Override" : 
+                self.goodEventFilter = Filter("StrippingGoodEventCondition"+self.name(),
+                                              Code=" ALG_EXECUTED('%s') & ~ALG_PASSED('%s') "
+                                              % (self.eventSelectionLine.name(), self.eventSelectionLine.name()),
+                                              Preambulo=["from LoKiHlt.algorithms import *"]
+                                              )
+
+        for line in self.lines:
+            if line.MaxCandidates == "Override":
                 line.MaxCandidates = self.MaxCandidates
-            if line.MaxCombinations == "Override" : 
+            if line.MaxCombinations == "Override":
                 line.MaxCombinations = self.MaxCombinations
 
-            if self.BadEventSelection != None :
-                if not self.AcceptBadEvents != False :
+            if self.BadEventSelection is not None:
+                if self.AcceptBadEvents is not True:
                     # inserting filter for good events inside the lines
-                    if not "StrippingGoodEventCondition" in line._members[0].name() :
-                      line._members.insert(0,self.goodEventFilter)
+                    if "StrippingGoodEventCondition" not in line._members[0].name():
+                        line._members.insert(0, self.goodEventFilter)
 
-            if line.prescale() > 0. : 
-                line.createConfigurable( self.TESPrefix, self.HDRLocation )
-                log.debug("ADDING configurable " + line.configurable().name() + "to stream " + self.name() )
+            if line.prescale() > 0.:
+                line.createConfigurable(self.TESPrefix, self.HDRLocation)
+                log.debug("ADDING configurable " + line.configurable().name() + "to stream " + self.name())
                 self.algs.append(line.configurable())
-
-            else : 
-                line.RequiredRawEvents = None #forcing None rawevents to avoid (harmless) errors from the DSTWriter
-                log.warning("Line " + line.name() + " has zero prescale, skipping" )
+            else:
+                line.RequiredRawEvents = None  # forcing None rawevents to avoid (harmless) errors from the DSTWriter
+                log.warning("Line " + line.name() + " has zero prescale, skipping")
 
         # Make the line for stream decision (OR of all stream lines)
 
         linesSeq = GaudiSequencer("StrippingStreamSeq"+self.name(),
-                                  ModeOR = True,
-                                  #ShortCircuit = False,
-                                  OutputLevel = WARNING, 
-                                  Members = self.algs)
-
-        self.streamLine = StrippingLine("Stream"+self.name(), checkPV = False, algos = [ linesSeq ] )
-        ## I think it is redundant, otherwise if it comes out it is needed
-        ## uncomment the following lines
-        #if self.BadEventSelection != None :
-        #    if not self.AcceptBadEvents != False :
-        #        if not "StrippingGoodEventCondition" in self.streamLine._members[0].name() :
+                                  ModeOR=True,
+                                  # ShortCircuit=False,
+                                  OutputLevel=WARNING,
+                                  Members=self.algs)
+
+        self.streamLine = StrippingLine("Stream"+self.name(),
+                                        checkPV=False,
+                                        algos=[linesSeq])
+        # I think it is redundant, otherwise if it comes out it is needed
+        # uncomment the following lines
+        # if self.BadEventSelection != None:
+        #    if not self.AcceptBadEvents != False:
+        #        if not "StrippingGoodEventCondition" in self.streamLine._members[0].name():
         #            self.streamLine._members.insert(0,self.goodEventFilter)
-        self.streamLine.createConfigurable( self.TESPrefix, self.HDRLocation )
+        self.streamLine.createConfigurable(self.TESPrefix, self.HDRLocation)
         self.streamLine.declareAppended()
 
-    def sequence ( self ) :
-        if self.seq == None :
+    def sequence(self):
+        if self.seq is None:
 
-            if self.eventSelectionLine == None:
+            if self.eventSelectionLine is None:
                 # We don't care of BadEvents, thus not insert bad event line in the stream sequence
                 self.seq = GaudiSequencer("StrippingSequenceStream"+self.name(),
-                                          ModeOR = True,
-                                          ShortCircuit = False,
-                                          OutputLevel = WARNING,
-                                          Members =  self.algs + [ self.streamLine.configurable() ] )
+                                          ModeOR=True,
+                                          ShortCircuit=False,
+                                          OutputLevel=WARNING,
+                                          Members=self.algs + [self.streamLine.configurable()]
+                                          )
 
             else:
 
-                if self.AcceptBadEvents != False :
+                if self.AcceptBadEvents:
 
                     # Need to think a bit more on this
                     log.error("NOT POSSIBLE TO ACCEPT BAD EVENTS WITH THE CURRENT CONFIGURATION OF STRIPPINGCONF!!!")
@@ -183,96 +186,100 @@ class StrippingStream ( object ) :
                     # since we care of bad events we have to protect the execution of lines and stream-line
                     # inserting them in a sequence with ModeOR = True and ShortCircuit = False.
                     lineSeq = GaudiSequencer("StrippingProtectedSequence"+self.name(),
-                                             ModeOR = True,
-                                             ShortCircuit = False,
-                                             OutputLevel = WARNING,
-                                             Members = self.algs + [ self.streamLine.configurable() ] )
+                                             ModeOR=True,
+                                             ShortCircuit=False,
+                                             OutputLevel=WARNING,
+                                             Members=self.algs + [self.streamLine.configurable()]
+                                             )
 
                     # We need a badEventSeq with IgnoreFilterPassed = True in order to always run the protected sequence with
                     # lines and stream-lines
                     badEventSeq = GaudiSequencer("StrippingBadEventSequence"+self.name(),
-                                                 Members = [ self.eventSelectionLine.configurable() ],
-                                                 OutputLevel = WARNING,
-                                                 IgnoreFilterPassed = True)
+                                                 Members=[self.eventSelectionLine.configurable()],
+                                                 OutputLevel=WARNING,
+                                                 IgnoreFilterPassed=True)
 
-                    # The final sequence is an AND sequence of the badEventSeq and the lines + stream-lines
-                    #  algorithms (protected sequence)
+                    # The final sequence is an AND sequence of the badEventSeq
+                    #  and the lines + stream-lines algorithms (protected sequence)
                     self.seq = GaudiSequencer("StrippingSequenceStream"+self.name(),
-                                              OutputLevel = WARNING,
-                                              Members = [ badEventSeq, lineSeq ] )
+                                              OutputLevel=WARNING,
+                                              Members=[badEventSeq, lineSeq]
+                                              )
 
         return self.seq
 
-
-    def outputLocations (self) : 
+    def outputLocations(self):
         outputList = []
-        for i in self.lines :
+        for i in self.lines:
             output = i.outputLocation()
-            if output : 
+            if output:
                 outputList.append(output)
         return outputList
 
-
-    def filterMembers( self ) : 
+    def filterMembers(self):
         _members = []
-        for line in self.lines : 
+        for line in self.lines:
             lineMembers = line.filterMembers()
-            for i in lineMembers : 
-                if i not in _members : _members.append(i) 
+            for i in lineMembers:
+                if i not in _members:
+                    _members.append(i)
         return _members
 
-
-    def getRequiredRawEvents(self) :
-        rawEvents = { }
-        for line in self.lines : 
-            if ( line.RequiredRawEvents != None ) :
-                rawEvents[line.name()] = [ "/Event/"+r+"/RawEvent#1" for r in line.RequiredRawEvents ]
+    def getRequiredRawEvents(self):
+        rawEvents = {}
+        for line in self.lines:
+            if (line.RequiredRawEvents is not None):
+                rawEvents[line.name()] = ["/Event/" + r + "/RawEvent#1" for r in line.RequiredRawEvents]
         return rawEvents
 
+    def checkRawEventRequests(self):
+        for line in self.lines:
+            if line.RequiredRawEvents is not None:
+                log.debug("Stream='"+self.name() + "' Line='" + line.name() +
+                          "' Requests RawEvents " + str(line.RequiredRawEvents))
 
-    def checkRawEventRequests(self) :
-        for line in self.lines : 
-            if line.RequiredRawEvents != None :
-                log.debug("Stream='"+self.name()+"' Line='"+line.name()+
-                          "' Requests RawEvents "+str(line.RequiredRawEvents))
-
-    def checkMDSTFlag(self) :
-        for line in self.lines :
-            if line.MDSTFlag :
-                log.debug("Stream='"+self.name()+"' Line='"+line.name()+
+    def checkMDSTFlag(self):
+        for line in self.lines:
+            if line.MDSTFlag:
+                log.debug("Stream='" + self.name() + "' Line='" + line.name() +
                           "' Requests to go to MDST.DST")
 
-    def checkFlavourTagging(self,disableFT=False,verbose=False) :
-        for line in self.lines :
-            if line._EnableFlavourTagging :
-                if verbose : log.debug("Stream='"+self.name()+"' Line='"+line.name()+
-                                         "' Requests to run FlavourTagging")
+    def checkFlavourTagging(self, disableFT=False, verbose=False):
+        for line in self.lines:
+            if line._EnableFlavourTagging:
+                if verbose:
+                    log.debug("Stream='" + self.name() + "' Line='" + line.name() +
+                              "' Requests to run FlavourTagging")
                 if disableFT:
                     line._EnableFlavourTagging = False
-                    log.warning("Stream='"+self.name()+"' Line='"+line.name()+"' Requests Flavor Tagging but is not assigned to a micro-dst stream, Flavour Tagging has been disabled")
+                    log.warning("Stream='" + self.name() + "' Line='" +
+                                line.name() +
+                                "' Requests Flavor Tagging but is not assigned to a micro-dst stream, Flavour Tagging has been disabled")  # noqa
 
-    def checkPVRefit(self) :
-        for line in self.lines :
+    def checkPVRefit(self):
+        for line in self.lines:
             sel = line.selection()
-            #for algo in line._algos:
-            if sel != None:
+            # for algo in line._algos:
+            if sel is not None:
                 props = sel.algorithm().getProperties()
                 if props.has_key('ReFitPVs'):
-                    if props['ReFitPVs'] == True:
-                        log.warning("Stream='"+self.name()+"' Line='"+line.name()+
-                                    "' Requests to refit the PV")
+                    if props['ReFitPVs']:
+                        log.warning("Stream='" + self.name() + "' Line='" +
+                                    line.name() + "' Requests to refit the PV")
 
-    def getRelatedInfoLocations(self) : 
+    def getRelatedInfoLocations(self):
         locations = []
-        for line in self.lines : 
-            if line.RelatedInfoTools != None : 
-                for tool in line.RelatedInfoTools : 
-                    if 'Locations' in tool.keys() : 
+        for line in self.lines:
+            if line.RelatedInfoTools is not None:
+                for tool in line.RelatedInfoTools:
+                    if 'Locations' in tool.keys():
                         locs = tool['Locations']
-                        for part,loc in locs.iteritems() : 
-                            if loc not in locations : locations += [ loc ]
-                    if 'Location' in tool.keys() : 
+                        for part, loc in locs.iteritems():
+                            if loc not in locations:
+                                locations += [loc]
+                    if 'Location' in tool.keys():
                         loc = tool['Location']
-                        if loc not in locations : locations += [ loc ]
-        log.info("RelatedInfoLocations for stream %s: %s" % (self.name(), str(locations)) )
+                        if loc not in locations:
+                            locations += [loc]
+        log.info("RelatedInfoLocations for stream %s: %s" % (self.name(), str(locations)))
         return locations
diff --git a/Phys/StrippingConf/python/StrippingConf/Utils.py b/Phys/StrippingConf/python/StrippingConf/Utils.py
index dc34518f1..bca422c6b 100644
--- a/Phys/StrippingConf/python/StrippingConf/Utils.py
+++ b/Phys/StrippingConf/python/StrippingConf/Utils.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -19,17 +19,22 @@ from Gaudi.Configuration import log
 
 def _limitCombinatoricsMaxCandidates(configurable, MaxCandidates,
                                      MaxCombinations, force, incidentName):
-    '''Limit combinatorics of a configurable assuming it has MaxCandidates,
-    StopAtMaxCandidates, MaxCombinations, StopAtMaxCombinations and StopIncidentType attributes.'''
+    '''
+    Limit combinatorics of a configurable assuming it has MaxCandidates,
+    StopAtMaxCandidates, MaxCombinations, StopAtMaxCombinations
+    and StopIncidentType attributes.
+    '''
 
     didsomething = False
-    if (force or not configurable.isPropertySet('MaxCandidates')) and None != MaxCandidates:
+    if (force or not configurable.isPropertySet('MaxCandidates')) and \
+            (MaxCandidates is not None):
         log.debug("Forcing MaxCandidates settings for " + configurable.name())
         configurable.MaxCandidates = MaxCandidates
         configurable.StopAtMaxCandidates = True
         didsomething = True
-    if (force or not configurable.isPropertySet('MaxCombinations')) and None != MaxCombinations:
-        log.debug("Forcing MaxCombinations settings for " + configurable.name())
+    if (force or not configurable.isPropertySet('MaxCombinations')) and \
+            (MaxCombinations is not None):
+        log.debug("Forcing MaxCombinations settings for " + configurable.name())  # noqa
         configurable.MaxCombinations = MaxCombinations
         configurable.StopAtMaxCombinations = True
         didsomething = True
@@ -38,11 +43,18 @@ def _limitCombinatoricsMaxCandidates(configurable, MaxCandidates,
     return didsomething
 
 
-def _limitCombinatoricsMaxParticles(configurable, MaxCandidates, force, incidentName):
-    '''Limit combinatorics for a configurable assuming it's got MaxParticles & StopIncidentType
-    attributes.'''
+def _limitCombinatoricsMaxParticles(configurable,
+                                    MaxCandidates,
+                                    force,
+                                    incidentName):
+    '''
+    Limit combinatorics for a configurable
+    assuming it's got MaxParticles & StopIncidentType
+    attributes.
+    '''
 
-    if (force or not configurable.isPropertySet('MaxParticles')) and None != MaxCandidates:
+    if (force or not configurable.isPropertySet('MaxParticles')) and \
+            (MaxCandidates is not None):
         log.debug("Forcing MaxParticles settings for " + configurable.name())
         configurable.MaxParticles = MaxCandidates
         configurable.StopIncidentType = incidentName
@@ -82,9 +94,11 @@ def limitCombinatorics(configurable,
                        force,
                        incidentName='ExceedsCombinatoricsLimit'):
     """
-    - This function has the highest call counts. So it needs careful optimization.
-    - Because the action is reactive, it's best to order the case of most-probable
-      to the least-probable to exit the check as early as possible.
+    - This function has the highest call counts.
+      So it needs careful optimization.
+    - Because the action is reactive, it's best to order
+      the case of most-probable to the least-probable
+      to exit the check as early as possible.
     """
 
     # Check the name by string is MUCH FASTER than by class.
@@ -102,13 +116,22 @@ def limitCombinatorics(configurable,
                 conf, MaxCandidates, MaxCombinations, force, incidentName)
         return val
 
-    if classname in ('CombineParticles', 'DaVinci__N3BodyDecays', 'DaVinci__N4BodyDecays', 'DaVinci__N5BodyDecays'):
-        return _limitCombinatoricsMaxCandidates(configurable, MaxCandidates, MaxCombinations, force, incidentName)
+    if classname in ('CombineParticles',
+                     'DaVinci__N3BodyDecays',
+                     'DaVinci__N4BodyDecays',
+                     'DaVinci__N5BodyDecays'
+                     ):
+        return _limitCombinatoricsMaxCandidates(configurable,
+                                                MaxCandidates,
+                                                MaxCombinations,
+                                                force,
+                                                incidentName)
 
     if classname == 'StrippingAlg':
         val = False
         stages = ['Filter1']
-        for conf in [getattr(configurable, stage) for stage in stages if hasattr(configurable, stage)]:
+        for conf in [getattr(configurable, stage)
+                     for stage in stages if hasattr(configurable, stage)]:
             val |= limitCombinatorics(
                 conf, MaxCandidates, MaxCombinations, force, incidentName)
         if val:
@@ -116,15 +139,28 @@ def limitCombinatorics(configurable,
         return val
 
     if classname in ('SubPIDMMFilter', 'SubstitutePID'):
-        return _limitCombinatoricsMaxParticles(configurable, MaxCandidates, force, incidentName)
+        return _limitCombinatoricsMaxParticles(configurable,
+                                               MaxCandidates,
+                                               force,
+                                               incidentName)
 
     # Generic handling (slow)
-    if hasattr(type(configurable), 'StopAtMaxCandidates') and hasattr(type(configurable), 'MaxCandidates') and \
-            hasattr(type(configurable), 'StopAtMaxCombinations') and hasattr(type(configurable), 'MaxCombinations'):
-        return _limitCombinatoricsMaxCandidates(configurable, MaxCandidates, MaxCombinations, force, incidentName)
-
-    if hasattr(configurable, 'MaxParticles') and hasattr(configurable, 'StopIncidentType'):
-        return _limitCombinatoricsMaxParticles(configurable, MaxCandidates, force, incidentName)
+    if hasattr(type(configurable), 'StopAtMaxCandidates') and \
+            hasattr(type(configurable), 'MaxCandidates') and \
+            hasattr(type(configurable), 'StopAtMaxCombinations') and \
+            hasattr(type(configurable), 'MaxCombinations'):
+        return _limitCombinatoricsMaxCandidates(configurable,
+                                                MaxCandidates,
+                                                MaxCombinations,
+                                                force,
+                                                incidentName)
+
+    if (hasattr(configurable, 'MaxParticles') and
+            hasattr(configurable, 'StopIncidentType')):
+        return _limitCombinatoricsMaxParticles(configurable,
+                                               MaxCandidates,
+                                               force,
+                                               incidentName)
 
     # Generic handling (slow)
     if hasattr(configurable, 'Members'):
@@ -135,5 +171,4 @@ def limitCombinatorics(configurable,
                 i, MaxCandidates, MaxCombinations, force, incidentName)
         return val
 
-    # log.warning('Not able to set MaxCandidates and MaxCombinations to algorithm '+str(type(configurable))+'/'+configurable.name())
     return False
-- 
GitLab


From 16ba419fcdbd211e7061814864cecd6cc4afb2df Mon Sep 17 00:00:00 2001
From: erodrigu <eduardo.rodrigues@cern.ch>
Date: Tue, 30 May 2023 12:05:19 +0200
Subject: [PATCH 3/4] Use print(...)

---
 .../python/StrippingConf/Configuration.py     | 45 ++++++++++---------
 .../python/StrippingConf/StrippingLine.py     | 10 +++--
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/Phys/StrippingConf/python/StrippingConf/Configuration.py b/Phys/StrippingConf/python/StrippingConf/Configuration.py
index 479a36ebc..f0da03b9e 100755
--- a/Phys/StrippingConf/python/StrippingConf/Configuration.py
+++ b/Phys/StrippingConf/python/StrippingConf/Configuration.py
@@ -17,6 +17,7 @@ __author__  = "Anton Poluektov <A.O.Poluektov@warwick.ac.uk>"
 #
 # Configuration of stripping framework. 
 #
+from __future__ import print_function
 
 from os import environ
 from pprint import *
@@ -108,7 +109,7 @@ class StrippingConf ( object ) :
             if self._verbose:
                 mdstLinesNames = [ line.name() for line in mdstLines ]
                 log.warning("The lines going to FTAG.DST are")
-                print mdstLinesNames
+                print(mdstLinesNames)
                 log.warning("This was the former MDST.DST which is now a regular DST stream. This implementation should only be present in S28")
                 
             if mdstLines != []:
@@ -280,32 +281,32 @@ class StrippingConf ( object ) :
         stream.HDRLocation = self._hdrLocation
         if stream.BadEventSelection == "Override" :
             if isinstance(self.BadEventSelection,dict):
-              if stream.name() in self.BadEventSelection.keys():
-                stream.BadEventSelection = self.BadEventSelection[stream.name()]
-		log.info(self._name+ " setting BadEventSelection for stream "+ stream.name() + " as " + str(stream.BadEventSelection))
-              else:
-                stream.BadEventSelection = self.BadEventSelection['default']
-                log.info(self._name+ " setting BadEventSelection for stream "+ stream.name() + " as " + str(stream.BadEventSelection))
-	      log.info(self._name+ " setting BadEventSelection for stream "+ stream.name())
+                if stream.name() in self.BadEventSelection.keys():
+                    stream.BadEventSelection = self.BadEventSelection[stream.name()]
+                    log.info(self._name+ " setting BadEventSelection for stream "+ stream.name() + " as " + str(stream.BadEventSelection))
+                else:
+                    stream.BadEventSelection = self.BadEventSelection['default']
+                    log.info(self._name+ " setting BadEventSelection for stream "+ stream.name() + " as " + str(stream.BadEventSelection))
+                log.info(self._name+ " setting BadEventSelection for stream "+ stream.name())
             else:
-              stream.BadEventSelection = self.BadEventSelection
-        if stream.AcceptBadEvents == None :
+                stream.BadEventSelection = self.BadEventSelection
+        if stream.AcceptBadEvents is None:
             if isinstance(self.AcceptBadEvents,dict):
-              if stream.name() in self.AcceptBadEvents.keys():
-                stream.AcceptBadEvents = self.AcceptBadEvents[stream.name()]
-              	log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name()  + " as " + str(stream.AcceptBadEvents))
-	      else:
-                stream.AcceptBadEvents = self.AcceptBadEvents['default']
-		log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name()  + " as " + str(stream.AcceptBadEvents))
-              log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name())
+                if stream.name() in self.AcceptBadEvents.keys():
+                    stream.AcceptBadEvents = self.AcceptBadEvents[stream.name()]
+                    log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name()  + " as " + str(stream.AcceptBadEvents))
+                else:
+                    stream.AcceptBadEvents = self.AcceptBadEvents['default']
+                    log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name()  + " as " + str(stream.AcceptBadEvents))
+                log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name())
             else:
-              stream.AcceptBadEvents = self.AcceptBadEvents
+                stream.AcceptBadEvents = self.AcceptBadEvents
 
         if stream.MaxCandidates == "Override" : 
     	    stream.MaxCandidates = self.MaxCandidates
         if stream.MaxCombinations == "Override" : 
     	    stream.MaxCombinations = self.MaxCombinations
-        
+
         stream.createConfigurables()
         self._streams.append(stream)
         self._appendSequencer(stream)
@@ -317,7 +318,7 @@ class StrippingConf ( object ) :
         btag.addTool(BTaggingTool)
         applyTuning(btag.BTaggingTool)
         self._taggingSeq = GaudiSequencer("BTaggingSequence", Members = [btag])
-        
+
     def _appendSequencer(self, stream) :
         self._streamSequencers.append(stream.sequence())
 
@@ -412,9 +413,9 @@ def string2Configurable( name ) :
         if ( t and cfg.getType() == t ) or cfg.getType() == 'ConfigurableGeneric' :
             return cfg
         else :
-            print 'got something for %s, don\'t know what to do with %s'%(self,str(cfg))
+            print('got something for %s, don\'t know what to do with %s'%(self,str(cfg)))
             return None
-    print 'cannot convert %s into a known configurable' % name
+    print('cannot convert %s into a known configurable' % name)
     return None
 
 # =============================================================================
diff --git a/Phys/StrippingConf/python/StrippingConf/StrippingLine.py b/Phys/StrippingConf/python/StrippingConf/StrippingLine.py
index c40e31bd3..7acce4014 100755
--- a/Phys/StrippingConf/python/StrippingConf/StrippingLine.py
+++ b/Phys/StrippingConf/python/StrippingConf/StrippingLine.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 ###############################################################################
-# (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -10,6 +10,8 @@
 # or submit itself to any jurisdiction.                                       #
 ###############################################################################
 
+from __future__ import print_function
+
 #
 # StrippingLine
 #
@@ -112,7 +114,7 @@ def _add_to_stripping_lines_( line ) :
     """
     lname = line.name()
     if lname in _stripping_lines__:
-        raise ValueError,"Created StrippingLine with duplicate name %s" % lname 
+        raise ValueError,"Created StrippingLine with duplicate name %s" % lname  # noqa
     _stripping_lines__[lname] = line
 
 
@@ -865,8 +867,8 @@ class StrippingLine(object):
                                      lines)
                 matches[expr] = linematches
                 if not linematches :
-                    print 'WARNING: For line', self.name(), 'trigger requirement', \
-                        expr, 'doesn\'t match any trigger line!'
+                    print('WARNING: For line' + self.name() + 'trigger requirement' +
+                          expr + 'doesn\'t match any trigger line!')
         return matches
 
     def _extract_hlt_exprs(self, code) :
-- 
GitLab


From 50af84cf6c5040483ac492d6d6d604310c18b733 Mon Sep 17 00:00:00 2001
From: erodrigu <eduardo.rodrigues@cern.ch>
Date: Tue, 30 May 2023 12:50:36 +0200
Subject: [PATCH 4/4] Please Flake8 for
 Phys/StrippingConf/python/StrippingConf/Configuration.py

---
 .../python/StrippingConf/Configuration.py     | 632 ++++++++++--------
 1 file changed, 346 insertions(+), 286 deletions(-)
 mode change 100755 => 100644 Phys/StrippingConf/python/StrippingConf/Configuration.py

diff --git a/Phys/StrippingConf/python/StrippingConf/Configuration.py b/Phys/StrippingConf/python/StrippingConf/Configuration.py
old mode 100755
new mode 100644
index f0da03b9e..5d1f9d9b4
--- a/Phys/StrippingConf/python/StrippingConf/Configuration.py
+++ b/Phys/StrippingConf/python/StrippingConf/Configuration.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -9,45 +9,44 @@
 # or submit itself to any jurisdiction.                                       #
 ###############################################################################
 """
-High level configuration tools for StrippingConf, to be used with Moore and DaVinci
+High level configuration tools for StrippingConf,
+to be used with Moore and DaVinci.
 """
 
-__author__  = "Anton Poluektov <A.O.Poluektov@warwick.ac.uk>"
+from __future__ import print_function
+__author__ = "Anton Poluektov <A.O.Poluektov@warwick.ac.uk>"
+from StrippingStream import StrippingStream
+from Configurables import StrippingAlg
+from Gaudi.Configuration import log, WARNING
 
 #
-# Configuration of stripping framework. 
+# Configuration of stripping framework.
 #
-from __future__ import print_function
 
-from os import environ
-from pprint import *
-from Gaudi.Configuration import *
-from Configurables import StrippingAlg
-from StrippingStream import StrippingStream
-from StrippingLine import StrippingLine
-from Utils import limitCombinatorics 
-
-class StrippingConf ( object ) :
-
-    def __init__( self,
-                  name = "",
-                  TESPrefix = 'Strip', 
-                  HDRLocation = 'Phys/DecReports', 
-                  Streams = [],
-                  DSTStreams = [],
-                  MicroDSTStreams = [],
-                  GlobalFlavourTagging = True,
-                  BadEventSelection = None, 
-                  AcceptBadEvents = True,
-                  MaxCandidates = None, 
-                  MaxCombinations = None,
-                  ActiveMDSTStream = False,
-                  Verbose = False ) :
-        
-        log.info("Initialising StrippingConf "+ name)
-        if name == "" :
+from Utils import limitCombinatorics
+
+
+class StrippingConf (object):
+
+    def __init__(self,
+                 name="",
+                 TESPrefix='Strip',
+                 HDRLocation='Phys/DecReports',
+                 Streams=[],
+                 DSTStreams=[],
+                 MicroDSTStreams=[],
+                 GlobalFlavourTagging=True,
+                 BadEventSelection=None,
+                 AcceptBadEvents=True,
+                 MaxCandidates=None,
+                 MaxCombinations=None,
+                 ActiveMDSTStream=False,
+                 Verbose=False):
+
+        log.info("Initialising StrippingConf " + name)
+        if name == "":
             self._name = "StrippingGlobal"
-        else :
+        else:
             self._name = name
 
         self._verbose = Verbose
@@ -67,32 +66,33 @@ class StrippingConf ( object ) :
         self.MaxCandidates = MaxCandidates
         self.MaxCombinations = MaxCombinations
 
-        ## To be uncommented to limit combinatorics for StandardParticles
-        if self.MaxCandidates != None or self.MaxCombinations != None:
+        # To be uncommented to limit combinatorics for StandardParticles
+        if self.MaxCandidates is not None or self.MaxCombinations is not None:
             self.limitCombForStdParticles()
 
-        ## Forces the limits on all configurables that implement the option...
-        if self.MaxCandidates != None or self.MaxCombinations != None:
+        # Forces the limits on all configurables that implement the option...
+        if self.MaxCandidates is not None or self.MaxCombinations is not None:
             self.checkAllForCombLimit()
 
         self.checkFlavourTagging(Streams)
 
         linesForFT = []
         if self._GlobalFlavourTagging:
-          for stream in Streams:
-            for line in stream.lines:
-              if line._EnableFlavourTagging: 
-                line._EnableFlavourTagging = False
-                linesForFT += [ line ]
+            for stream in Streams:
+                for line in stream.lines:
+                    if line._EnableFlavourTagging:
+                        line._EnableFlavourTagging = False
+                        linesForFT += [line]
 
-        for stream in Streams :
+        for stream in Streams:
             self.appendStream(stream)
 
-	# Global FT locations have to be filled after appending streams, 
-	# because outputLocations of lines can be redefined
+        # Global FT locations have to be filled after appending streams,
+        # because outputLocations of lines can be redefined
         if self._GlobalFlavourTagging:
-          for line in linesForFT:
-            self._taggingLocations += [ line.outputLocation().replace("/Particles","") ]
+            for line in linesForFT:
+                self._taggingLocations += [
+                    line.outputLocation().replace("/Particles", "")]
 
         if self._GlobalFlavourTagging and self._taggingLocations != []:
             self.appendFlavourTagging()
@@ -101,437 +101,497 @@ class StrippingConf ( object ) :
         self.checkUniqueOutputLocations()
 
         if self._verbose:
-          self.checkRawEventRequests()
-          self.checkMDSTFlag()
+            self.checkRawEventRequests()
+            self.checkMDSTFlag()
 
         if self._activeMDST:
-            mdstLines = [ line for line in self.activeLines(self.MicroDSTStreams) if line.MDSTFlag ]
+            mdstLines = [line for line in self.activeLines(
+                self.MicroDSTStreams) if line.MDSTFlag]
             if self._verbose:
-                mdstLinesNames = [ line.name() for line in mdstLines ]
+                mdstLinesNames = [line.name() for line in mdstLines]
                 log.warning("The lines going to FTAG.DST are")
                 print(mdstLinesNames)
-                log.warning("This was the former MDST.DST which is now a regular DST stream. This implementation should only be present in S28")
-                
+                log.warning(
+                    "This was the former MDST.DST which is now a regular DST stream. This implementation should only be present in S28")  # noqa
+
             if mdstLines != []:
-              mdstStream = StrippingStream( "FTAG", Lines = mdstLines )
-              self.appendStream(mdstStream)
+                mdstStream = StrippingStream("FTAG", Lines=mdstLines)
+                self.appendStream(mdstStream)
             else:
-              log.warning("No line has been selected to go to the FTAG stream (former MDST), thus it will be skipped")
- 
+                log.warning(
+                    "No line has been selected to go to the FTAG stream (former MDST), thus it will be skipped")  # noqa
+
         from Gaudi.Configuration import appendPostConfigAction
-        appendPostConfigAction ( defaultToolConfigCheck )
+        appendPostConfigAction(defaultToolConfigCheck)
 
-    def checkRawEventRequests(self) :
-        for stream in self.activeStreams() : stream.checkRawEventRequests()
+    def checkRawEventRequests(self):
+        for stream in self.activeStreams():
+            stream.checkRawEventRequests()
 
-    def checkMDSTFlag(self) :
-        for stream in self.activeStreams() : stream.checkMDSTFlag()
+    def checkMDSTFlag(self):
+        for stream in self.activeStreams():
+            stream.checkMDSTFlag()
 
-    def checkFlavourTagging(self,streams) :
-        for stream in streams : 
-          if stream.name() in self.DSTStreams : stream.checkFlavourTagging(disableFT=True,verbose=self._verbose)
-          elif stream.name() in self.MicroDSTStreams : stream.checkFlavourTagging(disableFT=False,verbose=self._verbose)
-          else : stream.checkFlavourTagging(disableFT=False,verbose=self._verbose)
+    def checkFlavourTagging(self, streams):
+        for stream in streams:
+            if stream.name() in self.DSTStreams:
+                stream.checkFlavourTagging(
+                    disableFT=True, verbose=self._verbose)
+            elif stream.name() in self.MicroDSTStreams:
+                stream.checkFlavourTagging(
+                    disableFT=False, verbose=self._verbose)
+            else:
+                stream.checkFlavourTagging(
+                    disableFT=False, verbose=self._verbose)
 
-    def checkAppendedLines (self) : 
+    def checkAppendedLines(self):
         """
         Check if all declared lines are appended to streams
         """
         allAppended = True
         from StrippingLine import strippingLines
-        for line in strippingLines() : 
-            if not line.isAppended() : 
-                log.warning("Line " + line.name() + " is declared but not appended to any stream")
+        for line in strippingLines():
+            if not line.isAppended():
+                log.warning("Line " + line.name() +
+                            " is declared but not appended to any stream")
                 allAppended = False
-	
-        if allAppended : 
+
+        if allAppended:
             log.info("All declared lines are appended to streams")
 
-    def checkUniqueOutputLocations (self) : 
+    def checkUniqueOutputLocations(self):
         """
         Check if the output locations of all active lines are unique
         """
         log.info("Checking uniqueness of output locations")
-        import sys
         locations = {}
-        for stream in self.activeStreams() :
-            for line in stream.lines :
+        for stream in self.activeStreams():
+            for line in stream.lines:
                 location = line.outputLocation()
-                if location and location != '' :
-                    if location not in locations.keys() : 
-                        locations[location] = [ (line.name(),stream.name()) ]
-                    else : 
-                        locations[location] += [ (line.name(),stream.name()) ]
+                if location and location != '':
+                    if location not in locations.keys():
+                        locations[location] = [(line.name(), stream.name())]
+                    else:
+                        locations[location] += [(line.name(), stream.name())]
         locationsUnique = True
         locationsUniqueSameStream = True
         message = ''
         messagesamestream = ''
-        for loc, nameandstream in locations.iteritems() : 
-            if len(nameandstream) > 1 :
+        for loc, nameandstream in locations.iteritems():
+            if len(nameandstream) > 1:
                 innermessage = ''
                 innerlines = {}
                 for ns in nameandstream:
-                    if innermessage=='':
-                        innermessage=str(ns[0])+"(stream "+str(ns[1])+")"
+                    if innermessage == '':
+                        innermessage = str(ns[0])+"(stream "+str(ns[1])+")"
                     else:
-                        innermessage+=" ,"+str(ns[0])+"(stream "+str(ns[1])+")"
-                    if ns[1] not in innerlines.keys() :
+                        innermessage += " ," + \
+                            str(ns[0])+"(stream "+str(ns[1])+")"
+                    if ns[1] not in innerlines.keys():
                         innerlines[ns[1]] = [ns[0]]
                     else:
-                        innerlines[ns[1]] += [ ns[0] ]
-                message += "\tLines "+innermessage+" share the same output location '"+loc+"'\n"
-                #sys.stderr.write(message)
+                        innerlines[ns[1]] += [ns[0]]
+                message += "\tLines "+innermessage+" share the same output location '"+loc+"'\n"  # noqa
+                # sys.stderr.write(message)
                 locationsUnique = False
 
-                #print innerlines
-                
-                for stinner, linner in innerlines.iteritems() :
-                    if len(linner) > 1 :
+                # print innerlines
+
+                for stinner, linner in innerlines.iteritems():
+                    if len(linner) > 1:
                         inmsg = ''
                         for inl in linner:
-                            if inmsg=='':
-                                inmsg=str(inl)+"(stream "+stinner+")"
+                            if inmsg == '':
+                                inmsg = str(inl)+"(stream "+stinner+")"
                             else:
-                                inmsg=" ,"+str(inl)+"(stream "+stinner+")"
-                        messagesamestream+="\tLines "+inmsg+" share the same output location '"+loc+"' and the same stream '"+stinner+"! Please remove duplicates in configuration'\n"
+                                inmsg = " ,"+str(inl)+"(stream "+stinner+")"
+                        messagesamestream += "\tLines "+inmsg + \
+                                             " share the same output location '"+loc + \
+                            "' and the same stream '"+stinner+"! Please remove duplicates in configuration'\n"  # noqa
                         locationsUniqueSameStream = False
-                        
-                    
-                    
-        if not locationsUnique : 
-            #raise Exception('\n' + message)
+
+        if not locationsUnique:
+            # raise Exception('\n' + message)
             log.warning('\n' + message)
 
-        if not locationsUniqueSameStream :
-            #raise Exception('\n' + message)
+        if not locationsUniqueSameStream:
+            # raise Exception('\n' + message)
             raise Exception('\n' + messagesamestream)
 
-
-    def activeStreams (self) :
+    def activeStreams(self):
         """
-        Return the list of all active StrippingStreams. 
+        Return the list of all active StrippingStreams.
         """
         return self._streams
 
-    def activeLines (self,selStream = [] ) :
+    def activeLines(self, selStream=[]):
         """
-        Return the list of all stripping lines 
+        Return the list of all stripping lines.
         """
         streams = self.activeStreams()
         lines = []
         for stream in streams:
-          if selStream != [] and stream.name() in selStream:
-            for line in stream.lines:
-              lines.append(line)
-          elif selStream == []:
-            for line in stream.lines:
-              lines.append(line)
-    
+            if selStream != [] and stream.name() in selStream:
+                for line in stream.lines:
+                    lines.append(line)
+            elif selStream == []:
+                for line in stream.lines:
+                    lines.append(line)
+
         return lines
 
-    def sequence (self) :
+    def sequence(self):
         """
         Return GaudiSequencer containing stream sequencers
         """
         from Configurables import GaudiSequencer
-        log.debug("Initialising GaudiSequencer/"+ self._name)
-        if self._sequence == None :
-            log.debug("Initialising GaudiSequencer/"+ self._name)
+        log.debug("Initialising GaudiSequencer/" + self._name)
+        if self._sequence is None:
+            log.debug("Initialising GaudiSequencer/" + self._name)
             selSeq = GaudiSequencer(self._name+"_Selection",
-                                    ModeOR = True, 
-                                    ShortCircuit = False,
-                                    OutputLevel = WARNING, 
-                                    Members = self._streamSequencers)
+                                    ModeOR=True,
+                                    ShortCircuit=False,
+                                    OutputLevel=WARNING,
+                                    Members=self._streamSequencers)
 
-            self._sequence = GaudiSequencer(self._name,Members = [selSeq])
+            self._sequence = GaudiSequencer(self._name, Members=[selSeq])
 
             if self._GlobalFlavourTagging and self._taggingLocations != []:
                 self._sequence.Members += [self._taggingSeq]
 
         return self._sequence
 
-    def selections (self) :
+    def selections(self):
         """
         Return list of selection names for TagCreator
         """
-        _selections = [ self._name ]
-        for stream in self._streams : 
+        _selections = [self._name]
+        for stream in self._streams:
             streamName = stream.sequence().name()
             _selections.append(streamName)
-            for line in stream.lines :
+            for line in stream.lines:
                 _selections.append(line.name())
         return _selections
 
-    def appendStreams(self, streams) :
+    def appendStreams(self, streams):
         """
         Append a list of streams to the configuration.
         """
-        for stream in streams :
+        for stream in streams:
             self.appendStream(stream)
-            
-    def appendStream(self, stream) :
+
+    def appendStream(self, stream):
         """
         Append a StrippingStream to the configuration. Takes care of adding
         corresponding sequencer to _streamSequencers list.
         """
-        log.info(self._name+ " appending stream "+ stream.name())
-        
-        if stream.TESPrefix == None : 
+        log.info(self._name + " appending stream " + stream.name())
+
+        if stream.TESPrefix is None:
             stream.TESPrefix = self._tesPrefix
         stream.HDRLocation = self._hdrLocation
-        if stream.BadEventSelection == "Override" :
-            if isinstance(self.BadEventSelection,dict):
+        if stream.BadEventSelection == "Override":
+            if isinstance(self.BadEventSelection, dict):
                 if stream.name() in self.BadEventSelection.keys():
-                    stream.BadEventSelection = self.BadEventSelection[stream.name()]
-                    log.info(self._name+ " setting BadEventSelection for stream "+ stream.name() + " as " + str(stream.BadEventSelection))
+                    stream.BadEventSelection = self.BadEventSelection[stream.name()]  # noqa
+                    log.info(self._name +
+                             " setting BadEventSelection for stream " +
+                             stream.name() + " as " +
+                             str(stream.BadEventSelection))
                 else:
-                    stream.BadEventSelection = self.BadEventSelection['default']
-                    log.info(self._name+ " setting BadEventSelection for stream "+ stream.name() + " as " + str(stream.BadEventSelection))
-                log.info(self._name+ " setting BadEventSelection for stream "+ stream.name())
+                    stream.BadEventSelection = self.BadEventSelection['default']  # noqa
+                    log.info(self._name +
+                             " setting BadEventSelection for stream " +
+                             stream.name() + " as " +
+                             str(stream.BadEventSelection))
+                log.info(self._name +
+                         " setting BadEventSelection for stream " +
+                         stream.name())
             else:
                 stream.BadEventSelection = self.BadEventSelection
         if stream.AcceptBadEvents is None:
-            if isinstance(self.AcceptBadEvents,dict):
+            if isinstance(self.AcceptBadEvents, dict):
                 if stream.name() in self.AcceptBadEvents.keys():
-                    stream.AcceptBadEvents = self.AcceptBadEvents[stream.name()]
-                    log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name()  + " as " + str(stream.AcceptBadEvents))
+                    stream.AcceptBadEvents = self.AcceptBadEvents[stream.name(
+                    )]
+                    log.info(self._name +
+                             " setting AcceptBadEvents for stream " +
+                             stream.name() + " as " +
+                             str(stream.AcceptBadEvents))
                 else:
                     stream.AcceptBadEvents = self.AcceptBadEvents['default']
-                    log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name()  + " as " + str(stream.AcceptBadEvents))
-                log.info(self._name+ " setting AcceptBadEvents for stream "+ stream.name())
+                    log.info(self._name +
+                             " setting AcceptBadEvents for stream " +
+                             stream.name() +
+                             " as " + str(stream.AcceptBadEvents))
+                log.info(
+                    self._name + " setting AcceptBadEvents for stream " +
+                    stream.name())
             else:
                 stream.AcceptBadEvents = self.AcceptBadEvents
 
-        if stream.MaxCandidates == "Override" : 
-    	    stream.MaxCandidates = self.MaxCandidates
-        if stream.MaxCombinations == "Override" : 
-    	    stream.MaxCombinations = self.MaxCombinations
+        if stream.MaxCandidates == "Override":
+            stream.MaxCandidates = self.MaxCandidates
+        if stream.MaxCombinations == "Override":
+            stream.MaxCombinations = self.MaxCombinations
 
         stream.createConfigurables()
         self._streams.append(stream)
         self._appendSequencer(stream)
 
-    def appendFlavourTagging(self) :
+    def appendFlavourTagging(self):
         from Configurables import BTagging, BTaggingTool, GaudiSequencer
         from FlavourTagging.Tunings import applyTuning
-        btag = BTagging( "BTag_Global",Inputs = self._taggingLocations )
+        btag = BTagging("BTag_Global", Inputs=self._taggingLocations)
         btag.addTool(BTaggingTool)
         applyTuning(btag.BTaggingTool)
-        self._taggingSeq = GaudiSequencer("BTaggingSequence", Members = [btag])
+        self._taggingSeq = GaudiSequencer("BTaggingSequence", Members=[btag])
 
-    def _appendSequencer(self, stream) :
+    def _appendSequencer(self, stream):
         self._streamSequencers.append(stream.sequence())
 
-    def decReportLocations(self) : 
+    def decReportLocations(self):
         locs = []
-        for stream in self._streams : 
-            for line in stream.lines : 
+        for stream in self._streams:
+            for line in stream.lines:
                 loc = line.decReportLocation()
-                if loc != None and loc not in locs : locs.append(loc)
+                if loc is not None and loc not in locs:
+                    locs.append(loc)
 
         return locs
 
-    def limitCombForStdParticles(self,incidentName = 'ExceedsCombinatoricsLimit'):
+    def limitCombForStdParticles(self,
+                                 incidentName='ExceedsCombinatoricsLimit'):
         from StandardParticles import locations as stdLoc
-        for loc,alg in stdLoc.iteritems():
-            if hasattr(type(alg),'StopAtMaxCandidates') and \
-               hasattr(type(alg),'MaxCandidates') and \
-               hasattr(type(alg),'StopAtMaxCombinations') and \
-               hasattr(type(alg),'MaxCombinations'):
-                if self.MaxCandidates != None:
+        for loc, alg in stdLoc.iteritems():
+            if hasattr(type(alg), 'StopAtMaxCandidates') and \
+               hasattr(type(alg), 'MaxCandidates') and \
+               hasattr(type(alg), 'StopAtMaxCombinations') and \
+               hasattr(type(alg), 'MaxCombinations'):
+                if self.MaxCandidates is not None:
                     alg.StopAtMaxCandidates = True
                     alg.MaxCandidates = self.MaxCandidates
-                if self.MaxCombinations != None:
+                if self.MaxCombinations is not None:
                     alg.StopAtMaxCombinations = True
                     alg.MaxCombinations = self.MaxCombinations
-                if self.MaxCandidates != None or self.MaxCombinations != None :
+                if self.MaxCandidates is not None or self.MaxCombinations is not None:  # noqa
                     alg.StopIncidentType = incidentName
-                ## comment to be removed once performed some more test
-                #if self._verbose: log.warning('Changed parameters StopAtMaxCandidates = '+str(alg.StopAtMaxCandidates)+' MaxCandidates = '+str(alg.MaxCandidates)+' StopIncidentType = '+str(alg.StopIncidentType)+' for algorithm '+str(alg.name()))
-
+                # comment to be removed once performed some more test
+                # if self._verbose: log.warning('Changed parameters StopAtMaxCandidates = '+str(alg.StopAtMaxCandidates)+' MaxCandidates = '+str(alg.MaxCandidates)+' StopIncidentType = '+str(alg.StopIncidentType)+' for algorithm '+str(alg.name()))  # noqa
 
     # Loops over all known configurables and applies MaxCandidate limits
-    def checkAllForCombLimit(self) :
-        '''Limit the combinatorics of all configurables using self.MaxCandidates and self.MaxCombinations,
-        unless these have already been configured. This is normally called before the streams are appended 
-        & their configurables created.'''
 
-        if self.MaxCandidates == None and self.MaxCombinations == None :
+    def checkAllForCombLimit(self):
+        '''
+        Limit the combinatorics of all configurables
+        using self.MaxCandidates and self.MaxCombinations,
+        unless these have already been configured.
+        This is normally called before the streams are appended
+        & their configurables created.
+        '''
+
+        if self.MaxCandidates is None and self.MaxCombinations is None:
             return
 
         from Gaudi.Configuration import allConfigurables
-        
-        for conf in allConfigurables.values() :
-            limitCombinatorics(conf, self.MaxCandidates, self.MaxCombinations, False)
+
+        for conf in allConfigurables.values():
+            limitCombinatorics(conf, self.MaxCandidates,
+                               self.MaxCombinations, False)
 
 
 # =============================================================================
-# Some useful decorations 
+# Some useful decorations
 # =============================================================================
-## Calculate the effective length of the string
-#  which is the length from the last '\n'-symbol 
-def len1 ( line ) :
+# Calculate the effective length of the string
+#  which is the length from the last '\n'-symbol
+def len1(line):
     """
     Calculate the effective length of the line,
-    which is thw length from the last '\n'-symbol 
+    which is thw length from the last '\n'-symbol
     """
     _i = line.rfind('\n')
     return len(line) if _i < 0 else len(line) - _i
 
-## the major properties/attributes  
-_stripping_props_   =      [ 'AcceptFraction'    , 
-                   'PercertPass'       ,
-                   'L0Channels'        ,
-                   'InputSelection'    ,
-                   'InputSelection1'   ,
-                   'InputSelection2'   ,
-                   'InputSelection3'   ,
-                   'InputSelections'   ,
-                   'OutputSelection'   ,
-                   'RecoName'          ,
-                   'MatchName'         ,
-                   'FilterDescription' ] 
-
-## Get the tuple of major interesting properties for Hlt1  objects
-def strippingProps () :
+
+# the major properties/attributes
+_stripping_props_ = ['AcceptFraction',
+                     'PercertPass',
+                     'L0Channels',
+                     'InputSelection',
+                     'InputSelection1',
+                     'InputSelection2',
+                     'InputSelection3',
+                     'InputSelections',
+                     'OutputSelection',
+                     'RecoName',
+                     'MatchName',
+                     'FilterDescription']
+
+# Get the tuple of major interesting properties for Hlt1  objects
+
+
+def strippingProps():
     """
     Get the tuple of major interesting properties for Hlt1  objects
 
     """
-    _stripping_props_.sort() 
+    _stripping_props_.sort()
     return tuple(_stripping_props_)
 
 
 # =============================================================================
-## Try to promote a string to the corresponding configurable
-def string2Configurable( name ) :
+# Try to promote a string to the corresponding configurable
+def string2Configurable(name):
     # try to decode it into something reasonable
-    (n,t) = (name,None) if name.find('/') == -1 else name.split('/')
+    (n, t) = (name, None) if name.find('/') == -1 else name.split('/')
     from Gaudi.Configuration import allConfigurables
     cfg = allConfigurables.get(n)
-    if cfg :
-        if ( t and cfg.getType() == t ) or cfg.getType() == 'ConfigurableGeneric' :
+    if cfg:
+        if (t and cfg.getType() == t) or cfg.getType() == 'ConfigurableGeneric':  # noqa
             return cfg
-        else :
-            print('got something for %s, don\'t know what to do with %s'%(self,str(cfg)))
+        else:
+            print('got something for %s, don\'t know what to do with %s' %
+                  (name, str(cfg)))
             return None
     print('cannot convert %s into a known configurable' % name)
     return None
 
 # =============================================================================
-## Print the major properties/attributes of the configurables
+# Print the major properties/attributes of the configurables
 #  @param obj  the object to be inspected
-#  @param lst  list of attributes/properties 
+#  @param lst  list of attributes/properties
 #  @param line the (output) line
 #  @paral l1   the indentation parameter
 #  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 #  @date 2008-08-06
-def prnt ( obj        ,   # the object 
-           lst  = []  ,   # list of 'major' properties
-           line = ''  ,   # the line to eb updated
-           l1   = 65  ) : # the indentation/format parameter 
+
+
+def prnt(obj,   # the object
+         lst=[],   # list of 'major' properties
+         line='',   # the line to eb updated
+         l1=65):  # the indentation/format parameter
     """
     Print the major properties/attributes of the configurables
     @param obj  the object to be inspected
-    @param lst  list of attributes/properties 
+    @param lst  list of attributes/properties
     @param line the (output) line
     @paral l1   the indentation parameter
     @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
     @date 2008-08-06
 
     >>> obj = ...  # get the object/configurable
-    >>> print prnt ( obj , [ 'OutputLevel' , 'Members'] ) # print... 
-    
+    >>> print prnt ( obj , [ 'OutputLevel' , 'Members'] ) # print...
+
     """
-    if not lst : lst = strippingProps () 
-    elif list  is type(lst) : pass
-    elif tuple is type(lst) : pass
-    else : lst = [ lst ]
+    if not lst:
+        lst = strippingProps()
+    elif list is type(lst):
+        pass
+    elif tuple is type(lst):
+        pass
+    else:
+        lst = [lst]
     #
-    for item in lst :
-        if hasattr ( obj , item ) :
-            if l1 < len1( line ) : line += '\n' + l1*' '
-            line += "%-15s : %s" % ( item , getattr ( obj , item ) )
-    return line 
+    for item in lst:
+        if hasattr(obj, item):
+            if l1 < len1(line):
+                line += '\n' + l1*' '
+            line += "%-15s : %s" % (item, getattr(obj, item))
+    return line
 
 # =============================================================================
-## The helper function for narcissic self-print of sequences  & algorithms 
+# The helper function for narcissic self-print of sequences  & algorithms
 #  @param self  the object to be inspected
 #  @param level the recursion level
-#  @param lst   the list of major properties/attributes 
+#  @param lst   the list of major properties/attributes
 #  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
 #  @date 2008-08-06
-def __enroll__ ( self       ,   ## the object
-                 level = 0  ,   ## the recursion level
-                 lst   = [] ) : ## the major properties  
+
+
+def __enroll__(self,  # the object
+               level=0,  # the recursion level
+               lst=[]):  # the major properties
     """
-    The helper function for narcissic self-print of sequences  & algorithms 
+    The helper function for narcissic self-print of sequences  & algorithms
     @param self  the object to be inspected
     @param level the recursion level
-    @param lst   the list of major properties/attributes 
+    @param lst   the list of major properties/attributes
     @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
     @date 2008-08-06
-    
+
     """
 
-    if type(self) == str :
+    if type(self) == str:
         cfg = string2Configurable(self)
-        if cfg : self = cfg
-    if hasattr ( self , 'sequence' ) :
-        return __enroll__ ( self.sequence() , level )
-    if hasattr ( self , 'sequencer' ) :
-        return __enroll__ ( self.sequencer() , level )
+        if cfg:
+            self = cfg
+    if hasattr(self, 'sequence'):
+        return __enroll__(self.sequence(), level)
+    if hasattr(self, 'sequencer'):
+        return __enroll__(self.sequencer(), level)
 
     _tab = 50
-    _indent_ = ('%-3d'%level) + level * '   ' 
-    try:     line = _indent_ + self.name ()
-    except:  line = _indent_ + ( self if type(self) == str else '<UNKNOWN>' )
-        
-    if len1(line)>( _tab-1): line +=  '\n'+ _tab*' '
-    else :                   line +=  (_tab-len1(line))*' '
-    try:                     line +=  '%-25.25s'%self.getType()
-    except:                  line +=  '<UNKNOWN>'
-
-    line = prnt ( self , lst , line, l1 = _tab+25 ) + '\n'
-
-    # use the recursion 
-    if hasattr ( self , 'Members' ) :
-        for _m in getattr(self,'Members') : line += __enroll__ ( _m , level + 1 , lst ) 
-
-    if type(self) is StrippingAlg :
-        for i in [ 'Prescale','ODIN','L0DU','HLT','Filter1','Postscale' ] :
-            if hasattr(self,i) : line += __enroll__( getattr(self,i), level + 1, lst )
-
-    if type(self) is StrippingConf : 
+    _indent_ = ('%-3d' % level) + level * '   '
+    try:
+        line = _indent_ + self.name()
+    except:  # noqa
+        line = _indent_ + (self if type(self) == str else '<UNKNOWN>')
+
+    if len1(line) > (_tab-1):
+        line += '\n' + _tab*' '
+    else:
+        line += (_tab-len1(line))*' '
+    try:
+        line += '%-25.25s' % self.getType()
+    except:  # noqa
+        line += '<UNKNOWN>'
+
+    line = prnt(self, lst, line, l1=_tab+25) + '\n'
+
+    # use the recursion
+    if hasattr(self, 'Members'):
+        for _m in getattr(self, 'Members'):
+            line += __enroll__(_m, level + 1, lst)
+
+    if type(self) is StrippingAlg:
+        for i in ['Prescale', 'ODIN', 'L0DU', 'HLT', 'Filter1', 'Postscale']:
+            if hasattr(self, i):
+                line += __enroll__(getattr(self, i), level + 1, lst)
+
+    if type(self) is StrippingConf:
         lines = 0
-        for i in self.activeStreams() : 
+        for i in self.activeStreams():
             lines += len(i.sequence().Members)
-        line += "Summary: " + len(self.sequence().Members) + " streams, " + lines + " lines\n"
+        line += "Summary: " + len(self.sequence().Members) + \
+            " streams, " + lines + " lines\n"
 
     return line
 
-def defaultToolConfigCheck () : 
+
+def defaultToolConfigCheck():
     from Gaudi.Configuration import allConfigurables
-    
+
     log.info('Checking if public tools have default configuration')
 
-    for conf in allConfigurables.values() : 
-        if conf.name().find('ToolSvc.')>=0 : 
+    for conf in allConfigurables.values():
+        if conf.name().find('ToolSvc.') >= 0:
             difference = []
-            if isinstance(type(conf).__slots__,dict) : 
-                for k,v in type(conf).__slots__.iteritems() : 
-                    if hasattr(conf, k) : 
-                        val = getattr(conf,k)
-                        if val not in allConfigurables.values() : 
-                            if v != val : 
-                                difference.append( (k, v, val ) )
-            if len(difference) > 0 : 
-                log.warning( 'tool %s has non-default configuration! Attributes that differ:' % conf.name() )
-                for d in difference : 
-                    log.warning( '    %s = %s (default = %s)' % ( d[0], str(d[2]), str(d[1]) ) )
-
-
-for conf in [ StrippingAlg, StrippingStream, StrippingConf] :
-    if conf :
-        conf.__str__ = __enroll__ 
-
+            if isinstance(type(conf).__slots__, dict):
+                for k, v in type(conf).__slots__.iteritems():
+                    if hasattr(conf, k):
+                        val = getattr(conf, k)
+                        if val not in allConfigurables.values():
+                            if v != val:
+                                difference.append((k, v, val))
+            if len(difference) > 0:
+                log.warning(
+                    'tool %s has non-default configuration! Attributes that differ:' % conf.name())  # noqa
+                for d in difference:
+                    log.warning('    %s = %s (default = %s)' %
+                                (d[0], str(d[2]), str(d[1])))
+
+
+for conf in [StrippingAlg, StrippingStream, StrippingConf]:
+    if conf:
+        conf.__str__ = __enroll__
-- 
GitLab