nodes: 0, module; 1, function_definition; 2, function_name:sort; 3, parameters; 4, block; 5, identifier:in_bam; 6, identifier:config; 7, default_parameter; 8, default_parameter; 9, expression_statement; 10, assert_statement; 11, if_statement; 12, expression_statement; 13, expression_statement; 14, if_statement; 15, return_statement; 16, identifier:order; 17, string:"coordinate"; 18, identifier:out_dir; 19, None; 20, comment:"""Sort a BAM file, skipping if already present.
      """; 21, call; 22, binary_operator:"%s in not a BAM file" % in_bam; 23, call; 24, block; 25, assignment; 26, assignment; 27, not_operator; 28, block; 29, identifier:sort_file; 30, identifier:is_bam; 31, argument_list; 32, string:"%s in not a BAM file"; 33, identifier:in_bam; 34, identifier:bam_already_sorted; 35, argument_list; 36, return_statement; 37, identifier:sort_stem; 38, call; 39, identifier:sort_file; 40, binary_operator:sort_stem + ".bam"; 41, call; 42, expression_statement; 43, expression_statement; 44, with_statement; 45, identifier:in_bam; 46, identifier:in_bam; 47, identifier:config; 48, identifier:order; 49, identifier:in_bam; 50, identifier:_get_sort_stem; 51, argument_list; 52, identifier:sort_stem; 53, string:".bam"; 54, attribute; 55, argument_list; 56, assignment; 57, assignment; 58, with_clause; 59, block; 60, identifier:in_bam; 61, identifier:order; 62, identifier:out_dir; 63, identifier:utils; 64, identifier:file_exists; 65, identifier:sort_file; 66, identifier:samtools; 67, call; 68, identifier:cores; 69, call; 70, with_item; 71, expression_statement; 72, expression_statement; 73, expression_statement; 74, expression_statement; 75, comment:# Slightly decrease memory and allow more accurate representation; 76, comment:# in Mb to ensure fits within systems like SLURM; 77, expression_statement; 78, expression_statement; 79, expression_statement; 80, attribute; 81, argument_list; 82, attribute; 83, argument_list; 84, as_pattern; 85, assignment; 86, assignment; 87, assignment; 88, assignment; 89, assignment; 90, assignment; 91, call; 92, identifier:config_utils; 93, identifier:get_program; 94, string:"samtools"; 95, identifier:config; 96, subscript; 97, identifier:get; 98, string:"num_cores"; 99, integer:1; 100, call; 101, as_pattern_target; 102, identifier:tx_sort_stem; 103, subscript; 104, identifier:tx_dir; 105, call; 106, identifier:order_flag; 107, conditional_expression:"-n" if order == "queryname" else ""; 108, identifier:resources; 109, call; 110, identifier:mem; 111, call; 112, identifier:cmd; 113, parenthesized_expression; 114, attribute; 115, argument_list; 116, identifier:config; 117, string:"algorithm"; 118, identifier:file_transaction; 119, argument_list; 120, identifier:tx_sort_file; 121, call; 122, integer:0; 123, attribute; 124, argument_list; 125, string:"-n"; 126, comparison_operator:order == "queryname"; 127, string:""; 128, attribute; 129, argument_list; 130, attribute; 131, argument_list; 132, concatenated_string; 133, identifier:do; 134, identifier:run; 135, call; 136, binary_operator:"Sort BAM file %s: %s to %s" %
                     (order, os.path.basename(in_bam), os.path.basename(sort_file)); 137, identifier:config; 138, identifier:sort_file; 139, attribute; 140, argument_list; 141, identifier:utils; 142, identifier:safe_makedir; 143, call; 144, identifier:order; 145, string:"queryname"; 146, identifier:config_utils; 147, identifier:get_resources; 148, string:"samtools"; 149, identifier:config; 150, call; 151, identifier:upper; 152, string:"{samtools} sort -@ {cores} -m {mem} -O BAM {order_flag} "; 153, string:"-T {tx_sort_stem}-sort -o {tx_sort_file} {in_bam}"; 154, attribute; 155, argument_list; 156, string:"Sort BAM file %s: %s to %s"; 157, tuple; 158, attribute; 159, identifier:splitext; 160, identifier:tx_sort_file; 161, attribute; 162, argument_list; 163, attribute; 164, argument_list; 165, identifier:cmd; 166, identifier:format; 167, dictionary_splat; 168, identifier:order; 169, call; 170, call; 171, identifier:os; 172, identifier:path; 173, attribute; 174, identifier:dirname; 175, identifier:tx_sort_file; 176, identifier:config_utils; 177, identifier:adjust_memory; 178, call; 179, float:1.25; 180, string:"decrease"; 181, keyword_argument; 182, call; 183, attribute; 184, argument_list; 185, attribute; 186, argument_list; 187, identifier:os; 188, identifier:path; 189, attribute; 190, argument_list; 191, identifier:out_modifier; 192, string:"M"; 193, identifier:locals; 194, argument_list; 195, attribute; 196, identifier:basename; 197, identifier:in_bam; 198, attribute; 199, identifier:basename; 200, identifier:sort_file; 201, identifier:resources; 202, identifier:get; 203, string:"memory"; 204, string:"2G"; 205, identifier:os; 206, identifier:path; 207, identifier:os; 208, identifier:path
code: def sort(in_bam, config, order="coordinate", out_dir=None):
      """Sort a BAM file, skipping if already present.
      """
      assert is_bam(in_bam), "%s in not a BAM file" % in_bam
      if bam_already_sorted(in_bam, config, order):
          return in_bam
  
      sort_stem = _get_sort_stem(in_bam, order, out_dir)
      sort_file = sort_stem + ".bam"
      if not utils.file_exists(sort_file):
          samtools = config_utils.get_program("samtools", config)
          cores = config["algorithm"].get("num_cores", 1)
          with file_transaction(config, sort_file) as tx_sort_file:
              tx_sort_stem = os.path.splitext(tx_sort_file)[0]
              tx_dir = utils.safe_makedir(os.path.dirname(tx_sort_file))
              order_flag = "-n" if order == "queryname" else ""
              resources = config_utils.get_resources("samtools", config)
              # Slightly decrease memory and allow more accurate representation
              # in Mb to ensure fits within systems like SLURM
              mem = config_utils.adjust_memory(resources.get("memory", "2G"),
                                               1.25, "decrease", out_modifier="M").upper()
              cmd = ("{samtools} sort -@ {cores} -m {mem} -O BAM {order_flag} "
                     "-T {tx_sort_stem}-sort -o {tx_sort_file} {in_bam}")
              do.run(cmd.format(**locals()), "Sort BAM file %s: %s to %s" %
                     (order, os.path.basename(in_bam), os.path.basename(sort_file)))
      return sort_file