HLTTriggerResultGetter.py 24.8 KB
Newer Older
1
# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
2
3

from TriggerJobOpts.TriggerFlags import TriggerFlags
4
5
from AthenaCommon.Logging import logging
from AthenaCommon.GlobalFlags import globalflags
6

7
from AthenaCommon.AppMgr import ServiceMgr
8
9
10
11
12
from RecExConfig.Configured import Configured

from RecExConfig.RecAlgsFlags import recAlgs
from RecExConfig.RecFlags import rec

13
14
from TrigRoiConversion.TrigRoiConversionConf import RoiWriter

15

16
17
def  EDMDecodingVersion():

18
    log = logging.getLogger("EDMDecodingVersion")
19

20
    # BYTESTREAM: decide Run3 or later based on ROD version, decide Run1/Run2 based on run number
21
    if globalflags.InputFormat.is_bytestream():
22
23
24
25
26
27
28

        # Check HLT ROD version in first event of first input file
        from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
        inputFileName = athenaCommonFlags.FilesInput()[0]
        import eformat
        from libpyeformat_helper import SubDetector
        bs = eformat.istream(inputFileName)
29

30
31
        rodVersionM = -1
        rodVersionL = -1
32
33
34
35
36
37
38
39
40
41
42
43
        # Do an empty loop over all robs to work around memory allocation problem ATR-20480
        for robf in bs[0].robs()[0]:
            pass
        # Find the first HLT ROBFragment in the first event
        for robf in bs[0].robs()[0]:
            if robf.rob_source_id().subdetector_id()==SubDetector.TDAQ_HLT:
                rodVersionM = robf.rod_minor_version() >> 8
                rodVersionL = robf.rod_minor_version() & 0xFF
                log.debug("HLT ROD minor version from input file is %d.%d", rodVersionM, rodVersionL)
                break

        if rodVersionM < 0 or rodVersionL < 0:
44
            log.warning("Cannot determine HLT ROD version from input file, falling back to runNumber-based decision")
45
        elif rodVersionM >= 1:
46
47
48
49
50
            TriggerFlags.EDMDecodingVersion = 3
            log.info("Decoding version set to 3, because running on BS file with HLT ROD version %d.%d", rodVersionM, rodVersionL)
            return

        # Use run number to determine decoding version
51
52
53
        from RecExConfig.AutoConfiguration  import GetRunNumber
        runNumber = GetRunNumber()

54
55
56
57
58
59
60
61
        boundary_run12 = 230000
        boundary_run23 = 368000

        if runNumber <= 0:
            log.error("Cannot determine decoding version because run number %d is invalid. Leaving the default version %d",
                        runNumber, TriggerFlags.EDMDecodingVersion())
        elif runNumber < boundary_run12:
            # Run-1 data
62
            TriggerFlags.EDMDecodingVersion = 1
63
            TriggerFlags.doMergedHLTResult = False
64
65
66
67
68
69
70
71
72
73
74
75
76
            log.info("Decoding version set to 1 based on BS file run number (runNumber < %d)",
                        boundary_run12)
        elif runNumber < boundary_run23:
            # Run-2 data
            TriggerFlags.EDMDecodingVersion = 2
            log.info("Decoding version set to 2 based on BS file run number (%d < runNumber < %d)",
                        boundary_run12, boundary_run23)
        else:
            # Run-3 data
            TriggerFlags.EDMDecodingVersion = 3
            log.info("Decoding version set to 3 based on BS file run number (runNumber > %d)",
                        boundary_run23)

77
    else:
78
        # POOL files: decide based on HLT output type present in file
79
        from RecExConfig.ObjKeyStore import cfgKeyStore
80
81
82
        from PyUtils.MetaReaderPeeker import convert_itemList
        cfgKeyStore.addManyTypesInputFile(convert_itemList(layout='#join'))

83
        TriggerFlags.doMergedHLTResult = True
84
        if cfgKeyStore.isInInputFile( "HLT::HLTResult", "HLTResult_EF" ):
85
            TriggerFlags.EDMDecodingVersion = 1
86
            TriggerFlags.doMergedHLTResult = False
