def TrigBjetBtagHypoToolFromName(name, conf): """ Configure a b-jet hypo tool from chain name. """ from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName decodedDict = dictFromChainName(conf) decodedDict['chainName'] = name # override return TrigBjetBtagHypoToolFromDict(decodedDict)
def makeChain(name, L1Thresholds, ChainSteps, Streams="physics:Main", Groups=["RATE:TestRateGroup", "BW:TestBW"]): """ In addition to making the chain object fills the flags that are used to generate MnuCOnfig JSON file """ from TriggerMenuMT.HLTMenuConfig.Menu.ChainDefInMenu import ChainProp prop = ChainProp(name=name, l1SeedThresholds=L1Thresholds, groups=Groups) from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName chainDict = dictFromChainName(prop) global chainsCounter chainDict["chainCounter"] = chainsCounter chainsCounter += 1 #set default chain prescale chainDict['prescale'] = 1 from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import Chain chainConfig = Chain(name=name, L1Thresholds=L1Thresholds, ChainSteps=ChainSteps) TriggerConfigHLT.registerChain(chainDict, chainConfig) return chainConfig
def testChainDictMaker(): chain_props = [ ChainProp(name='HLT_j260_320eta490_L1J75_31ETA49', groups=SingleJetGroup), ChainProp(name='HLT_j80_j60_L1J15', l1SeedThresholds=['FSNOSEED'] * 2, groups=MultiJetGroup), ChainProp(name='HLT_j0_HTSEP1000htSEP100etSEP0eta320_L1J15', l1SeedThresholds=['FSNOSEED'], groups=MultiJetGroup), ChainProp( name= 'HLT_j80_0eta240_2j60_320eta490_j0_dijetSEP80j1etSEP0j1eta240SEP80j2etSEP0j2eta240SEP700djmass_L1J20', l1SeedThresholds=['FSNOSEED'] * 3, groups=MultiJetGroup), ChainProp(name='HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20', l1SeedThresholds=['FSNOSEED'], groups=MultiJetGroup), ] result = [] for cp in chain_props: chain_dict = dictFromChainName(cp) result.append((cp.name, chain_dict)) return result
def TrigEgammaFastCaloHypoToolFromName( name, conf ): """ To be phased out """ """ set the name of the HypoTool (name=chain) and figure out the threshold and selection from conf """ from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName decodedDict = dictFromChainName(conf) return TrigEgammaFastCaloHypoToolFromDict( decodedDict )
def testValidConfigs(self): from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import ( dictFromChainName, ) chain_name = 'HLT_j85_L1J20' chain_dict = dictFromChainName(chain_name) tool = trigJetHypoToolFromDict(chain_dict) self.assertIsNotNone(tool) self.assertFalse(tool.visit_debug)
def TrigEgammaFastPhotonHypoToolFromName(name, conf): """ provides configuration of the hypo tool giben the chain name The argument will be replaced by "parsed" chain dict. For now it only serves simplest chain HLT_eXYZ. """ from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName decodedDict = dictFromChainName(conf) return TrigEgammaFastPhotonHypoToolFromDict(decodedDict)
def testValidConfigs(self): from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import ( dictFromChainName, ) chain_names = ('HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20', ) wid = max(len(c) for c in chain_names) for chain_name in chain_names: chain_dict = dictFromChainName(chain_name) tool = trigJetHypoToolFromDict(chain_dict) self.assertIsNotNone(tool) log.info('%s %s', chain_name.rjust(wid), tool)
def generateMenu(flags): """ Using flags generate appropriate Control Flow Graph wiht all HLT algorithms """ # convert to chainDefs from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName counter = 0 signatureToGenerator = {} menuChains = [] allChainDicts = [] menuAcc = ComponentAccumulator() mainSequenceName = 'HLTAllSteps' menuAcc.addSequence(seqAND(mainSequenceName)) for name, cfgFlag in list(iteritems(flags._flagdict)): if 'Trigger.menu.' not in name: continue value = flags._get(name) if len(value) == 0: continue signatureName = name.split('.')[-1] signatures = [] # fill the map[signature, generating function] if signatureName == 'combined': for chain in cfgFlag.get(): signatures += dictFromChainName(chain)['signatures'] else: signatures = [signatureName] for sig in signatures: fillGeneratorsMap(signatureToGenerator, sig.lower()) # call generating function and pass to CF builder for chain in cfgFlag.get(): # TODO topo threshold mainChainDict = dictFromChainName(chain) counter += 1 mainChainDict['chainCounter'] = counter #set default chain prescale mainChainDict['prescale'] = 1 allChainDicts.append(mainChainDict) chainDicts = splitInterSignatureChainDict(mainChainDict) listOfChainConfigs = [] for chainDict in chainDicts: signature = chainDict['signature'].lower() if signature not in signatureToGenerator: log.warning( 'Generator for {} is missing. Chain dict will not be built' .format(signature)) continue chainConfig = signatureToGenerator[signature](flags, chainDict) listOfChainConfigs.append(chainConfig) if len(listOfChainConfigs) > 1: theChainConfig = mergeChainDefs(listOfChainConfigs, mainChainDict) else: theChainConfig = listOfChainConfigs[0] TriggerConfigHLT.registerChain(mainChainDict, theChainConfig) menuChains.append(theChainConfig) log.info('Obtained Menu Chain objects') # pass all menuChain to CF builder useReworked = True if useReworked: menuAcc.wasMerged() menuAcc = generateDecisionTree(menuChains) else: menuAcc.wasMerged() menuAcc = ComponentAccumulator() mainSequenceName = 'HLTAllSteps' menuAcc.addSequence(seqAND(mainSequenceName)) chainsAcc = generateDecisionTreeOld( menuAcc.getSequence(mainSequenceName), menuChains, allChainDicts) menuAcc.merge(chainsAcc) menuAcc.printConfig() log.info('CF is built') # # generate JOSON representation of the config from TriggerMenuMT.HLTMenuConfig.Menu.HLTMenuJSON import generateJSON_newJO generateJSON_newJO(allChainDicts, menuChains, menuAcc.getSequence("HLTAllSteps")) from TriggerMenuMT.HLTMenuConfig.Menu.HLTPrescaleJSON import generateJSON_newJO as generatePrescaleJSON_newJO generatePrescaleJSON_newJO(allChainDicts, menuChains) return menuAcc
def generateAllChainConfigs(self): """ == Obtains chain configs for all chains in menu """ # get all chain names from menu log.debug("getting chains from Menu") chainsInMenu = self.getChainsFromMenu() # decoding of the chain name chainCounter = 0 all_chains = [] combinations_in_menu = [] signatures_to_align = set() length_of_configs = {} for chain in chainsInMenu: log.debug("Now processing chain: %s ", chain) chainDict = dictFromChainName(chain) chainCounter += 1 chainDict['chainCounter'] = chainCounter #set default chain prescale chainDict['prescale'] = 1 log.debug("Next: getting chain configuration for chain %s ", chain.name) chainConfig, lengthOfChainConfigs = self.__generateChainConfig( chainDict) all_chains += [(chainDict, chainConfig, lengthOfChainConfigs)] #update the signature length dictionary if we have a longer number of steps #or the signature isn't registered in the dictionary yet for config_length, config_sig in lengthOfChainConfigs: if config_sig in length_of_configs: if config_length > length_of_configs[config_sig]: length_of_configs[config_sig] = config_length else: length_of_configs[config_sig] = config_length # find the chains that contain more than one signature - what combinations do we need to deal with? # using sets here so we don't end up with duplicates - though in the future this may have to be revisited # if we split signatures into multiple types of algorithm if len(set(chainDict['signatures'])) > 1: combinations_in_menu += [list(set(chainDict['signatures']))] for sig in list(set(chainDict['signatures'])): signatures_to_align.update([sig]) #will likely always be true, but the grouping could be redefined groupPeskySignatures = True if groupPeskySignatures: # do some replacing of Electron --> Egamma, Photon --> Egamma # Jet/MET/b-jet --> JetMET # B-physics chains are hard-coded as muon chains, since they run muons # --> any B-->ee chains would need to be set as egamma! # these modified signatures are only used for the aligning! We don't overwrite # any of the signatures the chains are in. combinations_in_menu, signatures_to_align, length_of_configs = groupSignatures( combinations_in_menu, signatures_to_align, length_of_configs) #dict of signature: set it belongs to #e.g. {'Electron': ['Electron','Muon','Photon']} signature_sets_to_align = analyseCombinations( combinations_in_menu, signatures_to_align, doGroupSignatures=groupPeskySignatures) log.debug('Aligning the following signatures with sets: %s', signature_sets_to_align) for chainDict, chainConfig, lengthOfChainConfigs in all_chains: # start by ordering electron, photon, muon by having e+mu, g+mu, e+g chains # desired ordering: electron, photon, muon, tau, jet, met, b-jet # lengthOfChainConfigs is something like this: [(4, 'Photon'), (5, 'Muon')] # needs to match up with the maximum number of steps in a signature in the menu (length_of_configs) # start with electron! Only need to add post-steps for combined electron chains if the max length in a combined chain # is greater than the number of electron steps combined chain. Assume that the max length of an electron chain occurs # in a combined chain. signatures = chainDict['signatures'] if groupPeskySignatures: signatures, lengthOfChainConfigs = setChainSignatures( signatures, lengthOfChainConfigs) #parallel-merged single-signature chains or single signature chains. Anything that needs no splitting! if len(set(signatures)) == 1: if signatures[0] not in signature_sets_to_align or len( signature_sets_to_align[signatures[0]]) == 1: # no need to align lonely signatures # the latter condition should never happen, because we only put in signatures that are # in combined chains, and thus will need *some* aligning. but good to check in any case. log.debug( "Finished with retrieving chain configuration for chain %s", chain.name) chainConfig.numberAllSteps() TriggerConfigHLT.registerChain(chainDict, chainConfig) continue elif signatures[0] == signature_sets_to_align[ signatures[0]][0]: # if it's the first chain in the set to be aligned, again - nothing to do here. log.debug( "Finished with retrieving chain configuration for chain %s", chain.name) chainConfig.numberAllSteps() TriggerConfigHLT.registerChain(chainDict, chainConfig) continue else: # now we know that empty steps are necessary before this chain. we can loop through and add accordingly # but we want to do this in reverse the_align_sigs = signature_sets_to_align[ signatures[0]][:signature_sets_to_align[signatures[0]]. index(signatures[0])] the_align_sigs.reverse() for align_sig in the_align_sigs: chainConfig.insertEmptySteps( chainDict, 'Empty' + align_sig + 'Align', length_of_configs[align_sig], 0) log.debug( "Finished with retrieving chain configuration for chain %s", chain.name) chainConfig.numberAllSteps() TriggerConfigHLT.registerChain(chainDict, chainConfig) elif len(signatures) == 2: #check for a few bad conditions first: if (signatures[0] not in signature_sets_to_align or signatures[1] not in signature_sets_to_align): log.error( " one of the signatures in %s is not available in the sets to align dictionary!", signatures) elif signature_sets_to_align[signatures[ 0]] != signature_sets_to_align[signatures[1]]: log.error( " the two signatures %s point to different sets in the sets to align dictionary. Set1: %s, set2: %s!", signatures, signature_sets_to_align[signatures[0]], signature_sets_to_align[signatures[1]]) if len(signature_sets_to_align[signatures[0]]) == 2: # if the pair is on its own, then we just make sure the first signature's number # of steps is equal to the max in that signature (so the next signature starts at the right step) # not a dictionary because we could have a chain mu_jet_munoL1? Not sure. But don't want to # overwrite duplicates yet. # probably, at some point, will need to divide this beyond signature but instead as unique sequence within a signature. # munoL1 is already one case... length_firstsig = 0 max_length_firstsig = length_of_configs[ signature_sets_to_align[signatures[0]][0]] for config_length, config_sig in lengthOfChainConfigs: if config_sig == signature_sets_to_align[ signatures[0]][0]: length_firstsig = config_length if length_firstsig < max_length_firstsig: #too short! gotta add padding steps between two signatures... needed_steps = max_length_firstsig - length_firstsig chainConfig.insertEmptySteps( chainDict, 'Empty' + signature_sets_to_align[signatures[0]][0] + 'Align', needed_steps, length_firstsig) elif length_firstsig > max_length_firstsig: log.error( "%s first signature length %d is greater than the max calculated, %d", chainDict.name, length_firstsig, max_length_firstsig) log.debug( "Finished with retrieving chain configuration for chain %s", chain.name) chainConfig.numberAllSteps() TriggerConfigHLT.registerChain(chainDict, chainConfig) #this should probably work for signatures > 2, but might be a few gotchas (and errors need updating) if len(signature_sets_to_align[signatures[0]]) > 2: if (signatures[0] not in signature_sets_to_align or signatures[1] not in signature_sets_to_align): log.error( " one of the signatures in %s is not available in the sets to align dictionary!", signatures) elif signature_sets_to_align[signatures[ 0]] != signature_sets_to_align[signatures[1]]: log.error( " the two signatures %s point to different sets in the sets to align dictionary. Set1: %s, set2: %s!", signatures, signature_sets_to_align[signatures[0]], signature_sets_to_align[signatures[1]]) # we need to know which signatures are in the chain in which order. Assume this is always stored correctly. # (this should be true) # never need to align the last chain - it can end a different length, no problem. # ignore any signatures after the end of those in this chain the_align_sigs = signature_sets_to_align[ signatures[1]][:signature_sets_to_align[signatures[1]]. index(signatures[1])] the_align_sigs.reverse() for align_sig in the_align_sigs: max_length_sig = length_of_configs[align_sig] if align_sig in signatures: length_sig = 0 for config_length, config_sig in lengthOfChainConfigs: if config_sig == align_sig: length_sig = config_length if length_sig < max_length_sig: #too short! gotta add padding steps between two signatures... needed_steps = max_length_sig - length_sig chainConfig.insertEmptySteps( chainDict, 'Empty' + align_sig + 'Align', needed_steps, length_sig) else: # this sig isn't in the chain, but we still will need empty steps for it # always add them to the start, because we're running in reverse order chainConfig.insertEmptySteps( chainDict, 'Empty' + align_sig + 'Align', length_of_configs[align_sig], 0) log.debug( "Finished with retrieving chain configuration for chain %s", chain.name) chainConfig.numberAllSteps() TriggerConfigHLT.registerChain(chainDict, chainConfig) else: log.error( "Menu can't deal with combined chains with more than two signatures at the moment. oops..." ) if not TriggerConfigHLT.isChainRegistered(chainDict['chainName']): log.error("Chain %s has not been registered in the menu!", chainDict['chainName']) return TriggerConfigHLT.configsList()
def do_it(): print('\n------------------\n') chain_dict = dictFromChainName(chain_name) pp.pprint(chain_dict)
def TrigMETCellHypoToolFromName(name, conf): from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName decodedDict = dictFromChainName(conf) decodedDict['chainName'] = name return TrigMETCellHypoToolFromDict( decodedDict )
if __name__ == '__main__': # normaly this tools are private and have no clash in naming, for the test we create them and never assign so they are like public, # in Run3 config this is checked in a different way so having Run 3 JO behaviour solves test issue from AthenaCommon.Configurable import Configurable Configurable.configurableRun3Behavior = 1 configToTest = [ 'HLT_mu6fast_L1MU6', 'HLT_mu6Comb_L1MU6', 'HLT_mu6_L1MU6', 'HLT_mu20_ivar_L1MU20', 'HLT_2mu6Comb_L12MU6', 'HLT_2mu6_L12MU6' ] from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName for c in configToTest: log.info("testing config %s", c) chainDict = dictFromChainName(c) toolMufast = TrigMufastHypoToolFromDict(chainDict) assert toolMufast toolmuComb = TrigmuCombHypoToolFromDict(chainDict) assert toolmuComb toolMuiso = TrigMuisoHypoToolFromDict(chainDict) assert toolMuiso toolEFMSonly = TrigMuonEFMSonlyHypoToolFromDict(chainDict) assert toolEFMSonly toolEFCombiner = TrigMuonEFCombinerHypoToolFromDict(chainDict) assert toolEFCombiner log.info("All OK")