new_contents: #!/usr/bin/env python3
  #
  # Produces a complete database of wires in the ROI and their connections and tests if each
  # routing node is a tree (i.e. fails with an error when a loop is found).
  
  import os, sys, json
  
  with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")), "r") as f:
      tilegrid = json.load(f)["tiles"]
  
  with open("%s/%s/tileconn.json" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")), "r") as f:
      tileconn = json.load(f)
  
  grid = dict()
  wirepairs = dict()
  remwires = set()
  
  for tilename, tiledata in tilegrid.items():
      key = (tiledata["grid_x"], tiledata["grid_y"])
      grid[key] = tilename
  
  def check_tileconn_entry(tilename, tiledata, entry, idx):
      if idx == 0:
          otheridx = 1
          otherxy = (tiledata["grid_x"] + entry["grid_deltas"][0], tiledata["grid_y"] + entry["grid_deltas"][1])
      else:
          otheridx = 0
          otherxy = (tiledata["grid_x"] - entry["grid_deltas"][0], tiledata["grid_y"] - entry["grid_deltas"][1])
  
      if otherxy not in grid:
          return
  
      othertilename = grid[otherxy]
      othertiledata = tilegrid[othertilename]
  
      if othertiledata["type"] != entry["tile_types"][otheridx]:
          return
  
      print("  Found relevant entry (%s %s %d %d): %s" % (entry["tile_types"][0], entry["tile_types"][1],
              entry["grid_deltas"][0], entry["grid_deltas"][1], othertilename))
  
      for pair in entry["wire_pairs"]:
          wirename = "%s/%s" % (tilename, pair[idx])
          otherwirename = "%s/%s" % (othertilename, pair[otheridx])
  
          remwires.add(wirename)
          remwires.add(otherwirename)
  
          if wirename not in wirepairs:
              wirepairs[wirename] = set()
          wirepairs[wirename].add(otherwirename)
  
          if otherwirename not in wirepairs:
              wirepairs[otherwirename] = set()
          wirepairs[otherwirename].add(wirename)
  
  for tilename, tiledata in tilegrid.items():
      print("Connecting wires in tile %s." % tilename)
      for entry in tileconn:
          if entry["tile_types"][0] == tiledata["type"]:
              check_tileconn_entry(tilename, tiledata, entry, 0)
          if entry["tile_types"][1] == tiledata["type"]:
              check_tileconn_entry(tilename, tiledata, entry, 1)
  
  def check_wire(wire, source):
      for next_wire in wirepairs[wire]:
          if next_wire == source:
              continue
          print("  %s" % next_wire)
          if next_wire not in remwires:
              print("  ** FOUND LOOP IN THIS NODE **")
              sys.exit(1)
          remwires.remove(next_wire)
          check_wire(next_wire, wire)
  
  while len(remwires):
      wire = remwires.pop()
      print("Checking %s:" % wire)
      check_wire(wire, None)
  
  print("NO LOOP FOUND: OK")
  
  
subject: Add tileconnloops.py script