87
            log.info("Decoding version set to 1, because HLTResult_EF found in POOL file")
88
        elif cfgKeyStore.isInInputFile( "HLT::HLTResult", "HLTResult_HLT"):
89
            TriggerFlags.EDMDecodingVersion = 2
90
            log.info("Decoding version set to 2, because HLTResult_HLT found in POOL file")
91
        elif cfgKeyStore.isInInputFile( "xAOD::TrigCompositeContainer", "HLTNav_Summary"):
92
            TriggerFlags.EDMDecodingVersion = 3
93
94
95
96
97
            log.info("Decoding version set to 3, because HLTNav_Summary found in POOL file")
        elif rec.readAOD() and cfgKeyStore.isInInputFile( "xAOD::TrigNavigation", "TrigNavigation"):
            # If running on AOD input (e.g. for monitoring), there is not HLTResult, so check for TrigNavigation
            TriggerFlags.EDMDecodingVersion = 2
            log.info("Decoding version set to 2, because TrigNavigation found in POOL file")
98
99
100
101
102
103
104
105
        elif rec.readRDO():
            # If running Trigger on RDO input (without previous trigger result), choose Run-2 or Run-3 based on doMT
            if TriggerFlags.doMT():
                TriggerFlags.EDMDecodingVersion = 3
                log.info("Decoding version set to 3, because running Trigger with doMT=True")
            else:
                TriggerFlags.EDMDecodingVersion = 2
                log.info("Decoding version set to 2, because running Trigger with doMT=False")
106
        else:
107
            log.warning("Cannot recognise HLT EDM format, leaving default TriggerFlags.EDMDecodingVersion=%d", TriggerFlags.EDMDecodingVersion())
108
109


110
111
class xAODConversionGetter(Configured):
    def configure(self):
112
        from AthenaCommon.AlgSequence import AlgSequence
113
114
115
116
117
118
119
120
        topSequence = AlgSequence()

        #schedule xAOD conversions here
        from TrigBSExtraction.TrigBSExtractionConf import TrigHLTtoxAODConversion
        xaodconverter = TrigHLTtoxAODConversion()
        
        from TrigNavigation.TrigNavigationConfig import HLTNavigationOffline
        xaodconverter.Navigation = HLTNavigationOffline()
121

122
123
        from TrigEDMConfig.TriggerEDM import getPreregistrationList
        from TrigEDMConfig.TriggerEDM import getEFRun1BSList,getEFRun2EquivalentList,getL2Run1BSList,getL2Run2EquivalentList
124
125
126
127
128
129
130
        xaodconverter.Navigation.ClassesToPreregister = getPreregistrationList(TriggerFlags.EDMDecodingVersion())
        ## if TriggerFlags.EDMDecodingVersion() == 2:
        ##     #        if TriggerFlags.doMergedHLTResult():
        ##     #if EDMDecodingVersion() =='Run2': #FPP
        ##     xaodconverter.Navigation.ClassesToPreregister = getHLTPreregistrationList()
        ## else:
        ##     xaodconverter.Navigation.ClassesToPreregister = list(set(getL2PreregistrationList()+getEFPreregistrationList()+getHLTPreregistrationList()))
131
132

        #we attempt to convert the entire old navigation (L2+EF)
133
134
135
136
        #xaodconverter.BStoxAOD.ContainersToConvert = list(set(getL2PreregistrationList()+getEFPreregistrationList()))
        # we want only containers from Run 1 with the BS tag
        xaodconverter.BStoxAOD.ContainersToConvert = getL2Run1BSList() + getEFRun1BSList()
        xaodconverter.BStoxAOD.NewContainers = getL2Run2EquivalentList() + getEFRun2EquivalentList()
137
138
139
140

        xaodconverter.HLTResultKey="HLTResult_EF"
        topSequence += xaodconverter

141
142
143
144
145
146
        # define list of HLT xAOD containers to be written to the output root file
        # (previously this was defined in HLTTriggerResultGetter def configure)
        from TrigEDMConfig.TriggerEDM import getTriggerEDMList
        self.xaodlist = {}
        self.xaodlist.update( getTriggerEDMList(TriggerFlags.ESDEDMSet(), 2 ))

