nodes: 0, module; 1, function_definition; 2, function_name:align_bam; 3, parameters; 4, block; 5, identifier:in_bam; 6, identifier:ref_file; 7, identifier:names; 8, identifier:align_dir; 9, identifier:data; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, comment:# adjust memory for samtools since used for input and output; 18, expression_statement; 19, if_statement; 20, return_statement; 21, comment:"""Perform direct alignment of an input BAM file with BWA using pipes.
  
      This avoids disk IO by piping between processes:
       - samtools sort of input BAM to queryname
       - bedtools conversion to interleaved FASTQ
       - bwa-mem alignment
       - samtools conversion to BAM
       - samtools sort to coordinate
      """; 22, assignment; 23, assignment; 24, assignment; 25, assignment; 26, assignment; 27, assignment; 28, assignment; 29, not_operator; 30, block; 31, identifier:out_file; 32, identifier:config; 33, subscript; 34, identifier:out_file; 35, call; 36, identifier:samtools; 37, call; 38, identifier:bedtools; 39, call; 40, identifier:resources; 41, call; 42, identifier:num_cores; 43, call; 44, identifier:max_mem; 45, call; 46, call; 47, with_statement; 48, identifier:data; 49, string:"config"; 50, attribute; 51, argument_list; 52, attribute; 53, argument_list; 54, attribute; 55, argument_list; 56, attribute; 57, argument_list; 58, attribute; 59, argument_list; 60, attribute; 61, argument_list; 62, attribute; 63, argument_list; 64, with_clause; 65, block; 66, attribute; 67, identifier:join; 68, identifier:align_dir; 69, call; 70, identifier:config_utils; 71, identifier:get_program; 72, string:"samtools"; 73, identifier:config; 74, identifier:config_utils; 75, identifier:get_program; 76, string:"bedtools"; 77, identifier:config; 78, identifier:config_utils; 79, identifier:get_resources; 80, string:"samtools"; 81, identifier:config; 82, subscript; 83, identifier:get; 84, string:"num_cores"; 85, integer:1; 86, call; 87, identifier:upper; 88, identifier:utils; 89, identifier:file_exists; 90, identifier:out_file; 91, with_item; 92, with_statement; 93, identifier:os; 94, identifier:path; 95, attribute; 96, argument_list; 97, identifier:config; 98, string:"algorithm"; 99, attribute; 100, argument_list; 101, as_pattern; 102, with_clause; 103, block; 104, string:"{0}-sort.bam"; 105, identifier:format; 106, subscript; 107, identifier:config_utils; 108, identifier:adjust_memory; 109, call; 110, integer:3; 111, string:"decrease"; 112, call; 113, as_pattern_target; 114, with_item; 115, expression_statement; 116, expression_statement; 117, expression_statement; 118, expression_statement; 119, expression_statement; 120, expression_statement; 121, identifier:names; 122, string:"lane"; 123, attribute; 124, argument_list; 125, identifier:tx_tmpdir; 126, argument_list; 127, identifier:work_dir; 128, as_pattern; 129, assignment; 130, assignment; 131, assignment; 132, assignment; 133, assignment; 134, call; 135, identifier:resources; 136, identifier:get; 137, string:"memory"; 138, string:"1G"; 139, identifier:data; 140, call; 141, as_pattern_target; 142, identifier:bwa_cmd; 143, call; 144, identifier:tx_out_prefix; 145, subscript; 146, identifier:prefix1; 147, binary_operator:"%s-in1" % tx_out_prefix; 148, identifier:cmd; 149, parenthesized_expression; 150, identifier:cmd; 151, binary_operator:cmd.format(**locals()) + tobam_cl; 152, attribute; 153, argument_list; 154, attribute; 155, argument_list; 156, tuple; 157, identifier:_get_bwa_mem_cmd; 158, argument_list; 159, call; 160, integer:0; 161, string:"%s-in1"; 162, identifier:tx_out_prefix; 163, concatenated_string; 164, call; 165, identifier:tobam_cl; 166, identifier:do; 167, identifier:run; 168, identifier:cmd; 169, binary_operator:"bwa mem alignment from BAM: %s" % names["sample"]; 170, None; 171, list; 172, identifier:postalign; 173, identifier:tobam_cl; 174, identifier:data; 175, identifier:out_file; 176, call; 177, identifier:tobam_cl; 178, identifier:tx_out_file; 179, identifier:data; 180, identifier:out_file; 181, identifier:ref_file; 182, string:"-"; 183, attribute; 184, argument_list; 185, string:"unset JAVA_HOME && "; 186, string:"{samtools} sort -n -o -l 1 -@ {num_cores} -m {max_mem} {in_bam} {prefix1} "; 187, string:"| {bedtools} bamtofastq -i /dev/stdin -fq /dev/stdout -fq2 /dev/stdout "; 188, string:"| {bwa_cmd} | "; 189, attribute; 190, argument_list; 191, string:"bwa mem alignment from BAM: %s"; 192, subscript; 193, call; 194, call; 195, attribute; 196, argument_list; 197, attribute; 198, identifier:splitext; 199, identifier:tx_out_file; 200, identifier:cmd; 201, identifier:format; 202, dictionary_splat; 203, identifier:names; 204, string:"sample"; 205, attribute; 206, argument_list; 207, attribute; 208, argument_list; 209, identifier:bam; 210, identifier:is_paired; 211, identifier:in_bam; 212, identifier:os; 213, identifier:path; 214, call; 215, identifier:do; 216, identifier:file_nonempty; 217, identifier:tx_out_file; 218, identifier:do; 219, identifier:file_reasonable_size; 220, identifier:tx_out_file; 221, identifier:in_bam; 222, identifier:locals; 223, argument_list
code: def align_bam(in_bam, ref_file, names, align_dir, data):
      """Perform direct alignment of an input BAM file with BWA using pipes.
  
      This avoids disk IO by piping between processes:
       - samtools sort of input BAM to queryname
       - bedtools conversion to interleaved FASTQ
       - bwa-mem alignment
       - samtools conversion to BAM
       - samtools sort to coordinate
      """
      config = data["config"]
      out_file = os.path.join(align_dir, "{0}-sort.bam".format(names["lane"]))
      samtools = config_utils.get_program("samtools", config)
      bedtools = config_utils.get_program("bedtools", config)
      resources = config_utils.get_resources("samtools", config)
      num_cores = config["algorithm"].get("num_cores", 1)
      # adjust memory for samtools since used for input and output
      max_mem = config_utils.adjust_memory(resources.get("memory", "1G"),
                                           3, "decrease").upper()
      if not utils.file_exists(out_file):
          with tx_tmpdir(data) as work_dir:
              with postalign.tobam_cl(data, out_file, bam.is_paired(in_bam)) as (tobam_cl, tx_out_file):
                  bwa_cmd = _get_bwa_mem_cmd(data, out_file, ref_file, "-")
                  tx_out_prefix = os.path.splitext(tx_out_file)[0]
                  prefix1 = "%s-in1" % tx_out_prefix
                  cmd = ("unset JAVA_HOME && "
                         "{samtools} sort -n -o -l 1 -@ {num_cores} -m {max_mem} {in_bam} {prefix1} "
                         "| {bedtools} bamtofastq -i /dev/stdin -fq /dev/stdout -fq2 /dev/stdout "
                         "| {bwa_cmd} | ")
                  cmd = cmd.format(**locals()) + tobam_cl
                  do.run(cmd, "bwa mem alignment from BAM: %s" % names["sample"], None,
                         [do.file_nonempty(tx_out_file), do.file_reasonable_size(tx_out_file, in_bam)])
      return out_file