nodes: 0, module; 1, function_definition; 2, function_name:pair_SAM_alignments_with_buffer; 3, parameters; 4, block; 5, identifier:alignments; 6, default_parameter; 7, default_parameter; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, for_statement; 12, if_statement; 13, if_statement; 14, identifier:max_buffer_size; 15, integer:30000000; 16, identifier:primary_only; 17, False; 18, string; 19, assignment; 20, assignment; 21, identifier:almnt; 22, identifier:alignments; 23, block; 24, comparison_operator:len(almnt_buffer) > 0; 25, block; 26, comparison_operator:ambiguous_pairing_counter > 0; 27, block; 28, string_content:Iterate over SAM aligments with buffer, position-sorted paired-end
  
      Args:
          alignments (iterator of SAM/BAM alignments): the alignments to wrap
          max_buffer_size (int): maxmal numer of alignments to keep in memory.
          primary_only (bool): for each read, consider only the primary line
              (SAM flag 0x900 = 0). The SAM specification requires one and only
              one of those for each read.
  
      Yields:
          2-tuples with each pair of alignments.; 29, identifier:almnt_buffer; 30, dictionary; 31, identifier:ambiguous_pairing_counter; 32, integer:0; 33, if_statement; 34, if_statement; 35, comment:# FIXME: almnt.not_primary_alignment currently means secondary; 36, if_statement; 37, expression_statement; 38, if_statement; 39, call; 40, integer:0; 41, expression_statement; 42, for_statement; 43, identifier:ambiguous_pairing_counter; 44, integer:0; 45, expression_statement; 46, not_operator; 47, block; 48, comparison_operator:almnt.pe_which == "unknown"; 49, block; 50, boolean_operator; 51, block; 52, assignment; 53, comparison_operator:matekey in almnt_buffer; 54, block; 55, else_clause; 56, identifier:len; 57, argument_list; 58, call; 59, identifier:almnt_list; 60, call; 61, block; 62, call; 63, attribute; 64, raise_statement; 65, attribute; 66, string:"unknown"; 67, raise_statement; 68, identifier:primary_only; 69, parenthesized_expression; 70, continue_statement; 71, identifier:matekey; 72, tuple; 73, identifier:matekey; 74, identifier:almnt_buffer; 75, if_statement; 76, if_statement; 77, block; 78, identifier:almnt_buffer; 79, attribute; 80, argument_list; 81, identifier:list; 82, argument_list; 83, for_statement; 84, attribute; 85, argument_list; 86, identifier:almnt; 87, identifier:paired_end; 88, call; 89, identifier:almnt; 90, identifier:pe_which; 91, call; 92, boolean_operator; 93, attribute; 94, conditional_expression:"second" if almnt.pe_which == "first" else "first"; 95, conditional_expression:almnt.mate_start.chrom if almnt.mate_aligned else None; 96, conditional_expression:almnt.mate_start.pos if almnt.mate_aligned else None; 97, conditional_expression:almnt.iv.chrom if almnt.aligned else None; 98, conditional_expression:almnt.iv.start if almnt.aligned else None; 99, conditional_expression:-almnt.inferred_insert_size if almnt.aligned and almnt.mate_aligned else None; 100, comparison_operator:len(almnt_buffer[matekey]) == 1; 101, block; 102, else_clause; 103, comparison_operator:almnt.pe_which == "first"; 104, block; 105, else_clause; 106, expression_statement; 107, if_statement; 108, if_statement; 109, identifier:warnings; 110, identifier:warn; 111, binary_operator:"Mate records missing for %d records; first such record: %s." %
              (len(almnt_buffer), str(list(almnt_buffer.values())[0][0])); 112, call; 113, identifier:almnt; 114, identifier:almnt_list; 115, block; 116, identifier:warnings; 117, identifier:warn; 118, binary_operator:"Mate pairing was ambiguous for %d records; mate key for first such record: %s." %
              (ambiguous_pairing_counter, str(ambiguous_pairing_first_occurance)); 119, identifier:ValueError; 120, argument_list; 121, identifier:ValueError; 122, argument_list; 123, attribute; 124, attribute; 125, attribute; 126, identifier:name; 127, string:"second"; 128, comparison_operator:almnt.pe_which == "first"; 129, string:"first"; 130, attribute; 131, attribute; 132, None; 133, attribute; 134, attribute; 135, None; 136, attribute; 137, attribute; 138, None; 139, attribute; 140, attribute; 141, None; 142, unary_operator; 143, boolean_operator; 144, None; 145, call; 146, integer:1; 147, expression_statement; 148, delete_statement; 149, block; 150, attribute; 151, string:"first"; 152, expression_statement; 153, block; 154, assignment; 155, comparison_operator:almntkey not in almnt_buffer; 156, block; 157, else_clause; 158, comparison_operator:len(almnt_buffer) > max_buffer_size; 159, block; 160, string:"Mate records missing for %d records; first such record: %s."; 161, tuple; 162, attribute; 163, argument_list; 164, if_statement; 165, string:"Mate pairing was ambiguous for %d records; mate key for first such record: %s."; 166, tuple; 167, string:"Sequence of paired-end alignments expected, but got single-end alignment."; 168, string:"Cannot process paired-end alignment found with 'unknown' 'pe_which' status."; 169, identifier:almnt; 170, identifier:not_primary_alignment; 171, identifier:almnt; 172, identifier:supplementary; 173, identifier:almnt; 174, identifier:read; 175, attribute; 176, string:"first"; 177, attribute; 178, identifier:chrom; 179, identifier:almnt; 180, identifier:mate_aligned; 181, attribute; 182, identifier:pos; 183, identifier:almnt; 184, identifier:mate_aligned; 185, attribute; 186, identifier:chrom; 187, identifier:almnt; 188, identifier:aligned; 189, attribute; 190, identifier:start; 191, identifier:almnt; 192, identifier:aligned; 193, attribute; 194, attribute; 195, attribute; 196, identifier:len; 197, argument_list; 198, assignment; 199, subscript; 200, expression_statement; 201, if_statement; 202, expression_statement; 203, identifier:almnt; 204, identifier:pe_which; 205, yield; 206, expression_statement; 207, identifier:almntkey; 208, tuple; 209, identifier:almntkey; 210, identifier:almnt_buffer; 211, expression_statement; 212, block; 213, call; 214, identifier:max_buffer_size; 215, raise_statement; 216, call; 217, call; 218, identifier:almnt_buffer; 219, identifier:values; 220, comparison_operator:almnt.pe_which == "first"; 221, block; 222, else_clause; 223, identifier:ambiguous_pairing_counter; 224, call; 225, identifier:almnt; 226, identifier:pe_which; 227, identifier:almnt; 228, identifier:mate_start; 229, identifier:almnt; 230, identifier:mate_start; 231, identifier:almnt; 232, identifier:iv; 233, identifier:almnt; 234, identifier:iv; 235, identifier:almnt; 236, identifier:inferred_insert_size; 237, identifier:almnt; 238, identifier:aligned; 239, identifier:almnt; 240, identifier:mate_aligned; 241, subscript; 242, identifier:mate; 243, subscript; 244, identifier:almnt_buffer; 245, identifier:matekey; 246, assignment; 247, comparison_operator:ambiguous_pairing_counter == 0; 248, block; 249, augmented_assignment; 250, tuple; 251, yield; 252, attribute; 253, attribute; 254, conditional_expression:almnt.iv.chrom if almnt.aligned else None; 255, conditional_expression:almnt.iv.start if almnt.aligned else None; 256, conditional_expression:almnt.mate_start.chrom if almnt.mate_aligned else None; 257, conditional_expression:almnt.mate_start.pos if almnt.mate_aligned else None; 258, conditional_expression:almnt.inferred_insert_size if almnt.aligned and almnt.mate_aligned else None; 259, assignment; 260, expression_statement; 261, identifier:len; 262, argument_list; 263, call; 264, identifier:len; 265, argument_list; 266, identifier:str; 267, argument_list; 268, attribute; 269, string:"first"; 270, expression_statement; 271, block; 272, identifier:str; 273, argument_list; 274, identifier:almnt_buffer; 275, identifier:matekey; 276, subscript; 277, integer:0; 278, identifier:mate; 279, call; 280, identifier:ambiguous_pairing_counter; 281, integer:0; 282, expression_statement; 283, identifier:ambiguous_pairing_counter; 284, integer:1; 285, identifier:almnt; 286, identifier:mate; 287, tuple; 288, attribute; 289, identifier:name; 290, identifier:almnt; 291, identifier:pe_which; 292, attribute; 293, attribute; 294, None; 295, attribute; 296, attribute; 297, None; 298, attribute; 299, attribute; 300, None; 301, attribute; 302, attribute; 303, None; 304, attribute; 305, boolean_operator; 306, None; 307, subscript; 308, list; 309, call; 310, identifier:almnt_buffer; 311, identifier:ValueError; 312, argument_list; 313, identifier:almnt_buffer; 314, subscript; 315, identifier:almnt; 316, identifier:pe_which; 317, yield; 318, expression_statement; 319, identifier:ambiguous_pairing_first_occurance; 320, identifier:almnt_buffer; 321, identifier:matekey; 322, attribute; 323, argument_list; 324, assignment; 325, identifier:mate; 326, identifier:almnt; 327, identifier:almnt; 328, identifier:read; 329, attribute; 330, identifier:chrom; 331, identifier:almnt; 332, identifier:aligned; 333, attribute; 334, identifier:start; 335, identifier:almnt; 336, identifier:aligned; 337, attribute; 338, identifier:chrom; 339, identifier:almnt; 340, identifier:mate_aligned; 341, attribute; 342, identifier:pos; 343, identifier:almnt; 344, identifier:mate_aligned; 345, identifier:almnt; 346, identifier:inferred_insert_size; 347, attribute; 348, attribute; 349, identifier:almnt_buffer; 350, identifier:almntkey; 351, identifier:almnt; 352, attribute; 353, argument_list; 354, string:"Maximum alignment buffer size exceeded while pairing SAM alignments."; 355, subscript; 356, integer:0; 357, tuple; 358, yield; 359, subscript; 360, identifier:pop; 361, integer:0; 362, identifier:ambiguous_pairing_first_occurance; 363, identifier:matekey; 364, identifier:almnt; 365, identifier:iv; 366, identifier:almnt; 367, identifier:iv; 368, identifier:almnt; 369, identifier:mate_start; 370, identifier:almnt; 371, identifier:mate_start; 372, identifier:almnt; 373, identifier:aligned; 374, identifier:almnt; 375, identifier:mate_aligned; 376, subscript; 377, identifier:append; 378, identifier:almnt; 379, call; 380, integer:0; 381, identifier:almnt; 382, None; 383, tuple; 384, identifier:almnt_buffer; 385, identifier:matekey; 386, identifier:almnt_buffer; 387, identifier:almntkey; 388, identifier:list; 389, argument_list; 390, None; 391, identifier:almnt; 392, call; 393, attribute; 394, argument_list; 395, identifier:almnt_buffer; 396, identifier:values