147
148
149
150
151
152
        return True
    
        

class ByteStreamUnpackGetter(Configured):
    def configure(self):
153
        log = logging.getLogger("ByteStreamUnpackGetter")
154

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
        log.info( "TriggerFlags.dataTakingConditions: %s", TriggerFlags.dataTakingConditions() )
        hasHLT = TriggerFlags.dataTakingConditions()=='HltOnly' or TriggerFlags.dataTakingConditions()=='FullTrigger'
        if not hasHLT:
            log.info("Will not configure HLT BS unpacking because dataTakingConditions flag indicates HLT was disabled")
            return True

        # Define the decoding sequence
        from TrigHLTResultByteStream.TrigHLTResultByteStreamConf import HLTResultMTByteStreamDecoderAlg
        from TrigOutputHandling.TrigOutputHandlingConf import TriggerEDMDeserialiserAlg
        from AthenaCommon.CFElements import seqAND
        decoder = HLTResultMTByteStreamDecoderAlg()
        deserialiser = TriggerEDMDeserialiserAlg("TrigDeserialiser")
        decodingSeq = seqAND("HLTDecodingSeq")
        decodingSeq += decoder  # BS -> HLTResultMT
        decodingSeq += deserialiser  # HLTResultMT -> xAOD

        # Append the decoding sequence to topSequence
        from AthenaCommon.AlgSequence import AlgSequence
        topSequence = AlgSequence()
        topSequence += decodingSeq

        log.debug("Configured HLT result BS decoding sequence")
        return True

class ByteStreamUnpackGetterRun2(Configured):
    def configure(self):

        log = logging.getLogger("ByteStreamUnpackGetterRun2")
183
184
185
186
        from AthenaCommon.AlgSequence import AlgSequence 
        topSequence = AlgSequence()
        
        #if TriggerFlags.readBS():
187
        log.info( "TriggerFlags.dataTakingConditions: %s", TriggerFlags.dataTakingConditions() )
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
        # in MC this is always FullTrigger
        hasHLT = TriggerFlags.dataTakingConditions()=='HltOnly' or TriggerFlags.dataTakingConditions()=='FullTrigger'
        
        if hasHLT:
            # Decide based on the run number whether to assume a merged, or a
            # split HLT:
            if not TriggerFlags.doMergedHLTResult():
                ServiceMgr.ByteStreamAddressProviderSvc.TypeNames += [
                    "HLT::HLTResult/HLTResult_L2",
                    "HLT::HLTResult/HLTResult_EF" ]
            else:
                ServiceMgr.ByteStreamAddressProviderSvc.TypeNames += [
                    "HLT::HLTResult/HLTResult_HLT" ]
                pass
            pass

        # BS unpacking
        from TrigBSExtraction.TrigBSExtractionConf import TrigBSExtraction
        extr = TrigBSExtraction()
        
        if hasHLT:
            from TrigNavigation.TrigNavigationConfig import HLTNavigationOffline
            extr.Navigation = HLTNavigationOffline()
211
212

            from TrigEDMConfig.TriggerEDM import getEDMLibraries
213
            extr.Navigation.Dlls = getEDMLibraries()            
214
215
216
217
218

            from TrigEDMConfig.TriggerEDM import getPreregistrationList
            extr.Navigation.ClassesToPreregister = getPreregistrationList(TriggerFlags.EDMDecodingVersion())
            
            if TriggerFlags.doMergedHLTResult():
219
220
                extr.L2ResultKey=""
                extr.EFResultKey=""
221
222
            else:
                extr.HLTResultKey=""
223
224
225
226

            #
            # Configure DataScouting
            #
227
228
229
230
231
232
233
234
235
236
237
            from PyUtils.MetaReaderPeeker import metadata

            stream_local = metadata['stream']

            if stream_local.startswith('calibration_DataScouting_') or TriggerFlags.doAlwaysUnpackDSResult():
                if 'calibration' in stream_local and 'DataScouting_' in stream_local:
                    ds_tag = stream_local[12:27]
                    ServiceMgr.ByteStreamAddressProviderSvc.TypeNames += [ "HLT::HLTResult/"+ds_tag ]
                    extr.DSResultKeys += [ ds_tag ]

        else:
