Source code for pyathena.io.read_athinput


import re
import collections

[docs]def read_athinput(filename, as_namedtuple=False, verbose=False): """ Function to read athinput and configure block from simulation log Parameters ---------- filename : string Name of the file to open, including extension verbose : bool Print verbose message Returns ------- par : dict or namedtuple Each item is a dictionary or namedtuple containing individual input block. """ if verbose: print('[read_par]: Reading params from {0}'.format(filename)) lines = [] with open(filename, 'r') as f: lines = f.readlines() DUMP = False for i, line in enumerate(lines): if 'PAR_DUMP' in line: DUMP = True break if DUMP: # from simulation log flag = True for i, line in enumerate(lines): if 'PAR_DUMP' in line: if flag: istart = i flag = False else: iend = i else: # from restart for i, line in enumerate(lines): if '<comment>' in line: istart = i if 'SMR enabled?' in line or '<par_end>' in line: iend = i lines = lines[istart:iend] # Parse lines reblock = re.compile(r"<\w+>\s*") ## reparam=re.compile(r"[-\[\]\w]+\s*=") # To deal with space (such as star particles in <configure>) reparam = re.compile(r"[-\[\]\w]+[\s*[-\[\]\w]*]*\s*=") # Find blocks first block = [] for l in lines: b = reblock.match(l) if b is not None: block.append(b.group().strip()[1:-1]) # remove comment block block.remove('comment') o = {} for b in block: o.setdefault(b, {}) # Add keys and values to each block for l in lines: b = reblock.match(l) p = reparam.match(l) if b is not None: bstr = b.group().strip()[1:-1] if bstr in o: bname = bstr # bname is valid block else: bname = None elif p is not None and bname is not None: lsplit = l.split() i1_found=False for i, lsplit_ in enumerate(lsplit): if lsplit_ == '=': i0 = i if lsplit_ == '#': i1 = i i1_found=True break pname = '_'.join(lsplit[:i0]) if i1_found: value = ' '.join(lsplit[i0+1:i1]) else: value = lsplit[i0+1] # Evaluate if value is floating point number (or real number) or integer or string # Too complicated...there must be a better way... if re.match(r'^[+-]?\d*\.\d*[eE][+-]?\d+$',value) or \ re.match(r'^[+-]?\d+[eE][+-]?\d+$',value) or \ re.match(r'^[+-]?\d+\.\d*$',value): o[bname][pname] = float(value) elif re.match(r'^-?[0-9]+$',value): o[bname][pname] = int(value) # o[bname][l.split()[0]]=float(value) else: o[bname][pname] = value if as_namedtuple: # Convert to namedtuple par = collections.namedtuple('par', o.keys())(**o) return par else: return o