code: def pair_SAM_alignments_with_buffer(
          alignments,
          max_buffer_size=30000000,
          primary_only=False):
      '''Iterate over SAM aligments with buffer, position-sorted paired-end
  
      Args:
          alignments (iterator of SAM/BAM alignments): the alignments to wrap
          max_buffer_size (int): maxmal numer of alignments to keep in memory.
          primary_only (bool): for each read, consider only the primary line
              (SAM flag 0x900 = 0). The SAM specification requires one and only
              one of those for each read.
  
      Yields:
          2-tuples with each pair of alignments.
      '''
  
      almnt_buffer = {}
      ambiguous_pairing_counter = 0
      for almnt in alignments:
          if not almnt.paired_end:
              raise ValueError(
                  "Sequence of paired-end alignments expected, but got single-end alignment.")
          if almnt.pe_which == "unknown":
              raise ValueError(
                  "Cannot process paired-end alignment found with 'unknown' 'pe_which' status.")
          # FIXME: almnt.not_primary_alignment currently means secondary
          if primary_only and (almnt.not_primary_alignment or almnt.supplementary):
              continue
  
          matekey = (
              almnt.read.name,
              "second" if almnt.pe_which == "first" else "first",
              almnt.mate_start.chrom if almnt.mate_aligned else None,
              almnt.mate_start.pos if almnt.mate_aligned else None,
              almnt.iv.chrom if almnt.aligned else None,
              almnt.iv.start if almnt.aligned else None,
              -almnt.inferred_insert_size if almnt.aligned and almnt.mate_aligned else None)
  
          if matekey in almnt_buffer:
              if len(almnt_buffer[matekey]) == 1:
                  mate = almnt_buffer[matekey][0]
                  del almnt_buffer[matekey]
              else:
                  mate = almnt_buffer[matekey].pop(0)
                  if ambiguous_pairing_counter == 0:
                      ambiguous_pairing_first_occurance = matekey
                  ambiguous_pairing_counter += 1
              if almnt.pe_which == "first":
                  yield (almnt, mate)
              else:
                  yield (mate, almnt)
          else:
              almntkey = (
                  almnt.read.name, almnt.pe_which,
                  almnt.iv.chrom if almnt.aligned else None,
                  almnt.iv.start if almnt.aligned else None,
                  almnt.mate_start.chrom if almnt.mate_aligned else None,
                  almnt.mate_start.pos if almnt.mate_aligned else None,
                  almnt.inferred_insert_size if almnt.aligned and almnt.mate_aligned else None)
              if almntkey not in almnt_buffer:
                  almnt_buffer[almntkey] = [almnt]
              else:
                  almnt_buffer[almntkey].append(almnt)
              if len(almnt_buffer) > max_buffer_size:
                  raise ValueError(
                      "Maximum alignment buffer size exceeded while pairing SAM alignments.")
  
      if len(almnt_buffer) > 0:
          warnings.warn(
              "Mate records missing for %d records; first such record: %s." %
              (len(almnt_buffer), str(list(almnt_buffer.values())[0][0])))
          for almnt_list in list(almnt_buffer.values()):
              for almnt in almnt_list:
                  if almnt.pe_which == "first":
                      yield (almnt, None)
                  else:
                      yield (None, almnt)
  
      if ambiguous_pairing_counter > 0:
          warnings.warn(
              "Mate pairing was ambiguous for %d records; mate key for first such record: %s." %
              (ambiguous_pairing_counter, str(ambiguous_pairing_first_occurance)))