238
239
240
241
242
            #if data doesn't have HLT info set HLTResult keys as empty strings to avoid warnings
            # but the extr alg must run
            extr.L2ResultKey=""
            extr.EFResultKey=""
            extr.HLTResultKey=""
243
            extr.DSResultKeys=[]
244
245
246
247
248
249
250
251
252

        topSequence += extr
        
        from TrigSerializeTP.TrigSerializeTPConf import TrigSerTPTool
        TrigSerToolTP = TrigSerTPTool('TrigSerTPTool')

        from AthenaCommon.AppMgr import ToolSvc
        ToolSvc += TrigSerToolTP
        from TrigEDMConfig.TriggerEDM import getTPList
253
        TrigSerToolTP.TPMap = getTPList((TriggerFlags.EDMDecodingVersion()))
254
255
256
257
258
        
        from TrigSerializeCnvSvc.TrigSerializeCnvSvcConf import TrigSerializeConvHelper
        TrigSerializeConvHelper = TrigSerializeConvHelper(doTP = True)
        ToolSvc += TrigSerializeConvHelper

259
260
261
262
        #
        # Configure L1Topo validation data algorithm
        #
        if hasHLT and TriggerFlags.doMergedHLTResult() and TriggerFlags.writeL1TopoValData() :
263
264
265
266
            # make sure that CTP_RDO is known (see also ATR-14683)
            ServiceMgr.ByteStreamAddressProviderSvc.TypeNames += [
                "CTP_RDO/CTP_RDO"
                ]
267
268
269
270
            from L1TopoValDataCnv.L1TopoValDataCnvConf import xAODMaker__L1TopoValDataCnvAlg
            L1TopoValDataCvnAlg = xAODMaker__L1TopoValDataCnvAlg()
            topSequence += L1TopoValDataCvnAlg

271
272
273
274
        return True


class TrigDecisionGetter(Configured):
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    def configure(self):
        log = logging.getLogger("TrigDecisionGetter")

        from AthenaCommon.AlgSequence import AlgSequence
        topSequence = AlgSequence()

        from TrigDecisionMaker.TrigDecisionMakerConfig import TrigDecisionMakerMT
        tdm = TrigDecisionMakerMT('TrigDecMakerMT')

        if not TriggerFlags.readBS():
            # Construct trigger bits from HLTNav_summary instead of reading from BS
            from TrigOutputHandling.TrigOutputHandlingConf import TriggerBitsMakerTool
            tdm.BitsMakerTool = TriggerBitsMakerTool()

        topSequence += tdm
        log.info('xTrigDecision writing enabled')

        return True

class TrigDecisionGetterRun2(Configured):
295
296
297
    #class to setup the writing or just making of TrigDecisionObject
    def configure(self):
        
298
        log = logging.getLogger("TrigDecisionGetterRun2")
299
300
301
302
303
304
305
306
307
308
309

        from AthenaCommon.AlgSequence import AlgSequence 
        topSequence = AlgSequence()
        
        #if hasOnlyLVL1:
        #from RecExConfig.ObjKeyStore import objKeyStore
        #objKeyStore.addStreamESD('TrigDec::TrigDecision','TrigDecision')
        #objKeyStore.addStreamAOD('TrigDec::TrigDecision','TrigDecision')
        
        from RecExConfig.RecFlags import rec
        if ( rec.doWriteESD() or rec.doWriteAOD() or rec.doESD() or rec.doAOD() ) and \
310
               ( not ( rec.readAOD() or rec.readESD() or rec.doWriteBS()) ):
311
            log.info("Will write TrigDecision object to storegate")
312
            
313
            from TrigDecisionMaker.TrigDecisionMakerConfig import WriteTrigDecision
314
            trigDecWriter = WriteTrigDecision()  # noqa: F841
315
316
317
318

#            from TrigDecisionMaker.TrigDecisionMakerConfig import WritexAODTrigDecision
#            trigDecWriter = WritexAODTrigDecision()

