ScanLHA.slha module
Parsing and writing of (S)LHA files.
""" Parsing and writing of (S)LHA files. """ from collections import defaultdict import logging import pylha def genSLHA(blocks): """ Generate string in SLHA format from `'blocks'` entry of a `ScanLHA.config.Config` instance. """ out = '' for block in blocks: out += 'BLOCK {}\n'.format(block['block']) for data in block['lines']: data = defaultdict(str,data) if any(k in ['scan','values','random','dependent'] for k in data): try: para = data['parameter'] except KeyError: logging.info('Using {}.{} as template parameter.'.format(block, data['id'])) para = '{}.{}'.format(block,data['id']) data['value'] = '{%' + para + '%}' out += '{id} {value} #{parameter} {comment}\n'.format_map(data) return out def list2dict(l): """ recursively convert [1,2,3,4] to {'1':{'2':{'3':4}} """ if len(l) == 1: return l[0] return { str(l[0]) : list2dict(l[1:]) } def mergedicts(l, d): """ merge list of nested dicts """ if type(l) == list: d.update(l[0]) for dct in l[1:]: mergedicts(dct, d) return d elif type(l) == dict: for k,v in l.items(): if k in d and isinstance(d[k], dict): mergedicts(l[k], d[k]) else: d[k] = l[k] def parseSLHA(slhafile, blocks=[]): """ Turn the content of an SLHA file into a dictionary `slhafile` : path tp file `blocks` : list of BLOCKs (strings) to read, if empty all blocks are read Uses [pylha](https://github.com/DavidMStraub/pylha pylha) but gives a more meaningful output the result is stored in a nested dictionary. """ try: with open(slhafile,'r') as f: slha = pylha.load(f) except FileNotFoundError: logging.error('File %s not found.' % slhafile) return {} except: logging.error('Could not parse %s !' % slhafile) return {} try: slha_blocks = slha['BLOCK'] except KeyError: slha_blocks = {} if blocks: slha_blocks = { b : v for b,v in slha_blocks.items() if b in blocks } try: # TODO convert into valid slha instead of dropping slha_blocks.pop('HiggsBoundsInputHiggsCouplingsBosons') slha_blocks.pop('HiggsBoundsInputHiggsCouplingsFermions') except KeyError: pass for b,v in slha_blocks.items(): try: v['values'] = mergedicts([list2dict(l) for l in v['values']],{}) v['info'] = ''.join(str(i) for i in v['info']) except: pass if 'DECAY' not in slha: return slha_blocks decayblock = 'DECAYS' if 'DECAY' in slha_blocks else 'DECAY' slha_blocks[decayblock] = slha['DECAY'] for d,v in slha_blocks[decayblock].items(): try: v['values'] = mergedicts([list2dict(list(reversed(l))) for l in v['values']],{}) v['info'] = ''.join(str(i) for i in v['info']) if len(v['info']) > 1 else v['info'][0] except: pass return slha_blocks
Functions
def genSLHA(
blocks)
Generate string in SLHA format from 'blocks'
entry of a ScanLHA.config.Config
instance.
def genSLHA(blocks): """ Generate string in SLHA format from `'blocks'` entry of a `ScanLHA.config.Config` instance. """ out = '' for block in blocks: out += 'BLOCK {}\n'.format(block['block']) for data in block['lines']: data = defaultdict(str,data) if any(k in ['scan','values','random','dependent'] for k in data): try: para = data['parameter'] except KeyError: logging.info('Using {}.{} as template parameter.'.format(block, data['id'])) para = '{}.{}'.format(block,data['id']) data['value'] = '{%' + para + '%}' out += '{id} {value} #{parameter} {comment}\n'.format_map(data) return out
def list2dict(
l)
recursively convert [1,2,3,4] to {'1':{'2':{'3':4}}
def list2dict(l): """ recursively convert [1,2,3,4] to {'1':{'2':{'3':4}} """ if len(l) == 1: return l[0] return { str(l[0]) : list2dict(l[1:]) }
def mergedicts(
l, d)
merge list of nested dicts
def mergedicts(l, d): """ merge list of nested dicts """ if type(l) == list: d.update(l[0]) for dct in l[1:]: mergedicts(dct, d) return d elif type(l) == dict: for k,v in l.items(): if k in d and isinstance(d[k], dict): mergedicts(l[k], d[k]) else: d[k] = l[k]
def parseSLHA(
slhafile, blocks=[])
Turn the content of an SLHA file into a dictionary
slhafile
: path tp file
blocks
: list of BLOCKs (strings) to read, if empty all blocks are read
Uses pylha but gives a more meaningful output the result is stored in a nested dictionary.
def parseSLHA(slhafile, blocks=[]): """ Turn the content of an SLHA file into a dictionary `slhafile` : path tp file `blocks` : list of BLOCKs (strings) to read, if empty all blocks are read Uses [pylha](https://github.com/DavidMStraub/pylha pylha) but gives a more meaningful output the result is stored in a nested dictionary. """ try: with open(slhafile,'r') as f: slha = pylha.load(f) except FileNotFoundError: logging.error('File %s not found.' % slhafile) return {} except: logging.error('Could not parse %s !' % slhafile) return {} try: slha_blocks = slha['BLOCK'] except KeyError: slha_blocks = {} if blocks: slha_blocks = { b : v for b,v in slha_blocks.items() if b in blocks } try: # TODO convert into valid slha instead of dropping slha_blocks.pop('HiggsBoundsInputHiggsCouplingsBosons') slha_blocks.pop('HiggsBoundsInputHiggsCouplingsFermions') except KeyError: pass for b,v in slha_blocks.items(): try: v['values'] = mergedicts([list2dict(l) for l in v['values']],{}) v['info'] = ''.join(str(i) for i in v['info']) except: pass if 'DECAY' not in slha: return slha_blocks decayblock = 'DECAYS' if 'DECAY' in slha_blocks else 'DECAY' slha_blocks[decayblock] = slha['DECAY'] for d,v in slha_blocks[decayblock].items(): try: v['values'] = mergedicts([list2dict(list(reversed(l))) for l in v['values']],{}) v['info'] = ''.join(str(i) for i in v['info']) if len(v['info']) > 1 else v['info'][0] except: pass return slha_blocks