blob: 9ddc1e4c427fc896f59147e82a57abf479bb7b6a [file] [log] [blame] [edit]
#!/usr/bin/env python3
""" Tool for sanity checking rrgraph CHAN PTC's.
"""
import lxml.etree as ET
import argparse
def check_ptc(xml):
""" Checks ptc values used on CHANX and CHANY rr graph nodes are valid.
CHAN ptc numbers are an index per x/y coordinate and channel type (CHANX or
CHANY). ptc's at a particular coordinate/type must start at 0, and fill
to the max value.
"""
chan_ptcs = {}
nodes = {}
for node in xml.find('rr_nodes').iter('node'):
assert node.attrib['id'] not in nodes
nodes[node.attrib['id']] = node
node_type = node.attrib['type']
if node_type in ['CHANX', 'CHANY']:
loc_xml = node.find('loc')
assert loc_xml is not None
for x in range(int(loc_xml.attrib['xlow']),
int(loc_xml.attrib['xhigh']) + 1):
for y in range(int(loc_xml.attrib['ylow']),
int(loc_xml.attrib['yhigh']) + 1):
key = (node_type, x, y)
if key not in chan_ptcs:
chan_ptcs[key] = []
chan_ptcs[key].append(
(node.attrib['id'], int(loc_xml.attrib['ptc']))
)
for (node_type, x, y), node_ptcs in chan_ptcs.items():
nodes, ptcs = zip(*node_ptcs)
starts_at_zero = min(ptcs) == 0
ends_at_max_val = max(ptcs) == len(ptcs) - 1
all_values_present = len(ptcs) == len(set(ptcs))
if not all((starts_at_zero, ends_at_max_val, all_values_present)):
sorted_nodes = sorted(zip(ptcs, nodes), key=lambda x: x[0])
for idx, (ptc, node) in enumerate(sorted_nodes):
if idx == ptc:
continue
if idx > 1:
raise ValueError(
"""\
Gap in ptc value for type = {node_type} @ ({x}, {y})
Expect PTC = {idx}, found {ptc}
Current node is id = {cur_node}
Previous node is id = {prev_node}""".format(
x=x,
y=y,
node_type=node_type,
idx=idx,
ptc=ptc,
cur_node=node,
prev_node=sorted_nodes[idx - 1][1],
)
)
else:
raise ValueError(
"Lowest ptc is {ptc} for type = {node_type} @ ({x}, {y})"
.format(
x=x,
y=y,
node_type=node_type,
ptc=ptc,
)
)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('input_xml')
args = parser.parse_args()
xml = ET.parse(args.input_xml, ET.XMLParser(remove_blank_text=True))
check_ptc(xml)
if __name__ == "__main__":
main()