diff --git a/.flake8 b/.flake8 index f09edf220fceaa55a412c0d38a93e91e3bd4ddf1..b9a430c9c3d354cab2bd67ade7784b4818291142 100644 --- a/.flake8 +++ b/.flake8 @@ -4,6 +4,5 @@ exclude = Phys/CommonParticlesArchive/* Phys/StrippingSettings/* Phys/StrippingArchive/* - Phys/Stripping/* Phys/StrippingSelections/* Phys/StrippingDoc/python/StrippingDoc/stripping* diff --git a/Phys/Stripping/python/Stripping/Configuration.py b/Phys/Stripping/python/Stripping/Configuration.py index 31664504a46f942b6acf04d3bb7dd7f315ad892a..1ae8157267e699c495820789d2a559a5c1ceaa95 100644 --- a/Phys/Stripping/python/Stripping/Configuration.py +++ b/Phys/Stripping/python/Stripping/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". # @@ -8,182 +8,182 @@ # granted to it by virtue of its status as an Intergovernmental Organization # # or submit itself to any jurisdiction. # ############################################################################### -from Configurables import LHCbConfigurableUser, GaudiSequencer -from CommonParticlesArchive import CommonParticlesArchiveConf -from StrippingConf.Configuration import StrippingConf +from __future__ import print_function +import os from Gaudi.Configuration import MessageSvc, INFO -from Configurables import DecodeRawEvent -from StrippingConf.Configuration import StrippingConf, StrippingStream -from StrippingSettings.Utils import strippingConfiguration, config_from_modules -import StrippingArchive -from StrippingArchive.Utils import buildStreams as buildStreamsFromArchive -from StrippingArchive import strippingArchive +from Configurables import LHCbConfigurableUser, GaudiSequencer from Configurables import ProcStatusCheck -from DSTWriters.Configuration import ( SelDSTWriter, - stripDSTStreamConf, - stripDSTElements, - stripMicroDSTStreamConf, - stripMicroDSTElements, - stripCalibMicroDSTStreamConf ) +from Configurables import DecodeRawEvent from Configurables import TimingAuditor, SequencerTimerTool, ChronoStatSvc from Configurables import AuditorSvc, ChronoAuditor from Configurables import StrippingReport from Configurables import AlgorithmCorrelationsAlg from Configurables import StrippingTCK from Configurables import TrackStateProvider, HltParticleFlow +from CommonParticlesArchive import CommonParticlesArchiveConf +from StrippingConf.Configuration import StrippingConf, StrippingStream +from StrippingSettings.Utils import strippingConfiguration, config_from_modules +import StrippingArchive +from StrippingArchive.Utils import buildStreams as buildStreamsFromArchive +from StrippingArchive import strippingArchive +from DSTWriters.Configuration import (SelDSTWriter, + stripDSTStreamConf, + stripDSTElements, + stripMicroDSTStreamConf, + stripMicroDSTElements, + stripCalibMicroDSTStreamConf) -import subprocess, os -class Stripping(LHCbConfigurableUser) : +class Stripping(LHCbConfigurableUser): '''Top level configuration of a full stripping job.''' __slotsanddoc__ = { - 'Version' : ('', 'Version of Stripping to run from StrippingSettings and StrippingArchive.' \ - '\nNone means both will be taken from StrippingSelections. Also defines ' \ - '\nthe version of CommonParticlesArchive to use. None means use CommonParticles.'), - 'ArchiveVersion' : ('', 'Version of StrippingArchive to use. Overrides Version.' \ - '\nNone means use StrippingSelections.'), - 'SettingsVersion' : ('', 'Version of StrippingSettings to use. Overrides Version.' \ - '\nNone means use default dicts from StrippingSelections.'), - 'UseSettingsDB' : (True, 'Whether to use the cached DB when loading configs from StrippingSettings,' \ - ' or use the python modules.'), - 'CommonParticlesArchiveVersion' : ('', 'Version of CommonParticlesArchive to use. Overrides Version.' \ - '\nNone means use CommonParticles.'), - 'Simulation' : (False, 'Whether data is MC or not'), - 'WGs' : ([], 'Which WGs to run. Can be a string or list of strings. Default all.'), - 'FilterConfigs' : ([], 'Which configs to run. An empty list means all. If a callable object is given in the list,' \ - '\nthis is passed to "filter" to select which configs are run from the list of config names.'), - 'FilterLines' : ([], 'Which lines to run. An empty list means all. If a callable object is given in the list,' \ - '\nthis is passed to "filter" to select which lines are run from the list of line names.'), - 'SingleStream' : ('', 'If set, all lines are written to a single stream of this name. Defaults to None' \ - '\nif Simulation is False, and to "AllStreams" if Simulation is True.'), - 'Filtered' : (True, 'Whether to filter selected events (for MC).'), - 'NoPrescaling' : (False, 'Disable prescaling (for MC)'), - 'MaxCandidates' : (2000, 'Max. candidates output by particle combiners'), - 'MaxCombinations' : (-1, 'Max. combinations checked by particle combiners'), - 'AcceptBadEvents' : (False, 'Accept bad events or not'), - 'StripTESPrefix' : ('Strip', 'TES prefix for stripping output'), - 'ActiveMDSTStream' : (True, 'Whether to enable the MDST.DST (latterly FTAG.DST) stream'), - 'Verbose' : (True, 'Whether StrippingConf is verbose'), - 'EnablePacking' : (True, 'Enable DST packing'), - 'SelectiveRawEvent' : (True, 'Enable per-line raw bank persistence. If False all raw banks are persisted.'), - 'MonitorTiming' : (False, 'Enable TimingAuditor and ChronoAuditor'), - 'PrintTimingTable' : (False, 'Whether the ChronoStatSvc prints the timing table.'), - 'ReportFrequency' : (0, 'If non-zero, enable StrippingReport with the given frequency'), - 'AlgorithmCorrelations' : (False, 'Enable AlgorithmCorrelationsAlg'), - 'TCK' : (0, 'Stripping TCK'), - 'DSTType' : ('dst', 'Type of DST output (can be set to, eg ldst or xdst for MC)'), - 'SplitStreamsByWG' : (False, 'Add streams split by WG'), - 'AddMergedStreamsAndStreamPerLine' : (False, 'Add a single DST and single mDST stream with all lines, and a stream per line (for BW studies)'), - 'OverrideRawEventInputs' : (4.2, 'Set the event format to be used to override the raw event inputs. If zero they won\'t be overridden.'), - 'ReportFile' : ('strippingreport.py', 'Name of the file to save the stripping report to.'), - 'HLT2Rate' : (0., 'Output rate of HLT2, for StrippingReport.'), - 'CloneLinesForTiming' : (False, 'Clone all lines and suffix their names with _TIMING for timing studies.'), - 'PatchConfig' : ([], 'Method to call to patch the config. The config will be passed as argument and assigned the return value.\n'\ - ' Has to be put in a list cause Gaudi won\'t accept functions as Configurable attributes.'), - 'PatchStreams' : ([], 'Method to call to patch the streams. The streams will be passed as argument and assigned the return value.\n'\ - ' Has to be put in a list cause Gaudi won\'t accept functions as Configurable attributes.'), - 'CacheTrackStatesOnDemand' : (False, 'Sets TrackStateProvider().CacheStatesOnDemand'), + 'Version': ('', 'Version of Stripping to run from StrippingSettings and StrippingArchive.' + + '\nNone means both will be taken from StrippingSelections. Also defines ' + + '\nthe version of CommonParticlesArchive to use. None means use CommonParticles.'), + 'ArchiveVersion': ('', 'Version of StrippingArchive to use. Overrides Version.' + + '\nNone means use StrippingSelections.'), + 'SettingsVersion': ('', 'Version of StrippingSettings to use. Overrides Version.' + + '\nNone means use default dicts from StrippingSelections.'), + 'UseSettingsDB': (True, 'Whether to use the cached DB when loading configs from StrippingSettings,' + + ' or use the python modules.'), + 'CommonParticlesArchiveVersion': ('', 'Version of CommonParticlesArchive to use. Overrides Version.' + + '\nNone means use CommonParticles.'), + 'Simulation': (False, 'Whether data is MC or not'), + 'WGs': ([], 'Which WGs to run. Can be a string or list of strings. Default all.'), + 'FilterConfigs': ([], 'Which configs to run. An empty list means all. If a callable object is given in the list,' + + '\nthis is passed to "filter" to select which configs are run from the list of config names.'), + 'FilterLines': ([], 'Which lines to run. An empty list means all. If a callable object is given in the list,' + + '\nthis is passed to "filter" to select which lines are run from the list of line names.'), + 'SingleStream': ('', 'If set, all lines are written to a single stream of this name. Defaults to None' + + '\nif Simulation is False, and to "AllStreams" if Simulation is True.'), + 'Filtered': (True, 'Whether to filter selected events (for MC).'), + 'NoPrescaling': (False, 'Disable prescaling (for MC)'), + 'MaxCandidates': (2000, 'Max. candidates output by particle combiners'), + 'MaxCombinations': (-1, 'Max. combinations checked by particle combiners'), + 'AcceptBadEvents': (False, 'Accept bad events or not'), + 'StripTESPrefix': ('Strip', 'TES prefix for stripping output'), + 'ActiveMDSTStream': (True, 'Whether to enable the MDST.DST (latterly FTAG.DST) stream'), + 'Verbose': (True, 'Whether StrippingConf is verbose'), + 'EnablePacking': (True, 'Enable DST packing'), + 'SelectiveRawEvent': (True, 'Enable per-line raw bank persistence. If False all raw banks are persisted.'), + 'MonitorTiming': (False, 'Enable TimingAuditor and ChronoAuditor'), + 'PrintTimingTable': (False, 'Whether the ChronoStatSvc prints the timing table.'), + 'ReportFrequency': (0, 'If non-zero, enable StrippingReport with the given frequency'), + 'AlgorithmCorrelations': (False, 'Enable AlgorithmCorrelationsAlg'), + 'TCK': (0, 'Stripping TCK'), + 'DSTType': ('dst', 'Type of DST output (can be set to, eg ldst or xdst for MC)'), + 'SplitStreamsByWG': (False, 'Add streams split by WG'), + 'AddMergedStreamsAndStreamPerLine': (False, 'Add a single DST and single mDST stream with all lines, and a stream per line (for BW studies)'), + 'OverrideRawEventInputs': (4.2, 'Set the event format to be used to override the raw event inputs. If zero they won\'t be overridden.'), + 'ReportFile': ('strippingreport.py', 'Name of the file to save the stripping report to.'), + 'HLT2Rate': (0., 'Output rate of HLT2, for StrippingReport.'), + 'CloneLinesForTiming': (False, 'Clone all lines and suffix their names with _TIMING for timing studies.'), + 'PatchConfig': ([], 'Method to call to patch the config. The config will be passed as argument and assigned the return value.\n' + + ' Has to be put in a list cause Gaudi won\'t accept functions as Configurable attributes.'), + 'PatchStreams': ([], 'Method to call to patch the streams. The streams will be passed as argument and assigned the return value.\n' + + ' Has to be put in a list cause Gaudi won\'t accept functions as Configurable attributes.'), + 'CacheTrackStatesOnDemand': (False, 'Sets TrackStateProvider().CacheStatesOnDemand'), } __slots__ = dict((slot, val[0]) for slot, val in __slotsanddoc__.iteritems()) _propertyDocDct = dict((slot, val[1]) for slot, val in __slotsanddoc__.iteritems()) - + __used_configurables__ = [DecodeRawEvent, SelDSTWriter] - + _knownDstStreams = {'BhadronCompleteEvent', 'CharmCompleteEvent', 'Dimuon', - 'EW', 'Semileptonic', 'Calibration', 'MiniBias', 'Radiative', + 'EW', 'Semileptonic', 'Calibration', 'MiniBias', 'Radiative', 'AllStreams', 'ALL', 'IFT'} _knownMdstStreams = {'Leptonic', 'Charm', 'PID', 'Bhadron', 'ALLMDST'} - sequence = GaudiSequencer('StrippingMainSequence', IgnoreFilterPassed = True) + sequence = GaudiSequencer('StrippingMainSequence', IgnoreFilterPassed=True) dstWriter = SelDSTWriter("MyDSTWriter") cache = {} - def _get_config(self) : + def _get_config(self): '''Get the settings config.''' - if self.getProp('SettingsVersion') : - if self.getProp('UseSettingsDB') : + if self.getProp('SettingsVersion'): + if self.getProp('UseSettingsDB'): self.cache['config'] = strippingConfiguration(self.getProp('SettingsVersion')) - else : + else: self.cache['config'] = config_from_modules(self.getProp('SettingsVersion')) - else : - # Have to do the import here cause importing StrippingSelections import CommonParticles, which - # needs to be redirected. + else: + # Have to do the import here cause importing StrippingSelections import CommonParticles, + # which needs to be redirected. from StrippingSelections import buildersConf self.cache['config'] = buildersConf() - - def _filter_configs(self) : + + def _filter_configs(self): '''Filter the configs.''' - if not self.getProp('FilterConfigs') : + if not self.getProp('FilterConfigs'): return filterconfigs = self.getProp('FilterConfigs') self.cache['config'] = dict(self.cache['config']) config = {} - for confname in filterconfigs : - if isinstance(confname, str) : - try : + for confname in filterconfigs: + if isinstance(confname, str): + try: config[confname] = self.cache['config'][confname] - except KeyError : - raise Exception("Couldn't find config {0} for Settings version {1}! Known configs are:\n{2}"\ - .format(confname, self.getProp('SettingsVersion'), - self.cache['config'].keys())) - elif hasattr(confname, '__call__') : + except KeyError: + raise Exception("Couldn't find config {0} for Settings version {1}! Known configs are:\n{2}" + .format(confname, self.getProp('SettingsVersion'), + self.cache['config'].keys())) + elif hasattr(confname, '__call__'): selected = filter(confname, self.cache['config'].keys()) - if not selected : + if not selected: raise Exception("Failed to select any configs using {0}!".format(filterconfigs)) config.update(dict((confname, self.cache['config'][confname]) for confname in selected)) - else : + else: raise TypeError("Don't know what to do with FilterConfigs {0!r}! It should be a list of strings or callables.".format(filterconfigs)) - + self.cache['config'] = config - - def _split_streams_by_wg(self) : + + def _split_streams_by_wg(self): '''Edit the configuration so that each stream is split by WG.''' - if not self.getProp('SplitStreamsByWG') : + if not self.getProp('SplitStreamsByWG'): return - print 'Splitting streams by WG' + print('Splitting streams by WG') self.cache['config'] = dict(self.cache['config']) - for config in self.cache['config'].values() : - if isinstance(config['STREAMS'], (tuple, list)) : + for config in self.cache['config'].values(): + if isinstance(config['STREAMS'], (tuple, list)): newstreams = list(config['STREAMS']) - for wg in config['WGs'] : - for stream in config['STREAMS'] : - wgstream = 'WG_' + wg + '_' + stream + for wg in config['WGs']: + for stream in config['STREAMS']: + wgstream = 'WG_' + wg + '_' + stream newstreams.append(wgstream) - if stream in self._knownDstStreams : + if stream in self._knownDstStreams: self._knownDstStreams.add(wgstream) - else : + else: self._knownMdstStreams.add(wgstream) config['STREAMS'] = newstreams - else : + else: newstreams = dict(config['STREAMS']) - for wg in config['WGs'] : - for stream, lines in config['STREAMS'].iteritems() : - wgstream = 'WG_' + wg + '_' + stream + for wg in config['WGs']: + for stream, lines in config['STREAMS'].iteritems(): + wgstream = 'WG_' + wg + '_' + stream newstreams[wgstream] = lines - if stream in self._knownDstStreams : + if stream in self._knownDstStreams: self._knownDstStreams.add(wgstream) - else : + else: self._knownMdstStreams.add(wgstream) config['STREAMS'] = newstreams - def _add_merged_and_single_line_streams(self) : + def _add_merged_and_single_line_streams(self): '''Add a single DST and single mDST stream with all lines, and a stream per line (for BW studies)''' - if not self.getProp('AddMergedStreamsAndStreamPerLine') : + if not self.getProp('AddMergedStreamsAndStreamPerLine'): return - + dstlines = set() mdstlines = set() - for stream in self.cache['streams'] : - if stream.name() in self._knownDstStreams : - for line in stream.lines : + for stream in self.cache['streams']: + if stream.name() in self._knownDstStreams: + for line in stream.lines: dstlines.add(line) - else : - for line in stream.lines : + else: + for line in stream.lines: mdstlines.add(line) dststream = StrippingStream('ALL') @@ -195,9 +195,9 @@ class Stripping(LHCbConfigurableUser) : self.cache['streams'].append(mdststream) newdststreams = [] - for line in dstlines : + for line in dstlines: streamname = 'Line_DST_' + line.name() - if streamname in newdststreams : + if streamname in newdststreams: continue newdststreams.append(streamname) linestream = StrippingStream(streamname) @@ -206,9 +206,9 @@ class Stripping(LHCbConfigurableUser) : self._knownDstStreams.add(streamname) newmdststreams = [] - for line in mdstlines : + for line in mdstlines: streamname = 'Line_MDST_' + line.name() - if streamname in newmdststreams : + if streamname in newmdststreams: continue newmdststreams.append(streamname) linestream = StrippingStream(streamname) @@ -216,244 +216,244 @@ class Stripping(LHCbConfigurableUser) : self.cache['streams'].append(linestream) self._knownMdstStreams.add(streamname) - def _build_streams(self) : + def _build_streams(self): '''Build the streams.''' - if self.getProp('ArchiveVersion') : + if self.getProp('ArchiveVersion'): self.cache['archive'] = strippingArchive(self.getProp('ArchiveVersion')) - self.cache['streams'] = buildStreamsFromArchive(stripping = self.cache['config'], - archive = self.cache['archive'], - WGs = self.getProp('WGs')) - else : + self.cache['streams'] = buildStreamsFromArchive(stripping=self.cache['config'], + archive=self.cache['archive'], + WGs=self.getProp('WGs')) + else: # Have to do the import here cause importing StrippingSelections imports CommonParticles, # which needs to be redirected. from StrippingSelections.Utils import buildStreams as buildStreamsFromSelections self.cache['archive'] = None - self.cache['streams'] = buildStreamsFromSelections(stripping = self.cache['config'], - WGs = self.getProp('WGs')) + self.cache['streams'] = buildStreamsFromSelections(stripping=self.cache['config'], + WGs=self.getProp('WGs')) # Remove MC lines if we're not running on MC. - if not self.getProp('Simulation') : - for stream in self.cache['streams'] : - stream.lines = filter(lambda line : 'MCwNoPID' not in line.name(), + if not self.getProp('Simulation'): + for stream in self.cache['streams']: + stream.lines = filter(lambda line: 'MCwNoPID' not in line.name(), stream.lines) - def _filter_lines(self) : + def _filter_lines(self): '''Filter the lines.''' - if not self.getProp('FilterLines') : + if not self.getProp('FilterLines'): return filterlines = self.getProp('FilterLines') - for stream in self.cache['streams'] : + for stream in self.cache['streams']: selected = [] - for filterline in filterlines : - if isinstance(filterline, str) : - selected += filter(lambda line : line.name() == filterline, stream.lines) - elif hasattr(filterline, '__call__') : + for filterline in filterlines: + if isinstance(filterline, str): + selected += filter(lambda line: line.name() == filterline, stream.lines) + elif hasattr(filterline, '__call__'): selected += filter(filterline, stream.lines) - else : + else: raise TypeError('FilterLines should be a list of strings or callables, don\'t know what to do with ' + repr(filterline)) stream.lines = selected # Remove empty streams. - self.cache['streams'] = filter(lambda stream : stream.lines, self.cache['streams']) + self.cache['streams'] = filter(lambda stream: stream.lines, self.cache['streams']) - if not self.cache['streams'] : + if not self.cache['streams']: raise Exception('Selected no lines using {0}!'.format(filterlines)) - def _make_single_stream(self) : + def _make_single_stream(self): '''Merge to a single DST stream if requested (eg, for MC).''' - if not self.getProp('SingleStream') : - return + if not self.getProp('SingleStream'): + return singlestream = StrippingStream(self.getProp('SingleStream')) streamnames = [] - for stream in self.cache['streams'] : - for line in stream.lines : - if not line.name() in streamnames : + for stream in self.cache['streams']: + for line in stream.lines: + if not line.name() in streamnames: singlestream.appendLines([line]) streamnames.append(line.name()) self.cache['streams'] = [singlestream] - def _set_filtered_prescaled(self) : + def _set_filtered_prescaled(self): '''Set whether to filter events, and if prescaling should be applied.''' # Filtered or not. - if not self.getProp('Filtered') : - for stream in self.cache['streams'] : + if not self.getProp('Filtered'): + for stream in self.cache['streams']: stream.sequence().IgnoreFilterPassed = True # Prescaled or not. - if self.getProp('NoPrescaling') : - for stream in self.cache['streams'] : - for line in stream.lines : + if self.getProp('NoPrescaling'): + for stream in self.cache['streams']: + for line in stream.lines: line._prescale = 1.0 - def _clone_lines_for_timing(self) : + def _clone_lines_for_timing(self): ''''Clone all lines and suffix their names with _TIMING for timing studies.''' - if not self.getProp('CloneLinesForTiming') : - return + if not self.getProp('CloneLinesForTiming'): + return newlines = {} - for stream in self.cache['streams'] : + for stream in self.cache['streams']: newstreamlines = [] - for line in stream.lines : - if not line.name() in newlines : - timingline = line.clone(l.name().strip("Stripping")+"_TIMING") + for line in stream.lines: + if not line.name() in newlines: + timingline = line.clone(line.name().strip("Stripping")+"_TIMING") newlines[line.name()] = timingline - else : + else: timingline = newlines[line.name()] newstreamlines.append(timingline) stream.appendLines(newstreamlines) - def _make_stripping_conf(self) : + def _make_stripping_conf(self): '''Make the StrippingConf.''' self.cache['dstStreams'] = [stream.name() for stream in self.cache['streams'] if stream.name() in self._knownDstStreams] self.cache['mdstStreams'] = [stream.name() for stream in self.cache['streams'] if stream.name() in self._knownMdstStreams] - #print 'DST streams :', self.cache['dstStreams'] - #print 'mDST streams :', self.cache['mdstStreams'] + # print('DST streams :', self.cache['dstStreams']) + # print('mDST streams:', self.cache['mdstStreams']) maxcombinations = self.getProp('MaxCombinations') - if maxcombinations == -1 : + if maxcombinations == -1: maxcombinations = None - self.cache['strippingconf'] = StrippingConf(Streams = self.cache['streams'], - MaxCandidates = self.getProp('MaxCandidates'), - MaxCombinations = maxcombinations, - AcceptBadEvents = self.getProp('AcceptBadEvents'), - BadEventSelection = ProcStatusCheck(), - TESPrefix = self.getProp('StripTESPrefix'), - ActiveMDSTStream = self.getProp('ActiveMDSTStream'), - Verbose = self.getProp('Verbose'), - DSTStreams = self.cache['dstStreams'], - MicroDSTStreams = self.cache['mdstStreams']) - + self.cache['strippingconf'] = StrippingConf(Streams=self.cache['streams'], + MaxCandidates=self.getProp('MaxCandidates'), + MaxCombinations=maxcombinations, + AcceptBadEvents=self.getProp('AcceptBadEvents'), + BadEventSelection=ProcStatusCheck(), + TESPrefix=self.getProp('StripTESPrefix'), + ActiveMDSTStream=self.getProp('ActiveMDSTStream'), + Verbose=self.getProp('Verbose'), + DSTStreams=self.cache['dstStreams'], + MicroDSTStreams=self.cache['mdstStreams']) + self.sequence.Members.append(self.cache['strippingconf'].sequence()) # Split FTAG/MDST stream if requested. - if not self.getProp('SplitStreamsByWG') : - return - - ftagstream = filter(lambda stream : stream.name() in ('FTAG', 'MDST'), + if not self.getProp('SplitStreamsByWG'): + return + + ftagstream = filter(lambda stream: stream.name() in ('FTAG', 'MDST'), self.cache['strippingconf'].activeStreams()) - if not ftagstream : + if not ftagstream: return ftagstream = ftagstream[0] newstreams = {} - for line in self.cache['strippingconf'].activeLines([ftagstream.name()]) : + for line in self.cache['strippingconf'].activeLines([ftagstream.name()]): # Find the WG stream that the line belongs to. - for stream in self.cache['strippingconf'].activeStreams() : - if 'WG_' == stream.name()[:3] and line.name() in [l.name() for l in stream.lines] : + for stream in self.cache['strippingconf'].activeStreams(): + if 'WG_' == stream.name()[:3] and line.name() in [ll.name() for ll in stream.lines]: streamname = 'WG_' + stream.name().split('_')[1] + '_' + ftagstream.name() - if not streamname in newstreams : + if streamname not in newstreams: newstreams[streamname] = StrippingStream(streamname) newstreams[streamname].appendLines([line]) self.cache['strippingconf'].DSTStreams += newstreams.keys() self.cache['strippingconf'].appendStreams(newstreams.values()) - def _set_tck(self) : - if not self.getProp('TCK') : - return - stck = StrippingTCK(HDRLocation = '/Event/Strip/Phys/DecReports', TCK=int(self.getProp('TCK'))) + def _set_tck(self): + if not self.getProp('TCK'): + return + stck = StrippingTCK(HDRLocation='/Event/Strip/Phys/DecReports', TCK=int(self.getProp('TCK'))) self.sequence.Members.append(stck) - def _configure_dst_writers(self) : + def _configure_dst_writers(self): '''Configure the dst writers.''' SelDSTWriterElements = { - 'default' : stripDSTElements(pack=self.getProp('EnablePacking')), + 'default': stripDSTElements(pack=self.getProp('EnablePacking')), } - mdstElements = stripMicroDSTElements(pack=self.getProp('EnablePacking')) - for mdst in self.cache['mdstStreams'] : + mdstElements = stripMicroDSTElements(pack=self.getProp('EnablePacking')) + for mdst in self.cache['mdstStreams']: SelDSTWriterElements[mdst] = mdstElements SelDSTWriterConf = { - 'default' : stripDSTStreamConf(pack = self.getProp('EnablePacking'), - selectiveRawEvent = self.getProp('SelectiveRawEvent'), - fileExtension = '.' + self.getProp('DSTType')), + 'default': stripDSTStreamConf(pack=self.getProp('EnablePacking'), + selectiveRawEvent=self.getProp('SelectiveRawEvent'), + fileExtension='.'+self.getProp('DSTType')), } - mdstStreamConf = stripMicroDSTStreamConf(pack=self.getProp('EnablePacking'), + mdstStreamConf = stripMicroDSTStreamConf(pack=self.getProp('EnablePacking'), selectiveRawEvent=self.getProp('SelectiveRawEvent')) - for mdst in self.cache['mdstStreams'] : + for mdst in self.cache['mdstStreams']: SelDSTWriterConf[mdst] = mdstStreamConf - if 'PID' in self.cache['mdstStreams'] : - SelDSTWriterConf['PID'] = stripCalibMicroDSTStreamConf(pack=self.getProp('EnablePacking'), + if 'PID' in self.cache['mdstStreams']: + SelDSTWriterConf['PID'] = stripCalibMicroDSTStreamConf(pack=self.getProp('EnablePacking'), selectiveRawEvent=self.getProp('SelectiveRawEvent')) - + self.dstWriter.StreamConf = SelDSTWriterConf self.dstWriter.MicroDSTElements = SelDSTWriterElements - if not self.dstWriter.isPropertySet('OutputFileSuffix') : - self.dstWriter.OutputFileSuffix ='000000' + if not self.dstWriter.isPropertySet('OutputFileSuffix'): + self.dstWriter.OutputFileSuffix = '000000' self.dstWriter.SelectionSequences = self.cache['strippingconf'].activeStreams() self.sequence.Members.append(self.dstWriter.sequence()) - def _configure_monitors(self) : + def _configure_monitors(self): '''Configure monitors - timing and StrippingReport.''' - if self.getProp('MonitorTiming') : - TimingAuditor().addTool(SequencerTimerTool,name="TIMER") + if self.getProp('MonitorTiming'): + TimingAuditor().addTool(SequencerTimerTool, name="TIMER") TimingAuditor().TIMER.NameSize = 60 TimingAuditor().OutputLevel = INFO AuditorSvc().Auditors.append(ChronoAuditor("Chrono")) - - if not self.getProp('PrintTimingTable') : + + if not self.getProp('PrintTimingTable'): ChronoStatSvc().ChronoPrintOutTable = False ChronoStatSvc().PrintEllapsedTime = False ChronoStatSvc().PrintSystemTime = False ChronoStatSvc().PrintUserTime = False - if self.getProp('ReportFrequency') > 0 : - sr = StrippingReport(Selections = self.cache['strippingconf'].selections(), - OnlyPositive = False, - EveryEvent = False, + if self.getProp('ReportFrequency') > 0: + sr = StrippingReport(Selections=self.cache['strippingconf'].selections(), + OnlyPositive=False, + EveryEvent=False, ReportFrequency=self.getProp('ReportFrequency'), - OutputLevel = INFO, - OutputFile = self.getProp('ReportFile'), - HLT2Rate = self.getProp('HLT2Rate')) + OutputLevel=INFO, + OutputFile=self.getProp('ReportFile'), + HLT2Rate=self.getProp('HLT2Rate')) self.sequence.Members.append(sr) - if self.getProp('AlgorithmCorrelations') : - ac = AlgorithmCorrelationsAlg(Algorithms = list(set(self.cache['strippingconf'].selections()))) + if self.getProp('AlgorithmCorrelations'): + ac = AlgorithmCorrelationsAlg(Algorithms=list(set(self.cache['strippingconf'].selections()))) self.sequence.Members.append(ac) def __apply_configuration__(self): '''Apply the configuration.''' # Check it's not already configured. - if 'strippingconf' in self.cache : + if 'strippingconf' in self.cache: return - # If 'Version' is set, use it for Archive, Settings and CommonParticles, + # If 'Version' is set, use it for Archive, Settings and CommonParticles, # if they're not set. - if self.getProp('Version') : - for prop in 'ArchiveVersion', 'SettingsVersion', 'CommonParticlesArchiveVersion' : - if not hasattr(self, prop) : + if self.getProp('Version'): + for prop in 'ArchiveVersion', 'SettingsVersion', 'CommonParticlesArchiveVersion': + if not hasattr(self, prop): setattr(self, prop, self.Version) - - if self.getProp('Simulation') and not hasattr(self, 'SingleStream') : + + if self.getProp('Simulation') and not hasattr(self, 'SingleStream'): self.SingleStream = 'AllStreams' - + MessageSvc().Format = '% F%60W%S%7W%R%T %0W%M' TrackStateProvider().CacheStatesOnDemand = self.getProp('CacheTrackStatesOnDemand') # Redirect CommonParticles to the archive. - if self.getProp('CommonParticlesArchiveVersion') : + if self.getProp('CommonParticlesArchiveVersion'): CommonParticlesArchiveConf().redirect(self.getProp('CommonParticlesArchiveVersion')) - if self.getProp('OverrideRawEventInputs') : + if self.getProp('OverrideRawEventInputs'): DecodeRawEvent().setProp("OverrideInputs", self.getProp('OverrideRawEventInputs')) - + # Get the settings config - self._get_config() + self._get_config() # Filter the configs. - self._filter_configs() + self._filter_configs() # Split streams by WG (if requested). self._split_streams_by_wg() # Patch the config. - if self.getProp('PatchConfig') : - for method in self.getProp('PatchConfig') : + if self.getProp('PatchConfig'): + for method in self.getProp('PatchConfig'): self.cache['config'] = method(self.cache['config']) # Build the streams. - self._build_streams() + self._build_streams() # Filter lines. self._filter_lines() @@ -468,8 +468,8 @@ class Stripping(LHCbConfigurableUser) : self._clone_lines_for_timing() # Patch the streams. - if self.getProp('PatchStreams') : - for method in self.getProp('PatchStreams') : + if self.getProp('PatchStreams'): + for method in self.getProp('PatchStreams'): self.cache['streams'] = method(self.cache['streams']) # Configure StrippingConf @@ -488,16 +488,16 @@ class Stripping(LHCbConfigurableUser) : # --- Test functionality --- - def check_used_configurables(self) : + def check_used_configurables(self): '''Get all instances of ConfigurableUser.''' from Gaudi.Configuration import allConfigurables, ConfigurableUser - return filter(lambda thing : isinstance(thing, ConfigurableUser), allConfigurables.values()) + return filter(lambda thing: isinstance(thing, ConfigurableUser), allConfigurables.values()) - def check_input_output(self) : + def check_input_output(self): '''Check that all Inputs of algorithms exist.''' - - from Configurables import Stripping, BTagging, DataOnDemandSvc, RelInfoConeVariables + + from Configurables import BTagging, DataOnDemandSvc, RelInfoConeVariables from Gaudi.Configuration import allConfigurables self.__apply_configuration__() @@ -507,66 +507,66 @@ class Stripping(LHCbConfigurableUser) : outputs = set(output.replace('/Event/', '') for output in DataOnDemandSvc().AlgMap.keys()) # Lines with RelatedInfoFilter redirect the output. - for stream in self.cache['streams'] : - for line in stream.lines : - if line.RelatedInfoFilter : + for stream in self.cache['streams']: + for line in stream.lines: + if line.RelatedInfoFilter: outputs.add(line.outputLocation()) - for thing in allConfigurables.values() : - try : - if hasattr(thing, 'Inputs') : + for thing in allConfigurables.values(): + try: + if hasattr(thing, 'Inputs'): # BTagging and RelInfoConeVariables take the input location without the '/Particles'. - if isinstance(thing, (BTagging, RelInfoConeVariables)) : - for inputloc in thing.Inputs : - if not inputloc.endswith('/Particles') : + if isinstance(thing, (BTagging, RelInfoConeVariables)): + for inputloc in thing.Inputs: + if not inputloc.endswith('/Particles'): inputloc += '/Particles' inputs.add(inputloc.replace('/Event/', '')) # Special case for HltParticleFlow which takes a list of lists in the format # [<class name>, <object type>, <location>]. Just extract the location. - elif isinstance(thing, HltParticleFlow) : + elif isinstance(thing, HltParticleFlow): inputs.update(inputloc[2].replace('/Event', '') for inputloc in thing.Inputs) # Assume it's a list of strings - else : + else: inputs.update(inputloc.replace('/Event/', '') for inputloc in thing.Inputs) - if hasattr(thing, 'Output') : + if hasattr(thing, 'Output'): outputs.add(thing.Output.replace('/Event/', '')) # In case handling of Input/Output attrs fails. - except : - print thing + except: # noqa + print(thing) raise - inputs = set(filter(lambda inpt : not inpt.startswith('Rec'), inputs)) + inputs = set(filter(lambda inpt: not inpt.startswith('Rec'), inputs)) # Get inputs that aren't the output of some other algo. missing = inputs.difference(outputs) missingalgs = {} - for missinput in missing : + for missinput in missing: algs = [] - for thing in allConfigurables.values() : - if not hasattr(thing, 'Inputs') : + for thing in allConfigurables.values(): + if not hasattr(thing, 'Inputs'): continue - if missinput in thing.Inputs or '/Event/' + missinput in thing.Inputs : + if missinput in thing.Inputs or '/Event/' + missinput in thing.Inputs: algs.append(thing) - if algs : + if algs: missingalgs[missinput] = algs return missingalgs - def check_hlt_filters(self, hlt1lines, hlt2lines) : + def check_hlt_filters(self, hlt1lines, hlt2lines): '''Check that HLT filters match the given lists of line names.''' self.__apply_configuration__() nomatches = {} - for stream in self.cache['streams'] : - for line in stream.lines : + for stream in self.cache['streams']: + for line in stream.lines: matches = line.check_hlt_filters(hlt1lines, hlt2lines) - if not all(matches.values()) : + if not all(matches.values()): streamnomatches = nomatches.get(stream.name(), {}) streamnomatches[line.name()] = tuple(expr for expr, ms in matches.iteritems() if not ms) nomatches[stream.name()] = streamnomatches return nomatches - def gen_python_doc(self, dvversion, datatype, stepid, fname = None) : + def gen_python_doc(self, dvversion, datatype, stepid, fname=None): '''Generate the python readable doc.''' import pprint from StrippingUtils.Utils import LineBuilder @@ -575,17 +575,17 @@ class Stripping(LHCbConfigurableUser) : # Enable the builder registry for bkk. LineBuilder.keepregistry = True - if not fname : - if not self.getProp('Version') : + if not fname: + if not self.getProp('Version'): raise ValueError('Version must be set to generate doc!') - fname = os.path.join(os.environ['STRIPPINGDOCROOT'], 'python', 'StrippingDoc', + fname = os.path.join(os.environ['STRIPPINGDOCROOT'], 'python', 'StrippingDoc', self.getProp('Version').lower() + '.py') - + linedoc = {} - for stream in self.cache['streams'] : + for stream in self.cache['streams']: streamname = stream.name() + ('.mdst' if stream.name() in self._knownMdstStreams else '.dst') - for line in stream.lines : - if line.name() in linedoc : + for line in stream.lines: + if line.name() in linedoc: linedoc[line.name()]['streams'].append(streamname) continue thislinedoc = line.python_doc() @@ -594,29 +594,29 @@ class Stripping(LHCbConfigurableUser) : thislinedoc['buildername'] = builder._name thislinedoc['buildertype'] = builder.__class__.__name__ thislinedoc['buildermodule'] = builder.__module__ - mod = __import__(builder.__module__, fromlist = ['__author__']) - try : + mod = __import__(builder.__module__, fromlist=['__author__']) + try: thislinedoc['author'] = mod.__author__ - except AttributeError : + except AttributeError: thislinedoc['author'] = None linedoc[line.name()] = thislinedoc - with open(fname, 'w') as fdoc : + with open(fname, 'w') as fdoc: fdoc.write('# ' + str(self).replace('\n', '\n# ') + '\n') - + fdoc.write('DaVinciVersion = {0!r}\n'.format(dvversion)) fdoc.write('datatype = {0!r}\n'.format(datatype)) fdoc.write('platform = {0!r}\n'.format(os.environ['CMTCONFIG'])) fdoc.write('stepid = {0}\n'.format(stepid)) fdoc.write('CondDBtag = {0!r}\n'.format(LHCbApp().getProp('CondDBtag'))) - fdoc.write('DDDBtag = {0!r}\n'.format(LHCbApp().getProp('DDDBtag'))) + fdoc.write('DDDBtag = {0!r}\n'.format(LHCbApp().getProp('DDDBtag'))) fdoc.write('TCK = ' + hex(self.getProp('TCK')) + '\n') - if self.getProp('Version') in StrippingArchive._stripping_help : + if self.getProp('Version') in StrippingArchive._stripping_help: description = StrippingArchive._stripping_help[self.getProp('Version')] - else : + else: description = '' fdoc.write('description = {0!r}\n'.format(description)) fdoc.write('lines = ' + pprint.pformat(linedoc).replace('\n', '\n' + (' ' * len('lines = ')))) # Check that it's readable. - execfile(fname) + execfile(fname) # noqa