319
320
321
322
323
324
325
326
            # inform TD maker that some parts may be missing
            if TriggerFlags.dataTakingConditions()=='Lvl1Only':
                topSequence.TrigDecMaker.doL2=False
                topSequence.TrigDecMaker.doEF=False
                topSequence.TrigDecMaker.doHLT=False
            elif TriggerFlags.dataTakingConditions()=='HltOnly':
                from AthenaCommon.AlgSequence import AlgSequence
                topSequence.TrigDecMaker.doL1=False
327
            # Decide based on the doMergedHLTResult to assume a merged, or a
328
329
330
331
332
333
334
335
336
337
            # split HLT:
            if not TriggerFlags.doMergedHLTResult():
                topSequence.TrigDecMaker.doHLT = False
            else:
                topSequence.TrigDecMaker.doL2 = False
                topSequence.TrigDecMaker.doEF = False
                pass
                
        else:
            log.info("Will not write TrigDecision object to storegate")
338
    
339
340
341
342
343
344
345
346
347
348
349
350
        return True
    
    
class HLTTriggerResultGetter(Configured):

    log = logging.getLogger("HLTTriggerResultGetter.py")

    def _AddOPIToESD(self):

        log = logging.getLogger("HLTTriggerResultGetter.py")        
        
        if rec.doESD():
351
352
353
354
            from PyUtils.MetaReaderPeeker import metadata
            if 'stream' in metadata:
                stream = metadata['stream']
                log.debug("the stream found in 'metadata' is "+stream)
355
356
                if "express" in stream:
                    from TrigEDMConfig.TriggerEDM import getTypeAndKey,EDMDetails
357
                    type,key=getTypeAndKey("TrigOperationalInfo#HLT_EXPRESS_OPI_HLT")
358
                    if 'collection'in EDMDetails[type]:
359
                        colltype = EDMDetails[type]['collection']
360
                        log.info("Adding HLT_EXPRESS_OPI_HLT to ESD for stream "+stream)
361
362
363
364
                        from RecExConfig.ObjKeyStore import objKeyStore
                        objKeyStore.addStreamESD(colltype, key)
                    return True
            else:
365
                log.warning("Could not determine stream of bytestream file, not adding HLT_EXPRESS_OPI_HLT to ESD.")
366
367
368
369
370
371
372
        return False

    def configure(self):

        log = logging.getLogger("HLTTriggerResultGetter.py")
        from RecExConfig.ObjKeyStore import objKeyStore

373
374
        # set EDMDecodingVersion
        EDMDecodingVersion()
375

376
377
378
379
        # Set AODFULL for data unless it was set explicitly already
        if TriggerFlags.AODEDMSet.isDefault() and globalflags.DataSource()=='data':
            TriggerFlags.AODEDMSet = 'AODFULL'
            
380
381
        from AthenaCommon.AlgSequence import AlgSequence
        topSequence = AlgSequence()
382
        log.info("BS unpacking (TF.readBS): %d", TriggerFlags.readBS() )
383
        if TriggerFlags.readBS():
384
385
386
387
            if TriggerFlags.EDMDecodingVersion() <= 2:
                bs = ByteStreamUnpackGetterRun2()  # noqa: F841
            else:
                bs = ByteStreamUnpackGetter()  # noqa: F841
388

389
390
391
392
393
        xAODContainers = {}
#        if not recAlgs.doTrigger():      #only convert when running on old data
        if TriggerFlags.EDMDecodingVersion()==1:
            xaodcnvrt = xAODConversionGetter()
            xAODContainers = xaodcnvrt.xaodlist
394
395

        if recAlgs.doTrigger() or TriggerFlags.doTriggerConfigOnly():
396
397
398
399
            if TriggerFlags.EDMDecodingVersion() <= 2:
                tdt = TrigDecisionGetterRun2()  # noqa: F841
            else:
                tdt = TrigDecisionGetter()  # noqa: F841
400

