HLTTriggerResultGetter.py 24.4 KB
Newer Older
1
# Copyright (C) 2002-2020 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

        # Check HLT ROD version in first event of first input file
        from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
        inputFileName = athenaCommonFlags.FilesInput()[0]
26
27
28
29
        if not inputFileName and athenaCommonFlags.isOnline():
            log.info("Online reconstruction mode, no input file available. Leaving default TriggerFlags.EDMDecodingVersion=%d", TriggerFlags.EDMDecodingVersion())
            return

30
31
32
        import eformat
        from libpyeformat_helper import SubDetector
        bs = eformat.istream(inputFileName)
33

34
35
        rodVersionM = -1
        rodVersionL = -1
36
        # Find the first HLT ROBFragment in the first event
37
        for robf in bs[0]:
38
39
40
41
42
43
44
            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:
45
            log.warning("Cannot determine HLT ROD version from input file, falling back to runNumber-based decision")
46
        elif rodVersionM >= 1:
47
48
49
50
51
            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
52
53
54
        from RecExConfig.AutoConfiguration  import GetRunNumber
        runNumber = GetRunNumber()

55
56
57
58
59
60
61
62
        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
63
            TriggerFlags.EDMDecodingVersion = 1
64
            TriggerFlags.doMergedHLTResult = False
65
66
67
68
69
70
71
72
73
74
75
76
77
            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)

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

84
        TriggerFlags.doMergedHLTResult = True
85
        if cfgKeyStore.isInInputFile( "HLT::HLTResult", "HLTResult_EF" ):
86
            TriggerFlags.EDMDecodingVersion = 1
87
            TriggerFlags.doMergedHLTResult = False
88
            log.info("Decoding version set to 1, because HLTResult_EF found in POOL file")
89
        elif cfgKeyStore.isInInputFile( "xAOD::TrigNavigation", "TrigNavigation" ):
90
            TriggerFlags.EDMDecodingVersion = 2
91
            log.info("Decoding version set to 2, because TrigNavigation found in POOL file")
92
        elif cfgKeyStore.isInInputFile( "xAOD::TrigCompositeContainer", "HLTNav_Summary"):
93
            TriggerFlags.EDMDecodingVersion = 3
94
            log.info("Decoding version set to 3, because HLTNav_Summary found in POOL file")
95
96
97
98
99
100
101
102
        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")
103
        else:
104
            log.warning("Cannot recognise HLT EDM format, leaving default TriggerFlags.EDMDecodingVersion=%d", TriggerFlags.EDMDecodingVersion())
105
106


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

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

119
120
        from TrigEDMConfig.TriggerEDM import getPreregistrationList
        from TrigEDMConfig.TriggerEDM import getEFRun1BSList,getEFRun2EquivalentList,getL2Run1BSList,getL2Run2EquivalentList
121
122
123
124
125
126
127
        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()))
128
129

        #we attempt to convert the entire old navigation (L2+EF)
130
131
132
133
        #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()
134
135
136
137

        xaodconverter.HLTResultKey="HLTResult_EF"
        topSequence += xaodconverter

138
139
140
141
142
143
        # 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 ))

144
145
146
147
148
149
        return True
    
        

class ByteStreamUnpackGetter(Configured):
    def configure(self):
150
        log = logging.getLogger("ByteStreamUnpackGetter")
151

152
153
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
        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")
180
181
182
183
        from AthenaCommon.AlgSequence import AlgSequence 
        topSequence = AlgSequence()
        
        #if TriggerFlags.readBS():
184
        log.info( "TriggerFlags.dataTakingConditions: %s", TriggerFlags.dataTakingConditions() )
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
        # 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()
204
205
206

        # Add fictional output to ensure data dependency in AthenaMT
        extr.ExtraOutputs += [("TrigBSExtractionOutput", "StoreGateSvc+TrigBSExtractionOutput")]
207
208
209
210
        
        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
            from PyUtils.MetaReaderPeeker import metadata
228
229
230
231
232
233
234
            if 'stream' in 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 ]
235
236

        else:
237
238
239
240
241
            #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=""
242
            extr.DSResultKeys=[]
243
244
245
246
247
248
249
250
251

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

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

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

270
271
272
273
        return True


class TrigDecisionGetter(Configured):
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    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):
294
295
296
    #class to setup the writing or just making of TrigDecisionObject
    def configure(self):
        
297
        log = logging.getLogger("TrigDecisionGetterRun2")
298
299
300
301
302
303
304
305
306
307
308

        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 \
309
               ( not ( rec.readAOD() or rec.readESD() or rec.doWriteBS()) ):
310
            log.info("Will write TrigDecision object to storegate")
311
            
312
            from TrigDecisionMaker.TrigDecisionMakerConfig import WriteTrigDecision
313
            trigDecWriter = WriteTrigDecision()  # noqa: F841
314

315
#           WritexAODTrigDecision() is called within WriteTrigDecision()
316

317
318
319
320
321
            # 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
322
323
324
                topSequence.TrigNavigationCnvAlg.doL2 = False
                topSequence.TrigNavigationCnvAlg.doEF = False
                topSequence.TrigNavigationCnvAlg.doHLT = False
325
326
327
            elif TriggerFlags.dataTakingConditions()=='HltOnly':
                from AthenaCommon.AlgSequence import AlgSequence
                topSequence.TrigDecMaker.doL1=False
