nodes: 0, module; 1, function_definition; 2, function_name:sort_header; 3, parameters; 4, block; 5, identifier:header_text; 6, expression_statement; 7, expression_statement; 8, expression_statement; 9, for_statement; 10, expression_statement; 11, expression_statement; 12, for_statement; 13, return_statement; 14, comment:"""sort the chromosomes in a header text"""; 15, assignment; 16, assignment; 17, identifier:ln; 18, identifier:lines; 19, block; 20, assignment; 21, assignment; 22, identifier:ln; 23, identifier:lines; 24, block; 25, identifier:output; 26, identifier:lines; 27, call; 28, identifier:rlens; 29, dictionary; 30, expression_statement; 31, if_statement; 32, identifier:output; 33, string; 34, identifier:done_lens; 35, False; 36, if_statement; 37, attribute; 38, argument_list; 39, assignment; 40, identifier:m; 41, block; 42, call; 43, block; 44, else_clause; 45, call; 46, identifier:split; 47, string:"\n"; 48, identifier:m; 49, call; 50, expression_statement; 51, attribute; 52, argument_list; 53, if_statement; 54, block; 55, attribute; 56, argument_list; 57, attribute; 58, argument_list; 59, assignment; 60, identifier:re; 61, identifier:match; 62, string; 63, identifier:ln; 64, not_operator; 65, block; 66, expression_statement; 67, identifier:header_text; 68, identifier:rstrip; 69, identifier:re; 70, identifier:match; 71, string; 72, identifier:ln; 73, subscript; 74, call; 75, string_content; 76, identifier:done_lens; 77, expression_statement; 78, for_statement; 79, augmented_assignment; 80, string_content; 81, identifier:rlens; 82, call; 83, attribute; 84, argument_list; 85, escape_sequence:\t; 86, assignment; 87, identifier:chr; 88, call; 89, block; 90, identifier:output; 91, binary_operator:ln.rstrip("\n")+"\n"; 92, escape_sequence:\t; 93, escape_sequence:\t; 94, attribute; 95, argument_list; 96, identifier:m; 97, identifier:group; 98, integer:2; 99, identifier:done_lens; 100, True; 101, identifier:sorted; 102, argument_list; 103, expression_statement; 104, call; 105, string:"\n"; 106, identifier:m; 107, identifier:group; 108, integer:1; 109, call; 110, augmented_assignment; 111, attribute; 112, argument_list; 113, attribute; 114, argument_list; 115, identifier:output; 116, binary_operator:"@SQ\tSN:"+chr+"\tLN:"+str(rlens[chr])+"\n"; 117, identifier:ln; 118, identifier:rstrip; 119, string:"\n"; 120, identifier:rlens; 121, identifier:keys; 122, binary_operator:"@SQ\tSN:"+chr+"\tLN:"+str(rlens[chr]); 123, string:"\n"; 124, binary_operator:"@SQ\tSN:"+chr+"\tLN:"; 125, call; 126, binary_operator:"@SQ\tSN:"+chr; 127, string:"\tLN:"; 128, identifier:str; 129, argument_list; 130, string:"@SQ\tSN:"; 131, identifier:chr; 132, subscript; 133, identifier:rlens; 134, identifier:chr
code: def sort_header(header_text):
    """sort the chromosomes in a header text"""
    lines = header_text.rstrip().split("\n")
    rlens = {}
    for ln in lines:
      m = re.match('@SQ\tSN:(\S+)\tLN:(\S+)',ln)
      if m:
        rlens[m.group(1)] = m.group(2)
    output = ''
    done_lens = False
    for ln in lines:
      if re.match('@SQ\tSN:',ln):
        if not done_lens:
          done_lens = True
          for chr in sorted(rlens.keys()):
            output += "@SQ\tSN:"+chr+"\tLN:"+str(rlens[chr])+"\n"
      else:
        output += ln.rstrip("\n")+"\n"
    return output