nodes: 0, module; 1, function_definition; 2, function_name:sort_layout; 3, parameters; 4, block; 5, identifier:thread; 6, identifier:listfile; 7, default_parameter; 8, expression_statement; 9, import_from_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, for_statement; 17, assert_statement; 18, expression_statement; 19, expression_statement; 20, expression_statement; 21, for_statement; 22, for_statement; 23, expression_statement; 24, expression_statement; 25, identifier:column; 26, integer:0; 27, comment:"""
      Sort the syntelog table according to chromomomal positions. First orient the
      contents against threadbed, then for contents not in threadbed, insert to
      the nearest neighbor.
      """; 28, dotted_name; 29, dotted_name; 30, assignment; 31, assignment; 32, assignment; 33, assignment; 34, assignment; 35, assignment; 36, identifier:t; 37, identifier:thread; 38, block; 39, comparison_operator:len(threaded) == len(imported); 40, assignment; 41, call; 42, assignment; 43, identifier:row; 44, identifier:fp; 45, block; 46, identifier:atoms; 47, identifier:threaded; 48, block; 49, call; 50, call; 51, identifier:jcvi; 52, identifier:formats; 53, identifier:base; 54, identifier:DictFile; 55, identifier:outfile; 56, binary_operator:listfile.rsplit(".", 1)[0] + ".sorted.list"; 57, identifier:threadorder; 58, attribute; 59, identifier:fw; 60, call; 61, identifier:lt; 62, call; 63, identifier:threaded; 64, list; 65, identifier:imported; 66, call; 67, expression_statement; 68, if_statement; 69, expression_statement; 70, expression_statement; 71, expression_statement; 72, call; 73, call; 74, identifier:total; 75, call; 76, attribute; 77, argument_list; 78, identifier:fp; 79, call; 80, expression_statement; 81, expression_statement; 82, if_statement; 83, expression_statement; 84, expression_statement; 85, attribute; 86, argument_list; 87, attribute; 88, argument_list; 89, subscript; 90, string:".sorted.list"; 91, identifier:thread; 92, identifier:order; 93, identifier:open; 94, argument_list; 95, identifier:DictFile; 96, argument_list; 97, identifier:set; 98, argument_list; 99, assignment; 100, comparison_operator:accn not in lt; 101, block; 102, call; 103, assignment; 104, call; 105, identifier:len; 106, argument_list; 107, identifier:len; 108, argument_list; 109, identifier:sum; 110, generator_expression; 111, identifier:logging; 112, identifier:debug; 113, call; 114, identifier:open; 115, argument_list; 116, assignment; 117, assignment; 118, comparison_operator:accn in imported; 119, block; 120, call; 121, call; 122, identifier:fw; 123, identifier:close; 124, identifier:logging; 125, identifier:debug; 126, call; 127, call; 128, integer:0; 129, identifier:outfile; 130, string:"w"; 131, identifier:listfile; 132, keyword_argument; 133, keyword_argument; 134, identifier:accn; 135, attribute; 136, identifier:accn; 137, identifier:lt; 138, continue_statement; 139, attribute; 140, argument_list; 141, identifier:atoms; 142, subscript; 143, attribute; 144, argument_list; 145, identifier:threaded; 146, identifier:imported; 147, integer:1; 148, for_in_clause; 149, attribute; 150, argument_list; 151, identifier:listfile; 152, identifier:atoms; 153, call; 154, identifier:accn; 155, subscript; 156, identifier:accn; 157, identifier:imported; 158, continue_statement; 159, identifier:insert_into_threaded; 160, argument_list; 161, identifier:print; 162, argument_list; 163, attribute; 164, argument_list; 165, attribute; 166, argument_list; 167, identifier:keypos; 168, identifier:column; 169, identifier:valuepos; 170, None; 171, identifier:t; 172, identifier:accn; 173, identifier:imported; 174, identifier:add; 175, identifier:accn; 176, identifier:lt; 177, identifier:accn; 178, identifier:threaded; 179, identifier:append; 180, identifier:atoms; 181, identifier:x; 182, call; 183, string:"Total: {0}, currently threaded: {1}"; 184, identifier:format; 185, identifier:total; 186, call; 187, attribute; 188, argument_list; 189, identifier:atoms; 190, integer:0; 191, identifier:atoms; 192, identifier:threaded; 193, identifier:threadorder; 194, call; 195, keyword_argument; 196, string:"File `{0}` sorted to `{1}`."; 197, identifier:format; 198, identifier:outfile; 199, attribute; 200, identifier:listfile; 201, identifier:rsplit; 202, string:"."; 203, integer:1; 204, identifier:open; 205, argument_list; 206, identifier:len; 207, argument_list; 208, identifier:row; 209, identifier:split; 210, attribute; 211, argument_list; 212, identifier:file; 213, identifier:fw; 214, identifier:thread; 215, identifier:filename; 216, identifier:listfile; 217, identifier:threaded; 218, string:"\t"; 219, identifier:join; 220, identifier:atoms
code: def sort_layout(thread, listfile, column=0):
      """
      Sort the syntelog table according to chromomomal positions. First orient the
      contents against threadbed, then for contents not in threadbed, insert to
      the nearest neighbor.
      """
      from jcvi.formats.base import DictFile
  
      outfile = listfile.rsplit(".", 1)[0] + ".sorted.list"
      threadorder = thread.order
      fw = open(outfile, "w")
      lt = DictFile(listfile, keypos=column, valuepos=None)
      threaded = []
      imported = set()
      for t in thread:
          accn = t.accn
          if accn not in lt:
              continue
  
          imported.add(accn)
          atoms = lt[accn]
          threaded.append(atoms)
  
      assert len(threaded) == len(imported)
  
      total = sum(1 for x in open(listfile))
      logging.debug("Total: {0}, currently threaded: {1}".format(total, len(threaded)))
      fp = open(listfile)
      for row in fp:
          atoms = row.split()
          accn = atoms[0]
          if accn in imported:
              continue
          insert_into_threaded(atoms, threaded, threadorder)
  
      for atoms in threaded:
          print("\t".join(atoms), file=fw)
  
      fw.close()
      logging.debug("File `{0}` sorted to `{1}`.".format(outfile, thread.filename))