| #!/usr/bin/env python3 |
| |
| import csv |
| import os |
| import pprint |
| import re |
| import sys |
| |
| from collections import defaultdict |
| |
| import common |
| import flatten |
| |
| |
| RE_MODEL_START = re.compile(r'^model\s+(?P<model>[^ ]+)\s+bsim(?P<bsim>[0-9vV]+)\s+{(\n|$)') |
| RE_MODEL_END = re.compile(r'^[\s\n]*ends(?P<end>.*)(\n|$)') |
| RE_ROW = re.compile(r'^\s*(?P<row>[0-9]+):\s*type=(?P<type>.*?)(\n|$)') |
| RE_PARAM = re.compile(r'^[+] (?P<param>[^ ]+)\s+=\s+(?P<value>.+?)(\n|$)') |
| RE_GROUP = re.compile(r'[*\s]*?(?P<group>[^*\n]+?)[*\s]*(\n|$)') |
| |
| |
| GROUPS = defaultdict(set) |
| FIELDS = set() |
| |
| |
| def write_csv(outname, models): |
| w = csv.writer(open(outname,'w')) |
| |
| row = ['model', 'bin', 'num_bins'] |
| row.extend(sorted(FIELDS)) |
| w.writerow(row) |
| |
| for m in models: |
| for i, r in enumerate(m['rows']): |
| row = [] |
| row.append(m['model']) |
| row.append(i) |
| row.append(len(m['rows'])) |
| for f in sorted(FIELDS): |
| row.append(r.get(f, 'N\A')) |
| w.writerow(row) |
| |
| |
| |
| def pm3_to_rows(infile): |
| models = [None] |
| |
| rows = [] |
| row_params = {} |
| group = None |
| for comment, bit in flatten.read_bits(infile, 'spice'): |
| if comment: |
| m = RE_GROUP.match(bit) |
| if m: |
| group = m.group('group').title() |
| print('g', group) |
| else: |
| print('#', repr(bit)) |
| else: |
| for l in bit.splitlines(keepends=True): |
| if models[-1] is None: |
| m = RE_MODEL_START.match(l) |
| if not m: |
| print("Skipping", repr(l)) |
| continue |
| models.pop(-1) |
| models.append({ |
| 'model': m.group('model'), |
| 'bsim': m.group('bsim'), |
| 'rows': [], |
| }) |
| continue |
| |
| m = RE_MODEL_END.match(l) |
| if m: |
| if row_params: |
| models[-1]['rows'].append(row_params) |
| print("Ends", m.group('end')) |
| models.append(None) |
| break |
| |
| m = RE_ROW.match(l) |
| if m: |
| if row_params: |
| models[-1]['rows'].append(row_params) |
| row = m.group('row') |
| t = m.group('type') |
| row_params = { |
| 'row': 0, |
| 'type': t, |
| } |
| continue |
| |
| m = RE_PARAM.match(l) |
| if m: |
| params = {} |
| |
| name = [m.group('param')] |
| value = [] |
| bits = m.group('value').split() |
| print(name, bits) |
| while bits: |
| value.append(bits.pop(0)) |
| if bits and bits[0] in ('+', '*'): |
| value.append(bits.pop(0)) |
| value.append(bits.pop(0)) |
| |
| if value[-1][-1] == '(': |
| value.append(bits.pop(0)) |
| continue |
| |
| params["".join(name)] = " ".join(value) |
| if bits: |
| name = [bits.pop(0)] |
| value = [] |
| assert bits.pop(0) == '=', repr(l) |
| print(params) |
| for k in params: |
| FIELDS.add(k) |
| GROUPS[group].add(k) |
| assert k not in row_params |
| try: |
| params[k] = float(params[k]) |
| except ValueError: |
| pass |
| row_params[k] = params[k] |
| |
| continue |
| |
| if l.strip(): |
| print('?', repr(l)) |
| |
| |
| assert models[-1] == None |
| models.pop(-1) |
| return models |
| |
| |
| models = [] |
| for pn in common.files(['.pm3']): |
| if 'rf' in pn: |
| continue |
| print() |
| print(pn) |
| print('='*75) |
| newmodels = pm3_to_rows(pn) |
| base, ext = os.path.splitext(pn) |
| print('-'*75) |
| outfile = base+'.csv' |
| print(outfile) |
| write_csv(outfile, newmodels) |
| print('='*75) |
| models.extend(newmodels) |
| |
| |
| write_csv('out.csv', models) |
| |
| sys.exit(1) |
| |
| # Header 1 |
| #row = ['',] |
| #for h1 in sorted(groups): |
| # row.append(h1) |
| # row.extend(['']*(len(groups[h1])-1)) |
| #csv_rows.append(row) |
| |
| # Header 2 |
| row = ['type',] |
| #h2toh1 = {} |
| for h1 in sorted(groups): |
| for h2 in sorted(groups[h1]): |
| row.append(h2) |
| h2toh1[h2] = h1 |
| csv_rows.append(row) |
| |
| for row in rows: |
| csv_rows.append([row['type'],]) |
| for h2 in csv_rows[1][1:]: |
| h1 = h2toh1[h2] |
| csv_rows[-1].append(row[h1].get(h2,'N/A')) |
| |
| w.writerows(csv_rows) |