Account for target joins when selecting route legs

This commit is contained in:
2026-09-24 17:53:47 -07:00
parent 427078461a
commit 497c1ad8b3
3 changed files with 338 additions and 10 deletions
@@ -0,0 +1,56 @@
"""Compare fixed Project/node/port/endpoint geometry and report routing changes.
Usage: python compare_probe.py OLD_JSONL NEW_JSONL NEW_OUTPUT_JSON
No layout-quality pass is inferred from equal inputs or successful execution.
"""
from pathlib import Path
import hashlib
import json
import sys
old_path, new_path, out = map(Path, sys.argv[1:])
def read(path):
rows = [json.loads(line) for line in path.read_text(encoding='utf-8').splitlines()]
return {row['fixture']: row for row in rows if 'fixture' in row}
old, new = read(old_path), read(new_path)
assert old.keys() == new.keys()
def variants(row):
yield 'before', row['before_project'], row['before']
yield 'baseline', row['after_project'], row['after']
for name in ['reset_only_control', 'experimental_candidate', 'manual_planar_order_witness']:
if row[name] is not None:
yield name, row[name]['project'], row[name]['metrics']
def endpoints(metrics):
return {e['id']: [e['points'][0], e['points'][-1]] for e in metrics['routed_edges']}
keys = ['proper_crossings', 'pairwise_collinear_shared_length',
'nonterminal_pairwise_shared_length', 'unrelated_node_collisions',
'unrelated_edge_node_penetrations', 'label_node_collisions',
'label_label_collisions', 'unrelated_label_stroke_intersections',
'warning_count', 'route_bends', 'route_length', 'drawing_area']
results = []
for name in old:
lhs, rhs = list(variants(old[name])), list(variants(new[name]))
assert len(lhs) == len(rhs)
for (variant, op, om), (other, np, nm) in zip(lhs, rhs):
assert variant == other
fixed = {'project':op == np, 'nodes':om['projected_nodes'] == nm['projected_nodes'],
'ports':om['projected_ports'] == nm['projected_ports'],
'route_endpoints':endpoints(om) == endpoints(nm)}
results.append({'fixture':name, 'variant':variant, 'fixed_geometry':fixed,
'metrics':{key:{'old':om[key], 'new':nm[key]} for key in keys},
'new_point_contacts':nm.get('point_contacts'),
'new_point_contact_details':nm.get('point_contact_details')})
summary = {'old_sha256':hashlib.sha256(old_path.read_bytes()).hexdigest(),
'new_sha256':hashlib.sha256(new_path.read_bytes()).hexdigest(),
'all_projects_nodes_ports_endpoints_exact':all(all(r['fixed_geometry'].values()) for r in results),
'scope':'Fixed-geometry comparison; quality vector retained, no aggregate quality pass.',
'results':results}
with out.open('x',encoding='utf-8') as f:
json.dump(summary,f,indent=2)
f.write('\n')
print(json.dumps({k:v for k,v in summary.items() if k != 'results'}))
for row in results:
if row['variant'] == 'experimental_candidate':
print(json.dumps({'fixture':row['fixture'], 'fixed_geometry':row['fixed_geometry'],
'changed_metrics':{k:v for k,v in row['metrics'].items() if v['old'] != v['new']},
'point_contacts':row['new_point_contacts']}))