Skip to content

Commit

Permalink
Temporarily fix high --normalisation issue until maptide refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
BioWilko committed Jan 23, 2025
1 parent a60ede0 commit 743d5d9
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 19 deletions.
54 changes: 41 additions & 13 deletions artic/align_trim.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@ def find_primer(bed, pos, direction, chrom, threshold=35):
primer_distances = [
(abs(p["start"] - pos), p["start"] - pos, p)
for p in bed
if (p["direction"] == direction) and (pos >= (p["start"] - threshold)) and chrom == p["chrom"]
if (p["direction"] == direction)
and (pos >= (p["start"] - threshold))
and chrom == p["chrom"]
]

else:
primer_distances = [
(abs(p["end"] - pos), p["end"] - pos, p)
for p in bed
if (p["direction"] == direction) and (pos <= (p["end"] + threshold)) and chrom == p["chrom"]
if (p["direction"] == direction)
and (pos <= (p["end"] + threshold))
and chrom == p["chrom"]
]

if not primer_distances:
Expand Down Expand Up @@ -206,9 +210,21 @@ def handle_segment(

# locate the nearest primers to this alignment segment
# p1 = find_primer(bed, segment.reference_start, "+", segment.reference_name, args.primer_match_threshold)
p1 = find_primer(bed=bed, pos=segment.reference_start, direction="+", chrom=segment.reference_name, threshold=args.primer_match_threshold)
p1 = find_primer(
bed=bed,
pos=segment.reference_start,
direction="+",
chrom=segment.reference_name,
threshold=args.primer_match_threshold,
)
# p2 = find_primer(bed, segment.reference_end, "-", segment.reference_name, args.primer_match_threshold)
p2 = find_primer(bed=bed, pos=segment.reference_end, direction="-", chrom=segment.reference_name, threshold=args.primer_match_threshold)
p2 = find_primer(
bed=bed,
pos=segment.reference_end,
direction="-",
chrom=segment.reference_name,
threshold=args.primer_match_threshold,
)

if not p1 or not p2:
if args.verbose:
Expand Down Expand Up @@ -361,7 +377,9 @@ def generate_amplicons(bed: list):
for chrom, amplicons_dict in amplicons.items():
for amplicon in amplicons_dict:
if not all([x in amplicons_dict[amplicon] for x in ["p_start", "p_end"]]):
raise ValueError(f"Primer scheme for amplicon {amplicon} for reference {chrom} is incomplete")
raise ValueError(
f"Primer scheme for amplicon {amplicon} for reference {chrom} is incomplete"
)

# Check if primer runs accross reference start / end -> circular virus
amplicons_dict[amplicon]["circular"] = (
Expand Down Expand Up @@ -408,7 +426,9 @@ def normalise(trimmed_segments: dict, normalise: int, bed: list, verbose: bool =
(amplicons[chrom][amplicon]["length"],), normalise, dtype=int
)

amplicon_depth = np.zeros((amplicons[chrom][amplicon]["length"],), dtype=int)
amplicon_depth = np.zeros(
(amplicons[chrom][amplicon]["length"],), dtype=int
)

if not segments:
if verbose:
Expand All @@ -425,12 +445,16 @@ def normalise(trimmed_segments: dict, normalise: int, bed: list, verbose: bool =
for segment in segments:
test_depths = np.copy(amplicon_depth)

relative_start = segment.reference_start - amplicons[chrom][amplicon]["p_start"]
relative_start = (
segment.reference_start - amplicons[chrom][amplicon]["p_start"]
)

if relative_start < 0:
relative_start = 0

relative_end = segment.reference_end - amplicons[chrom][amplicon]["p_start"]
relative_end = (
segment.reference_end - amplicons[chrom][amplicon]["p_start"]
)

test_depths[relative_start:relative_end] += 1

Expand All @@ -442,7 +466,7 @@ def normalise(trimmed_segments: dict, normalise: int, bed: list, verbose: bool =
output_segments.append(segment)

mean_depths[(chrom, amplicon)] = np.mean(amplicon_depth)

return output_segments, mean_depths


Expand Down Expand Up @@ -519,7 +543,9 @@ def go(args):
trimmed_segments[trimmed_segment.reference_name].setdefault(amplicon, [])

if trimmed_segment:
trimmed_segments[trimmed_segment.reference_name][amplicon].append(trimmed_segment)
trimmed_segments[trimmed_segment.reference_name][amplicon].append(
trimmed_segment
)

# normalise if requested
if args.normalise:
Expand All @@ -536,10 +562,12 @@ def go(args):

for output_segment in output_segments:
outfile.write(output_segment)

else:
for amplicon, segments in trimmed_segments.items():
for segment in segments:
outfile.write(segment)
for chrom, amplicon_dict in trimmed_segments.items():
for amplicon, segments in amplicon_dict.items():
for segment in segments:
outfile.write(segment)

# close up the file handles
infile.close()
Expand Down
11 changes: 9 additions & 2 deletions artic/make_depth_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ def collect_depths(bamfile, refName, minDepth, ignoreDeletions, warnRGcov):

# generate the pileup
for pileupcolumn in bamFile.pileup(
refName, start=0, stop=bamFile.get_reference_length(refName), max_depth=10000, truncate=False, min_base_quality=0
refName,
start=0,
stop=bamFile.get_reference_length(refName),
max_depth=100000000,
truncate=False,
min_base_quality=0,
):

# process the pileup column
for pileupread in pileupcolumn.pileups:

Expand All @@ -78,13 +82,16 @@ def collect_depths(bamfile, refName, minDepth, ignoreDeletions, warnRGcov):
# process the pileup read
if pileupread.is_refskip:
continue

if pileupread.is_del:
if not ignoreDeletions:
depths[pileupcolumn.pos] += 1
rgDepths[rg][pileupcolumn.pos] += 1

elif not pileupread.is_del:
depths[pileupcolumn.pos] += 1
rgDepths[rg][pileupcolumn.pos] += 1

else:
raise Exception("unhandled pileup read encountered")

Expand Down
13 changes: 11 additions & 2 deletions artic/minion.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ def run(parser, args):
)
raise SystemExit(1)

if args.normalise > 10000:
print(
colored.red(
"--normalise appears to be an aribtrarily high value, if you wish to not normalise your BAM files set '--normalise 0' to disable normalisation entirely"
),
file=sys.stderr,
)
raise SystemExit(1)

if args.model_dir:
model_path = args.model_dir
else:
Expand Down Expand Up @@ -169,7 +178,7 @@ def run(parser, args):
cmds.append(f"samtools index {args.sample}.{p}.trimmed.rg.sorted.bam")

cmds.append(
f"run_clair3.sh --enable_long_indel --chunk_size=10000 --haploid_precise --no_phasing_for_fa --bam_fn='{args.sample}.{p}.trimmed.rg.sorted.bam' --ref_fn='{ref}' --output='{args.sample}_rg_{p}' --threads='{args.threads}' --platform='ont' --model_path='{full_model_path}' --include_all_ctgs --min_coverage='{args.min_depth}'"
f"run_clair3.sh --enable_long_indel --chunk_size=10000 --haploid_precise --no_phasing_for_fa --bam_fn='{args.sample}.{p}.trimmed.rg.sorted.bam' --ref_fn='{ref}' --output='{args.sample}_rg_{p}' --threads='{args.threads}' --platform='ont' --model_path='{full_model_path}' --include_all_ctgs"
)

cmds.append(
Expand Down Expand Up @@ -199,7 +208,7 @@ def run(parser, args):

# 9) get the depth of coverage for each readgroup, create a coverage mask and plots, and add failed variants to the coverage mask (artic_mask must be run before bcftools consensus)
cmds.append(
f"artic_make_depth_mask --store-rg-depths {ref} {args.sample}.primertrimmed.rg.sorted.bam {args.sample}.coverage_mask.txt"
f"artic_make_depth_mask --depth {args.min_depth} --store-rg-depths {ref} {args.sample}.primertrimmed.rg.sorted.bam {args.sample}.coverage_mask.txt"
)

cmds.append(
Expand Down
2 changes: 1 addition & 1 deletion artic/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def init_pipeline_parser():
"--min-depth",
type=int,
default=20,
help="Minimum depth required to call a variant (default: %(default)d)",
help="Minimum coverage required for a position to be included in the consensus sequence (default: %(default)d)",
)
parser_minion.add_argument(
"--threads",
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = artic
version = 1.6.0
version = 1.6.1
author = Nick Loman
author_email = [email protected]
maintainer = Sam Wilkinson
Expand Down

0 comments on commit 743d5d9

Please sign in to comment.