401
402
403
404
405
406
407
408
409
410
411
        # Temporary hack to add Run-3 navigation to ESD and AOD
        if (rec.doESD() or rec.doAOD()) and TriggerFlags.EDMDecodingVersion() == 3:
            # The hack with wildcards is needed for BS->ESD because we don't know the exact keys
            # of HLT navigation containers before unpacking them from the BS event.
            objKeyStore._store['streamESD'].allowWildCard(True)
            objKeyStore._store['streamAOD'].allowWildCard(True)
            objKeyStore.addManyTypesStreamESD(['xAOD::TrigCompositeContainer#HLTNav*',
                                               'xAOD::TrigCompositeAuxContainer#HLTNav*'])
            objKeyStore.addManyTypesStreamAOD(['xAOD::TrigCompositeContainer#HLTNav*',
                                               'xAOD::TrigCompositeAuxContainer#HLTNav*'])

412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
        # TrigJetRec additions
        if rec.doWriteESD():
            objKeyStore.addStreamESD("JetKeyDescriptor","JetKeyMap")
            objKeyStore.addStreamESD("JetMomentMap","TrigJetRecMomentMap")

        if rec.doWriteAOD():
            objKeyStore.addStreamAOD("JetKeyDescriptor","JetKeyMap")
            objKeyStore.addStreamAOD("JetMomentMap","TrigJetRecMomentMap")
                    
        # ID truth
        if not rec.readESD() and (not rec.readAOD()) and TriggerFlags.doID() \
                and rec.doTruth():
            try:
                from TrigInDetTruthAlgs.TrigInDetTruthAlgsConfig import \
                    TrigIDTruthMaker
                topSequence += TrigIDTruthMaker()
            except Exception:
                log.warning( "Couldn't set up the trigger ID truth maker" )
                pass

        if rec.doESD() or rec.doAOD():
            from TrigEDMConfig.TriggerEDM import getTrigIDTruthList
            objKeyStore.addManyTypesStreamESD(getTrigIDTruthList(TriggerFlags.ESDEDMSet()))
            objKeyStore.addManyTypesStreamAOD(getTrigIDTruthList(TriggerFlags.AODEDMSet()))

437
438
439
440
441
442
        if (rec.doESD() or rec.doAOD()) and TriggerFlags.writeL1TopoValData():
            objKeyStore.addManyTypesStreamESD(['xAOD::TrigCompositeContainer#HLT_xAOD__TrigCompositeContainer_L1TopoValData',
                                               'xAOD::TrigCompositeAuxContainer#HLT_xAOD__TrigCompositeContainer_L1TopoValDataAux.'])
            objKeyStore.addManyTypesStreamAOD(['xAOD::TrigCompositeContainer#HLT_xAOD__TrigCompositeContainer_L1TopoValData',
                                               'xAOD::TrigCompositeAuxContainer#HLT_xAOD__TrigCompositeContainer_L1TopoValDataAux.'])
            log.debug("HLT_xAOD__TrigCompositeContainer_L1TopoValData(Aux.) for L1Topo validation added to the data.")
443

444
        if rec.doAOD() or rec.doWriteAOD():
445
446
447
448
            # schedule the RoiDescriptorStore conversion
            # log.warning( "HLTTriggerResultGetter - setting up RoiWriter" )
            topSequence += RoiWriter()
            # write out the RoiDescriptorStores
449
            from TrigEDMConfig.TriggerEDMRun2 import TriggerRoiList
450
451
            objKeyStore.addManyTypesStreamAOD( TriggerRoiList )

452
453
454
        #Are we adding operational info objects in ESD?
        added=self._AddOPIToESD()
        if added:
455
            log.debug("Operational Info object HLT_EXPRESS_OPI_HLT with extra information about express stream prescaling added to the data.")
456
457
458
459
460
461
        


        # ESD objects definitions
        _TriggerESDList = {}

462
        from TrigEDMConfig.TriggerEDM import getTriggerEDMList 
463
464
465
466
467
468
469
        # we have to store xAOD containers in the root file, NOT AOD,
        # if the xAOD container list is not empty
        if(xAODContainers):
            _TriggerESDList.update( xAODContainers )
        else:
            _TriggerESDList.update( getTriggerEDMList(TriggerFlags.ESDEDMSet(),  TriggerFlags.EDMDecodingVersion()) ) 
        
