@@ -182,7 +182,7 @@ def trim(segment, primer_pos, end, verbose=False):
182182
183183 # softmask the left primer
184184 if not end :
185- # update the position of the leftmost mappinng base
185+ # update the position of the leftmost mapping base
186186 segment .pos = pos - extra
187187 if verbose :
188188 print (
@@ -342,19 +342,34 @@ def handle_segments(
342342 )
343343 else :
344344 # locate the nearest primers to this alignment segment pair
345- p1 = find_primer_with_lookup (
346- lookup = lookup ,
347- pos = segment1 .reference_start ,
348- direction = "+" ,
349- chrom = segment1 .reference_name ,
350- )
351-
352- p2 = find_primer_with_lookup (
353- lookup = lookup ,
354- pos = segment2 .reference_end ,
355- direction = "-" ,
356- chrom = segment2 .reference_name ,
357- )
345+ if segment1 .reference_start < segment2 .reference_start :
346+ # if segment1 starts before segment2, then segment1 is the left segment relative to the reference
347+ p1 = find_primer_with_lookup (
348+ lookup = lookup ,
349+ pos = segment1 .reference_start ,
350+ direction = "+" ,
351+ chrom = segment1 .reference_name ,
352+ )
353+ p2 = find_primer_with_lookup (
354+ lookup = lookup ,
355+ pos = segment2 .reference_end ,
356+ direction = "-" ,
357+ chrom = segment2 .reference_name ,
358+ )
359+ else :
360+ # otherwise then segment2 is the left segment relative to the reference
361+ p1 = find_primer_with_lookup (
362+ lookup = lookup ,
363+ pos = segment2 .reference_start ,
364+ direction = "+" ,
365+ chrom = segment2 .reference_name ,
366+ )
367+ p2 = find_primer_with_lookup (
368+ lookup = lookup ,
369+ pos = segment1 .reference_end ,
370+ direction = "-" ,
371+ chrom = segment1 .reference_name ,
372+ )
358373
359374 if not p1 or not p2 :
360375 segment = segment1 if segment1 else segment2
@@ -366,8 +381,6 @@ def handle_segments(
366381 return False
367382
368383 # check if primers are correctly paired and then assign read group
369- # NOTE: removed this as a function as only called once
370- # TODO: will try improving this / moving it to the primer scheme processing code
371384 correctly_paired = p1 .amplicon_number == p2 .amplicon_number
372385
373386 if not paired :
@@ -469,15 +482,14 @@ def handle_segments(
469482 return False
470483
471484 # Check require-full-length
472- if not paired :
473- if args .require_full_length :
474- if segment .reference_start > p1 .end or segment .reference_end < p2 .start :
475- if args .verbose :
476- print (
477- f"{ segment .query_name } : ref_start { segment .reference_start } > p1.end { p1 .end } or ref_end { segment .reference_end } < p2.start { p2 .start } , does not span a full amplicon, skipping" ,
478- file = sys .stderr ,
479- )
480- return False
485+ if args .require_full_length :
486+ if segment .reference_start > p1 .end or segment .reference_end < p2 .start :
487+ if args .verbose :
488+ print (
489+ f"{ segment .query_name } : ref_start { segment .reference_start } > p1.end { p1 .end } or ref_end { segment .reference_end } < p2.start { p2 .start } , does not span a full amplicon, skipping" ,
490+ file = sys .stderr ,
491+ )
492+ return False
481493
482494 # If not normalising, write the segment to the output file and add it to amplicon depth numpy array
483495 if not args .normalise :
@@ -496,65 +508,46 @@ def handle_segments(
496508 return (amplicon , segment )
497509
498510 else :
499- if segment1 .reference_start < p1_position :
500- try :
501- trim (segment1 , p1_position , False , args .verbose )
502- if args .verbose :
503- print (
504- f"{ segment1 .query_name } : ref start { segment1 .reference_start } >= primer_position { p1_position } " ,
505- file = sys .stderr ,
511+ for segment_of_pair in (segment1 , segment2 ):
512+ if segment_of_pair .reference_start < p1_position :
513+ try :
514+ trim (
515+ segment_of_pair ,
516+ p1_position ,
517+ segment_of_pair .is_reverse ,
518+ args .verbose ,
506519 )
507- except Exception as e :
508- print (
509- f"{ segment1 .query_name } : Problem soft masking left primer (error: { e } ), skipping" ,
510- file = sys .stderr ,
511- )
512- return False
513-
514- elif segment1 .reference_end > p2_position : # type: ignore
515- try :
516- trim (segment1 , p2_position , True , args .verbose )
517- if args .verbose :
520+ if args .verbose :
521+ print (
522+ f"{ segment_of_pair .query_name } : ref start { segment_of_pair .reference_start } >= primer_position { p1_position } " ,
523+ file = sys .stderr ,
524+ )
525+ except Exception as e :
518526 print (
519- f"{ segment1 .query_name } : ref_end { segment1 . reference_end } >= primer_position { p2_position } " ,
527+ f"{ segment_of_pair .query_name } : Problem soft masking left primer (error: { e } ), skipping " ,
520528 file = sys .stderr ,
521529 )
522- except Exception as e :
523- print (
524- f"{ segment1 .query_name } : Problem soft masking right primer (error: { e } ), skipping" ,
525- file = sys .stderr ,
526- )
527- return False
530+ return False
528531
529- # softmask the alignment if right primer start/end inside alignment
530- if segment2 .reference_end > p2_position : # type: ignore
531- try :
532- trim (segment2 , p2_position , True , args .verbose )
533- if args .verbose :
534- print (
535- f"{ segment1 .query_name } : ref_start { segment2 .reference_start } >= primer_position { p2_position } " ,
536- file = sys .stderr ,
532+ if segment_of_pair .reference_end > p2_position : # type: ignore
533+ try :
534+ trim (
535+ segment_of_pair ,
536+ p2_position ,
537+ segment_of_pair .is_reverse ,
538+ args .verbose ,
537539 )
538- except Exception as e :
539- print (
540- f"{ segment1 .query_name } : Problem soft masking right primer (error: { e } ), skipping" ,
541- file = sys .stderr ,
542- )
543- return False
544- elif segment2 .reference_start < p1_position :
545- try :
546- trim (segment2 , p1_position , False , args .verbose )
547- if args .verbose :
540+ if args .verbose :
541+ print (
542+ f"{ segment_of_pair .query_name } : ref_end { segment_of_pair .reference_end } >= primer_position { p2_position } " ,
543+ file = sys .stderr ,
544+ )
545+ except Exception as e :
548546 print (
549- f"{ segment1 .query_name } : ref_end { segment2 . reference_end } >= primer_position { p1_position } " ,
547+ f"{ segment_of_pair .query_name } : Problem soft masking right primer (error: { e } ), skipping " ,
550548 file = sys .stderr ,
551549 )
552- except Exception as e :
553- print (
554- f"{ segment1 .query_name } : Problem soft masking left primer (error: { e } ), skipping" ,
555- file = sys .stderr ,
556- )
557- return False
550+ return False
558551
559552 # check the the alignment still contains bases matching the reference
560553 if "M" not in segment1 .cigarstring or "M" not in segment2 .cigarstring : # type: ignore
@@ -566,33 +559,40 @@ def handle_segments(
566559 return False
567560
568561 if args .require_full_length :
569- if segment1 .reference_start > p1 .end or segment2 .reference_end < p2 .start :
570- if args .verbose :
571- print (
572- f"{ segment1 .query_name } : ref_start { segment1 .reference_start } > p1.end { p1 .end } or ref_end { segment2 .reference_end } < p2.start { p2 .start } , does not span a full amplicon, skipping" ,
573- file = sys .stderr ,
574- )
575- return False
562+ if segment1 .reference_start < segment2 .reference_start :
563+ if (
564+ segment1 .reference_start > p1 .end
565+ or segment2 .reference_end < p2 .start
566+ ):
567+ if args .verbose :
568+ print (
569+ f"{ segment1 .query_name } : ref_start { segment1 .reference_start } > p1.end { p1 .end } or ref_end { segment2 .reference_end } < p2.start { p2 .start } , does not span a full amplicon, skipping" ,
570+ file = sys .stderr ,
571+ )
572+ return False
573+ else :
574+ if (
575+ segment2 .reference_start > p1 .end
576+ or segment1 .reference_end < p2 .start
577+ ):
578+ if args .verbose :
579+ print (
580+ f"{ segment1 .query_name } : ref_end { segment1 .reference_end } < p1.start { p1 .start } or ref_start { segment2 .reference_start } > p2.end { p2 .end } , does not span a full amplicon, skipping" ,
581+ file = sys .stderr ,
582+ )
583+ return False
576584
577585 # If not normalising, write the segments to the output file and add them to amplicon depth numpy array
578586 if not args .normalise :
579587 outfile_writer .write (segment1 )
580588 outfile_writer .write (segment2 )
581- segment1_amp_relative_start = segment1 .reference_start - p1 .start
582- segment1_amp_relative_end = segment1 .reference_end - p1 .start
583- if segment1_amp_relative_start < 0 :
584- segment1_amp_relative_start = 0
585-
586- segment2_amp_relative_start = segment2 .reference_start - p1 .start
587- segment2_amp_relative_end = segment2 .reference_end - p1 .start
588- if segment2_amp_relative_start < 0 :
589- segment2_amp_relative_start = 0
590-
589+ for segment_in_pair in (segment1 , segment2 ):
590+ segment_amp_relative_start = segment_in_pair .reference_start - p1 .start
591+ segment_amp_relative_end = segment_in_pair .reference_end - p1 .start
592+ if segment_amp_relative_start < 0 :
593+ segment_amp_relative_start = 0
591594 amp_depths [segment1 .reference_name ][amplicon ][
592- segment1_amp_relative_start :segment1_amp_relative_end
593- ] += 1
594- amp_depths [segment2 .reference_name ][amplicon ][
595- segment2_amp_relative_start :segment2_amp_relative_end
595+ segment_amp_relative_start :segment_amp_relative_end
596596 ] += 1
597597
598598 return (amplicon , False )
@@ -813,8 +813,8 @@ def go(args):
813813 pools_str .add ("unmatched" )
814814
815815 # open the input samfile and process read groups
816- if args .bamfile and args .bamfile != "-" :
817- infile = pysam .AlignmentFile (args .bamfile , "rb" )
816+ if args .samfile and args .samfile != "-" :
817+ infile = pysam .AlignmentFile (args .samfile , "rb" )
818818 else :
819819 infile = pysam .AlignmentFile ("-" , "rb" )
820820
@@ -1034,7 +1034,7 @@ def go(args):
10341034
10351035def main ():
10361036 parser = argparse .ArgumentParser (
1037- description = "Trim alignments from an amplicon scheme. Bam (input) can be provided by --bamfile or stdin"
1037+ description = "Trim alignments from an amplicon scheme. Bam (input) can be provided by --samfile or stdin"
10381038 )
10391039 parser .add_argument (
10401040 "bedfile" ,
@@ -1043,9 +1043,9 @@ def main():
10431043 metavar = "BEDFILE" ,
10441044 )
10451045 parser .add_argument (
1046- "--bamfile " ,
1047- "-b " ,
1048- help = "Sorted BAM file containing the aligned reads, if this is not provided (or '-') then 'align_trim' will read from stdin." ,
1046+ "--samfile " ,
1047+ "-i " ,
1048+ help = "Sorted SAM/ BAM file containing the aligned reads, if this is not provided (or '-') then 'align_trim' will read from stdin." ,
10491049 required = False ,
10501050 )
10511051 parser .add_argument (
0 commit comments