328
            # Decide based on the doMergedHLTResult to assume a merged, or a
329
330
331
            # split HLT:
            if not TriggerFlags.doMergedHLTResult():
                topSequence.TrigDecMaker.doHLT = False
332
333
                topSequence.TrigNavigationCnvAlg.doL2 = False
                topSequence.TrigNavigationCnvAlg.doHLT = False
334
335
336
            else:
                topSequence.TrigDecMaker.doL2 = False
                topSequence.TrigDecMaker.doEF = False
337
338
                topSequence.TrigNavigationCnvAlg.doL2 = False
                topSequence.TrigNavigationCnvAlg.doEF = False
339
340
341
342
                pass
                
        else:
            log.info("Will not write TrigDecision object to storegate")
343
    
344
345
346
347
348
349
350
351
352
353
354
355
        return True
    
    
class HLTTriggerResultGetter(Configured):

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

    def _AddOPIToESD(self):

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

    def configure(self):

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

378
379
        # set EDMDecodingVersion
        EDMDecodingVersion()
380

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

394
395
396
397
398
        xAODContainers = {}
#        if not recAlgs.doTrigger():      #only convert when running on old data
        if TriggerFlags.EDMDecodingVersion()==1:
            xaodcnvrt = xAODConversionGetter()
            xAODContainers = xaodcnvrt.xaodlist
399
400

        if recAlgs.doTrigger() or TriggerFlags.doTriggerConfigOnly():
401
402
403
404
            if TriggerFlags.EDMDecodingVersion() <= 2:
                tdt = TrigDecisionGetterRun2()  # noqa: F841
            else:
                tdt = TrigDecisionGetter()  # noqa: F841
405

406
407
408
409
410
411
412
413
414
415
416
        # 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*'])

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
        # 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()))

442
443
444
445
446
447
        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.")
448

449
        if rec.doAOD() or rec.doWriteAOD():
450
451
            # schedule the RoiDescriptorStore conversion
            # log.warning( "HLTTriggerResultGetter - setting up RoiWriter" )
452
453
454
455
            roiWriter = RoiWriter()
            # Add fictional input to ensure data dependency in AthenaMT
            roiWriter.ExtraInputs += [("TrigBSExtractionOutput", "StoreGateSvc+TrigBSExtractionOutput")]
            topSequence += roiWriter
456
            # write out the RoiDescriptorStores
457
            from TrigEDMConfig.TriggerEDMRun2 import TriggerRoiList
458
459
            objKeyStore.addManyTypesStreamAOD( TriggerRoiList )

460
461
462
        #Are we adding operational info objects in ESD?
        added=self._AddOPIToESD()
        if added:
463
            log.debug("Operational Info object HLT_EXPRESS_OPI_HLT with extra information about express stream prescaling added to the data.")
464
465
466
467
468
469
        


        # ESD objects definitions
        _TriggerESDList = {}

470
        from TrigEDMConfig.TriggerEDM import getTriggerEDMList 
471
472
473
474
475
476
477
        # 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()) ) 
        
478
        log.info("ESD content set according to the ESDEDMSet flag: %s and EDM version %d", TriggerFlags.ESDEDMSet() ,TriggerFlags.EDMDecodingVersion())
479
480
481
482

        # AOD objects choice
        _TriggerAODList = {}
        
483
484
        #from TrigEDMConfig.TriggerEDM import getAODList    
        _TriggerAODList.update( getTriggerEDMList(TriggerFlags.AODEDMSet(),  TriggerFlags.EDMDecodingVersion()) ) 
485

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

488
489
        log.debug("ESD EDM list: %s", _TriggerESDList)
        log.debug("AOD EDM list: %s", _TriggerAODList)
490
        
491
492
493
494
495
496
497
498
499
500
501
502
        # 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.")


503
504
        def _addSlimming(stream, edm):
            from TrigNavTools.TrigNavToolsConfig import navigationThinningSvc
505

506
507
            edmlist = list(y.split('-')[0] for x in edm.values() for y in x) #flatten names
          
508
509
510
511
512
513
514
515
516
            svc = navigationThinningSvc ({'name':'HLTNav_%s'%stream, 'mode':'cleanup', 
                                          'result':'HLTResult_HLT',
                                          'features':edmlist})

            from OutputStreamAthenaPool.CreateOutputStreams import registerTrigNavThinningSvc
            registerTrigNavThinningSvc (stream, svc)

            log.info("Configured slimming of HLT for %s", stream)
            print(svc)  # noqa: ATL901
517
518
519
            del edmlist


520
        if TriggerFlags.doNavigationSlimming() and rec.readRDO() and rec.doWriteAOD():
521
            _addSlimming('StreamAOD', _TriggerESDList ) #Use ESD item list also for AOD!
522
523
            log.info("configured navigation slimming for AOD output")
            
524
        if TriggerFlags.doNavigationSlimming() and rec.readRDO() and rec.doWriteESD():
525
526
            _addSlimming('StreamESD', _TriggerESDList )                
            log.info("configured navigation slimming for ESD output")
527
528
529



530
531

        objKeyStore.addManyTypesStreamESD( _TriggerESDList )
532
533
534
535
536
537
538
539
        objKeyStore.addManyTypesStreamAOD( _TriggerAODList )        
            
        return True