470
        log.info("ESD content set according to the ESDEDMSet flag: %s and EDM version %d", TriggerFlags.ESDEDMSet() ,TriggerFlags.EDMDecodingVersion())
471
472
473
474

        # AOD objects choice
        _TriggerAODList = {}
        
475
476
        #from TrigEDMConfig.TriggerEDM import getAODList    
        _TriggerAODList.update( getTriggerEDMList(TriggerFlags.AODEDMSet(),  TriggerFlags.EDMDecodingVersion()) ) 
477

478
        log.info("AOD content set according to the AODEDMSet flag: %s and EDM version %d", TriggerFlags.AODEDMSet(),TriggerFlags.EDMDecodingVersion())
479

480
481
        log.debug("ESD EDM list: %s", _TriggerESDList)
        log.debug("AOD EDM list: %s", _TriggerAODList)
482
        
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
        # Highlight what is in AOD list but not in ESD list, as this can cause
        # the "different number of entries in branch" problem, when it is in the
        # AOD list but the empty container per event is not created
        # Just compares keys of dicts, which are the class names, not their string keys in StoreGate
        not_in = [ element for element in  _TriggerAODList if element not in _TriggerESDList ]
        if (len(not_in)>0):
            log.warning("In AOD list but not in ESD list: ")
            log.warning(not_in)
        else:
            log.info("AOD list is subset of ESD list - good.")


        def _addSlimming(stream, thinningSvc, edm):
            from AthenaCommon.AlgSequence import AlgSequence 
            topSequence = AlgSequence()
498
            from TrigNavTools.TrigNavToolsConf import HLT__TrigNavigationSlimming
499
500
            from TrigNavTools.TrigNavToolsConfig import navigationSlimming

501
502
            edmlist = list(y.split('-')[0] for x in edm.values() for y in x) #flatten names
          
503
            # from HLT result drop unrecorded features
504
505
506
            # slimmerHLT = HLT__StreamTrigNavSlimming('HLTNavSlimmer_%s'%stream)
            slimmerHLT = HLT__TrigNavigationSlimming('TrigNavigationSlimmer_%s'%stream)
            tHLT = navigationSlimming({'name':'HLTNav_%s'%stream, 'mode':'cleanup', 
507
508
                                                          'ThinningSvc':thinningSvc, 'result':'HLTResult_HLT',
                                                          'features':edmlist})
509
            tHLT.ActInPlace=True
510
            slimmerHLT.ThinningTool = tHLT
511
            topSequence += slimmerHLT
512
            log.info("Configured slimming of HLT")
513
            print(slimmerHLT.ThinningTool)  # noqa: ATL901
514
515
516
517
            del edmlist


        from AthenaCommon.AppMgr import ServiceMgr as svcMgr
518
        from AthenaServices.Configurables import ThinningSvc
519
        
520
        if TriggerFlags.doNavigationSlimming() and rec.readRDO() and rec.doWriteAOD():
521
522
            if not hasattr(svcMgr, 'ThinningSvc'): # if the default is there it is configured for AODs
                svcMgr += ThinningSvc(name='ThinningSvc', Streams=['StreamAOD'])             
523
            _addSlimming('StreamAOD', svcMgr.ThinningSvc, _TriggerESDList ) #Use ESD item list also for AOD!
524
525
            log.info("configured navigation slimming for AOD output")
            
526
        if TriggerFlags.doNavigationSlimming() and rec.readRDO() and rec.doWriteESD():
527
528
            if not  hasattr(svcMgr, 'ESDThinningSvc'):
                svcMgr += ThinningSvc(name='ESDThinningSvc', Streams=['StreamESD']) # the default is configured for AODs
529
530
531
532
533
            _addSlimming('StreamESD', svcMgr.ESDThinningSvc, _TriggerESDList )                
            log.info("configured navigation slimming for ESD output")              



534
535

        objKeyStore.addManyTypesStreamESD( _TriggerESDList )
536
537
538
539
540
541
542
543
        objKeyStore.addManyTypesStreamAOD( _TriggerAODList )        
            
        return True