From ec4aaa5b1add2733c74eaeb9bb881034e702a916 Mon Sep 17 00:00:00 2001 From: Blaise Li <blaise.li__git@nsup.org> Date: Tue, 20 Apr 2021 11:42:07 +0200 Subject: [PATCH] Add tests of bed-shifting code. --- tests/data/bt1.bed | 10 +++ tests/data/shifted/m0/bt1.bed | 10 +++ tests/data/shifted/m1/bt1.bed | 10 +++ tests/data/shifted/m10/bt1.bed | 10 +++ tests/data/shifted/m11/bt1.bed | 10 +++ tests/data/shifted/m19/bt1.bed | 10 +++ tests/data/shifted/m20/bt1.bed | 10 +++ tests/data/shifted/m21/bt1.bed | 10 +++ tests/data/shifted/m4/bt1.bed | 10 +++ tests/data/shifted/m5/bt1.bed | 10 +++ tests/data/shifted/m6/bt1.bed | 10 +++ tests/data/shifted/m9/bt1.bed | 10 +++ tests/data/shifted/p0/bt1.bed | 10 +++ tests/data/shifted/p1/bt1.bed | 10 +++ tests/data/shifted/p10/bt1.bed | 10 +++ tests/data/shifted/p11/bt1.bed | 10 +++ tests/data/shifted/p19/bt1.bed | 10 +++ tests/data/shifted/p20/bt1.bed | 10 +++ tests/data/shifted/p21/bt1.bed | 10 +++ tests/data/shifted/p4/bt1.bed | 10 +++ tests/data/shifted/p5/bt1.bed | 10 +++ tests/data/shifted/p6/bt1.bed | 10 +++ tests/data/shifted/p9/bt1.bed | 10 +++ tests/test_bam25prime.py | 126 +++++++++++++++++++++++++++++++++ 24 files changed, 356 insertions(+) create mode 100644 tests/data/bt1.bed create mode 100644 tests/data/shifted/m0/bt1.bed create mode 100644 tests/data/shifted/m1/bt1.bed create mode 100644 tests/data/shifted/m10/bt1.bed create mode 100644 tests/data/shifted/m11/bt1.bed create mode 100644 tests/data/shifted/m19/bt1.bed create mode 100644 tests/data/shifted/m20/bt1.bed create mode 100644 tests/data/shifted/m21/bt1.bed create mode 100644 tests/data/shifted/m4/bt1.bed create mode 100644 tests/data/shifted/m5/bt1.bed create mode 100644 tests/data/shifted/m6/bt1.bed create mode 100644 tests/data/shifted/m9/bt1.bed create mode 100644 tests/data/shifted/p0/bt1.bed create mode 100644 tests/data/shifted/p1/bt1.bed create mode 100644 tests/data/shifted/p10/bt1.bed create mode 100644 tests/data/shifted/p11/bt1.bed create mode 100644 tests/data/shifted/p19/bt1.bed create mode 100644 tests/data/shifted/p20/bt1.bed create mode 100644 tests/data/shifted/p21/bt1.bed create mode 100644 tests/data/shifted/p4/bt1.bed create mode 100644 tests/data/shifted/p5/bt1.bed create mode 100644 tests/data/shifted/p6/bt1.bed create mode 100644 tests/data/shifted/p9/bt1.bed create mode 100755 tests/test_bam25prime.py diff --git a/tests/data/bt1.bed b/tests/data/bt1.bed new file mode 100644 index 0000000..1ae9665 --- /dev/null +++ b/tests/data/bt1.bed @@ -0,0 +1,10 @@ +I 0 5 a(I:0-5:+) . + +I 0 5 b(I:0-5:-) . - +I 0 10 c(I:0-10:+) . + +I 0 10 d(I:0-10:-) . - +I 5 10 e(I:5-10:+) . + +I 5 10 f(I:5-10:-) . - +I 5 20 g(I:5-20:+) . + +I 5 20 h(I:5-20:-) . - +I 10 15 i(I:10-15:+) . + +I 10 15 j(I:10-15:-) . - diff --git a/tests/data/shifted/m0/bt1.bed b/tests/data/shifted/m0/bt1.bed new file mode 100644 index 0000000..1ae9665 --- /dev/null +++ b/tests/data/shifted/m0/bt1.bed @@ -0,0 +1,10 @@ +I 0 5 a(I:0-5:+) . + +I 0 5 b(I:0-5:-) . - +I 0 10 c(I:0-10:+) . + +I 0 10 d(I:0-10:-) . - +I 5 10 e(I:5-10:+) . + +I 5 10 f(I:5-10:-) . - +I 5 20 g(I:5-20:+) . + +I 5 20 h(I:5-20:-) . - +I 10 15 i(I:10-15:+) . + +I 10 15 j(I:10-15:-) . - diff --git a/tests/data/shifted/m1/bt1.bed b/tests/data/shifted/m1/bt1.bed new file mode 100644 index 0000000..9e73706 --- /dev/null +++ b/tests/data/shifted/m1/bt1.bed @@ -0,0 +1,10 @@ +#I -1 4 a(I:0-5:+) . + +I 1 6 b(I:0-5:-) . - +#I -1 9 c(I:0-10:+) . + +I 1 11 d(I:0-10:-) . - +I 4 9 e(I:5-10:+) . + +I 6 11 f(I:5-10:-) . - +I 4 19 g(I:5-20:+) . + +I 6 21 h(I:5-20:-) . - +I 9 14 i(I:10-15:+) . + +I 11 16 j(I:10-15:-) . - diff --git a/tests/data/shifted/m10/bt1.bed b/tests/data/shifted/m10/bt1.bed new file mode 100644 index 0000000..30fc82f --- /dev/null +++ b/tests/data/shifted/m10/bt1.bed @@ -0,0 +1,10 @@ +#I -10 -5 a(I:0-5:+) . + +I 10 15 b(I:0-5:-) . - +#I -10 0 c(I:0-10:+) . + +I 10 20 d(I:0-10:-) . - +#I -5 0 e(I:5-10:+) . + +I 15 20 f(I:5-10:-) . - +#I -5 10 g(I:5-20:+) . + +I 15 30 h(I:5-20:-) . - +I 0 5 i(I:10-15:+) . + +I 20 25 j(I:10-15:-) . - diff --git a/tests/data/shifted/m11/bt1.bed b/tests/data/shifted/m11/bt1.bed new file mode 100644 index 0000000..6279924 --- /dev/null +++ b/tests/data/shifted/m11/bt1.bed @@ -0,0 +1,10 @@ +#I -11 -6 a(I:0-5:+) . + +I 11 16 b(I:0-5:-) . - +#I -11 -1 c(I:0-10:+) . + +I 11 21 d(I:0-10:-) . - +#I -6 -1 e(I:5-10:+) . + +I 16 21 f(I:5-10:-) . - +#I -6 9 g(I:5-20:+) . + +I 16 31 h(I:5-20:-) . - +#I -1 4 i(I:10-15:+) . + +I 21 26 j(I:10-15:-) . - diff --git a/tests/data/shifted/m19/bt1.bed b/tests/data/shifted/m19/bt1.bed new file mode 100644 index 0000000..ea3b922 --- /dev/null +++ b/tests/data/shifted/m19/bt1.bed @@ -0,0 +1,10 @@ +#I -19 -14 a(I:0-5:+) . + +I 19 24 b(I:0-5:-) . - +#I -19 -9 c(I:0-10:+) . + +I 19 29 d(I:0-10:-) . - +#I -14 -9 e(I:5-10:+) . + +I 24 29 f(I:5-10:-) . - +#I -14 1 g(I:5-20:+) . + +I 24 39 h(I:5-20:-) . - +#I -9 -4 i(I:10-15:+) . + +I 29 34 j(I:10-15:-) . - diff --git a/tests/data/shifted/m20/bt1.bed b/tests/data/shifted/m20/bt1.bed new file mode 100644 index 0000000..4ad9d02 --- /dev/null +++ b/tests/data/shifted/m20/bt1.bed @@ -0,0 +1,10 @@ +#I -20 -15 a(I:0-5:+) . + +I 20 25 b(I:0-5:-) . - +#I -20 -10 c(I:0-10:+) . + +I 20 30 d(I:0-10:-) . - +#I -15 -10 e(I:5-10:+) . + +I 25 30 f(I:5-10:-) . - +#I -15 0 g(I:5-20:+) . + +I 25 40 h(I:5-20:-) . - +#I -10 -5 i(I:10-15:+) . + +I 30 35 j(I:10-15:-) . - diff --git a/tests/data/shifted/m21/bt1.bed b/tests/data/shifted/m21/bt1.bed new file mode 100644 index 0000000..a0a6754 --- /dev/null +++ b/tests/data/shifted/m21/bt1.bed @@ -0,0 +1,10 @@ +#I -21 -16 a(I:0-5:+) . + +I 21 26 b(I:0-5:-) . - +#I -21 -11 c(I:0-10:+) . + +I 21 31 d(I:0-10:-) . - +#I -16 -11 e(I:5-10:+) . + +I 26 31 f(I:5-10:-) . - +#I -16 -1 g(I:5-20:+) . + +I 26 41 h(I:5-20:-) . - +#I -11 -6 i(I:10-15:+) . + +I 31 36 j(I:10-15:-) . - diff --git a/tests/data/shifted/m4/bt1.bed b/tests/data/shifted/m4/bt1.bed new file mode 100644 index 0000000..d96672e --- /dev/null +++ b/tests/data/shifted/m4/bt1.bed @@ -0,0 +1,10 @@ +#I -4 1 a(I:0-5:+) . + +I 4 9 b(I:0-5:-) . - +#I -4 6 c(I:0-10:+) . + +I 4 14 d(I:0-10:-) . - +I 1 6 e(I:5-10:+) . + +I 9 14 f(I:5-10:-) . - +I 1 16 g(I:5-20:+) . + +I 9 24 h(I:5-20:-) . - +I 6 11 i(I:10-15:+) . + +I 14 19 j(I:10-15:-) . - diff --git a/tests/data/shifted/m5/bt1.bed b/tests/data/shifted/m5/bt1.bed new file mode 100644 index 0000000..b7c4094 --- /dev/null +++ b/tests/data/shifted/m5/bt1.bed @@ -0,0 +1,10 @@ +#I -5 0 a(I:0-5:+) . + +I 5 10 b(I:0-5:-) . - +#I -5 5 c(I:0-10:+) . + +I 5 15 d(I:0-10:-) . - +I 0 5 e(I:5-10:+) . + +I 10 15 f(I:5-10:-) . - +I 0 15 g(I:5-20:+) . + +I 10 25 h(I:5-20:-) . - +I 5 10 i(I:10-15:+) . + +I 15 20 j(I:10-15:-) . - diff --git a/tests/data/shifted/m6/bt1.bed b/tests/data/shifted/m6/bt1.bed new file mode 100644 index 0000000..da19eec --- /dev/null +++ b/tests/data/shifted/m6/bt1.bed @@ -0,0 +1,10 @@ +#I -6 -1 a(I:0-5:+) . + +I 6 11 b(I:0-5:-) . - +#I -6 4 c(I:0-10:+) . + +I 6 16 d(I:0-10:-) . - +#I -1 4 e(I:5-10:+) . + +I 11 16 f(I:5-10:-) . - +#I -1 14 g(I:5-20:+) . + +I 11 26 h(I:5-20:-) . - +I 4 9 i(I:10-15:+) . + +I 16 21 j(I:10-15:-) . - diff --git a/tests/data/shifted/m9/bt1.bed b/tests/data/shifted/m9/bt1.bed new file mode 100644 index 0000000..9d7fecb --- /dev/null +++ b/tests/data/shifted/m9/bt1.bed @@ -0,0 +1,10 @@ +#I -9 -4 a(I:0-5:+) . + +I 9 14 b(I:0-5:-) . - +#I -9 1 c(I:0-10:+) . + +I 9 19 d(I:0-10:-) . - +#I -4 1 e(I:5-10:+) . + +I 14 19 f(I:5-10:-) . - +#I -4 11 g(I:5-20:+) . + +I 14 29 h(I:5-20:-) . - +I 1 6 i(I:10-15:+) . + +I 19 24 j(I:10-15:-) . - diff --git a/tests/data/shifted/p0/bt1.bed b/tests/data/shifted/p0/bt1.bed new file mode 100644 index 0000000..1ae9665 --- /dev/null +++ b/tests/data/shifted/p0/bt1.bed @@ -0,0 +1,10 @@ +I 0 5 a(I:0-5:+) . + +I 0 5 b(I:0-5:-) . - +I 0 10 c(I:0-10:+) . + +I 0 10 d(I:0-10:-) . - +I 5 10 e(I:5-10:+) . + +I 5 10 f(I:5-10:-) . - +I 5 20 g(I:5-20:+) . + +I 5 20 h(I:5-20:-) . - +I 10 15 i(I:10-15:+) . + +I 10 15 j(I:10-15:-) . - diff --git a/tests/data/shifted/p1/bt1.bed b/tests/data/shifted/p1/bt1.bed new file mode 100644 index 0000000..4371a2c --- /dev/null +++ b/tests/data/shifted/p1/bt1.bed @@ -0,0 +1,10 @@ +I 1 6 a(I:0-5:+) . + +#I -1 4 b(I:0-5:-) . - +I 1 11 c(I:0-10:+) . + +#I -1 9 d(I:0-10:-) . - +I 6 11 e(I:5-10:+) . + +I 4 9 f(I:5-10:-) . - +I 6 21 g(I:5-20:+) . + +I 4 19 h(I:5-20:-) . - +I 11 16 i(I:10-15:+) . + +I 9 14 j(I:10-15:-) . - diff --git a/tests/data/shifted/p10/bt1.bed b/tests/data/shifted/p10/bt1.bed new file mode 100644 index 0000000..5e85143 --- /dev/null +++ b/tests/data/shifted/p10/bt1.bed @@ -0,0 +1,10 @@ +I 10 15 a(I:0-5:+) . + +#I -10 -5 b(I:0-5:-) . - +I 10 20 c(I:0-10:+) . + +#I -10 0 d(I:0-10:-) . - +I 15 20 e(I:5-10:+) . + +#I -5 0 f(I:5-10:-) . - +I 15 30 g(I:5-20:+) . + +#I -5 10 h(I:5-20:-) . - +I 20 25 i(I:10-15:+) . + +I 0 5 j(I:10-15:-) . - diff --git a/tests/data/shifted/p11/bt1.bed b/tests/data/shifted/p11/bt1.bed new file mode 100644 index 0000000..761e685 --- /dev/null +++ b/tests/data/shifted/p11/bt1.bed @@ -0,0 +1,10 @@ +I 11 16 a(I:0-5:+) . + +#I -11 -6 b(I:0-5:-) . - +I 11 21 c(I:0-10:+) . + +#I -11 -1 d(I:0-10:-) . - +I 16 21 e(I:5-10:+) . + +#I -6 1 f(I:5-10:-) . - +I 16 31 g(I:5-20:+) . + +#I -6 9 h(I:5-20:-) . - +I 21 26 i(I:10-15:+) . + +#I -1 4 j(I:10-15:-) . - diff --git a/tests/data/shifted/p19/bt1.bed b/tests/data/shifted/p19/bt1.bed new file mode 100644 index 0000000..d80bd8b --- /dev/null +++ b/tests/data/shifted/p19/bt1.bed @@ -0,0 +1,10 @@ +I 19 24 a(I:0-5:+) . + +#I -19 -14 b(I:0-5:-) . - +I 19 29 c(I:0-10:+) . + +#I -19 -9 d(I:0-10:-) . - +I 24 29 e(I:5-10:+) . + +#I -14 -9 f(I:5-10:-) . - +I 24 39 g(I:5-20:+) . + +#I -14 1 h(I:5-20:-) . - +I 29 34 i(I:10-15:+) . + +#I -9 -4 j(I:10-15:-) . - diff --git a/tests/data/shifted/p20/bt1.bed b/tests/data/shifted/p20/bt1.bed new file mode 100644 index 0000000..d72aaae --- /dev/null +++ b/tests/data/shifted/p20/bt1.bed @@ -0,0 +1,10 @@ +I 20 25 a(I:0-5:+) . + +#I -20 -15 b(I:0-5:-) . - +I 20 30 c(I:0-10:+) . + +#I -20 -10 d(I:0-10:-) . - +I 25 30 e(I:5-10:+) . + +#I -15 -10 f(I:5-10:-) . - +I 25 40 g(I:5-20:+) . + +#I -15 0 h(I:5-20:-) . - +I 30 35 i(I:10-15:+) . + +#I -10 -5 j(I:10-15:-) . - diff --git a/tests/data/shifted/p21/bt1.bed b/tests/data/shifted/p21/bt1.bed new file mode 100644 index 0000000..6cafac3 --- /dev/null +++ b/tests/data/shifted/p21/bt1.bed @@ -0,0 +1,10 @@ +I 21 26 a(I:0-5:+) . + +#I -21 -16 b(I:0-5:-) . - +I 21 31 c(I:0-10:+) . + +#I -21 -11 d(I:0-10:-) . - +I 26 31 e(I:5-10:+) . + +#I -16 -11 f(I:5-10:-) . - +I 26 41 g(I:5-20:+) . + +#I -16 -1 h(I:5-20:-) . - +I 31 36 i(I:10-15:+) . + +#I -11 -6 j(I:10-15:-) . - diff --git a/tests/data/shifted/p4/bt1.bed b/tests/data/shifted/p4/bt1.bed new file mode 100644 index 0000000..6c26b23 --- /dev/null +++ b/tests/data/shifted/p4/bt1.bed @@ -0,0 +1,10 @@ +I 4 9 a(I:0-5:+) . + +#I -4 1 b(I:0-5:-) . - +I 4 14 c(I:0-10:+) . + +#I -4 6 d(I:0-10:-) . - +I 9 14 e(I:5-10:+) . + +I 1 6 f(I:5-10:-) . - +I 9 24 g(I:5-20:+) . + +I 1 16 h(I:5-20:-) . - +I 14 19 i(I:10-15:+) . + +I 6 11 j(I:10-15:-) . - diff --git a/tests/data/shifted/p5/bt1.bed b/tests/data/shifted/p5/bt1.bed new file mode 100644 index 0000000..db85793 --- /dev/null +++ b/tests/data/shifted/p5/bt1.bed @@ -0,0 +1,10 @@ +I 5 10 a(I:0-5:+) . + +#I -5 0 b(I:0-5:-) . - +I 5 15 c(I:0-10:+) . + +#I -5 5 d(I:0-10:-) . - +I 10 15 e(I:5-10:+) . + +I 0 5 f(I:5-10:-) . - +I 10 25 g(I:5-20:+) . + +I 0 15 h(I:5-20:-) . - +I 15 20 i(I:10-15:+) . + +I 5 10 j(I:10-15:-) . - diff --git a/tests/data/shifted/p6/bt1.bed b/tests/data/shifted/p6/bt1.bed new file mode 100644 index 0000000..fce8c22 --- /dev/null +++ b/tests/data/shifted/p6/bt1.bed @@ -0,0 +1,10 @@ +I 6 11 a(I:0-5:+) . + +#I -6 -1 b(I:0-5:-) . - +I 6 16 c(I:0-10:+) . + +#I -6 4 d(I:0-10:-) . - +I 11 16 e(I:5-10:+) . + +#I -1 4 f(I:5-10:-) . - +I 11 26 g(I:5-20:+) . + +#I -1 14 h(I:5-20:-) . - +I 16 21 i(I:10-15:+) . + +I 4 9 j(I:10-15:-) . - diff --git a/tests/data/shifted/p9/bt1.bed b/tests/data/shifted/p9/bt1.bed new file mode 100644 index 0000000..26dc925 --- /dev/null +++ b/tests/data/shifted/p9/bt1.bed @@ -0,0 +1,10 @@ +I 9 14 a(I:0-5:+) . + +#I -9 -4 b(I:0-5:-) . - +I 9 19 c(I:0-10:+) . + +#I -9 1 d(I:0-10:-) . - +I 14 19 e(I:5-10:+) . + +#I -4 1 f(I:5-10:-) . - +I 14 29 g(I:5-20:+) . + +#I -4 11 h(I:5-20:-) . - +I 19 24 i(I:10-15:+) . + +I 1 6 j(I:10-15:-) . - diff --git a/tests/test_bam25prime.py b/tests/test_bam25prime.py new file mode 100755 index 0000000..e2c76b3 --- /dev/null +++ b/tests/test_bam25prime.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +""" +Test cases for bam25prime. +""" + +import unittest +from collections import namedtuple +from pathlib import Path +from bam25prime import ( + BedTool, make_bed_shifter, make_bed_shift_checker) + + +Interval = namedtuple("Interval", ["chrom", "start", "stop", "strand"]) + +THIS_DIR = Path("__file__").resolve().parent +data_dir = THIS_DIR.joinpath("data") + + +def load_interval_dict(bed_path): + """ + Build a dict to store intervals allowing easy comparison between + obtained and expected results using bed names (4th column) as keys. + """ + itvl_dict = {} + with open(bed_path) as fh: + for line in fh: + if len(line.strip()) == 0 or line[0] == "#": + continue + ( + chrom, start, stop, + name, _, strand, *_) = line.strip().split("\t") + assert name not in itvl_dict, f"Non unique name: {name}" + itvl_dict[name] = Interval( + chrom, int(start), int(stop), strand) + return itvl_dict + + +def compare_itvl_dicts(observed, expected): + """ + Compute the sets of interval names: + * missing in the observed + * spurious in the observed + * different in the observed + Return a (missing, spurious, different) tuple. + """ + obs_names = set(observed.keys()) + exp_names = set(expected.keys()) + missing = exp_names - obs_names + spurious = obs_names - exp_names + common = obs_names & exp_names + different = set() + for itvl_name in common: + if observed[itvl_name] != expected[itvl_name]: + different.add(itvl_name) + return (missing, spurious, different) + + +def check_shifter(bed_path, s_name, shifter, checker): + bt = BedTool(bed_path) + bed_name = bed_path.stem + msg_base = f"{bed_name} transformed with {s_name}" + print(msg_base) + expected = load_interval_dict( + data_dir.joinpath("shifted", s_name, f"{bed_name}.bed")) + #print("bt") + #print(bt) + #print(bt) + #shifted_1 = bt.each(shifter).saveas() + #print(" shifted") + #print(shifted_1) + #print(shifted_1) + #shifted_2 = shifted_1.remove_invalid().saveas() + shifted_2 = bt.filter(checker).each(shifter).remove_invalid().saveas() + #print(" invalid removed") + #print(shifted_2) + #print(shifted_2) + shifted = shifted_2.sort() + #print(" sorted") + #print(shifted) + #print(shifted) + observed = load_interval_dict(shifted.fn) + #print(observed) + (missing, spurious, different) = compare_itvl_dicts( + observed, expected) + msg = "\n".join([ + msg_base, + f"\tMissing: {missing}", + f"\tSpurious: {spurious}", + f"\tDifferent: {different}"]) + return (missing, spurious, different, msg) + + +class TestBam25prime(unittest.TestCase): + def test_shift_pos(self): + shifters = { + f"p{shift}": ( + make_bed_shifter(shift), + make_bed_shift_checker(shift)) + for shift in [0, 1, 4, 5, 6, 9, 10, 11, 19, 20, 21] + } + for bed_path in data_dir.glob("*.bed"): + for (s_name, (shifter, checker)) in shifters.items(): + (missing, spurious, different, msg) = check_shifter( + bed_path, s_name, shifter, checker) + self.assertFalse( + missing | spurious | different, + msg) + + def test_shift_neg(self): + shifters = { + f"m{shift}": ( + make_bed_shifter(-shift), + make_bed_shift_checker(-shift)) + for shift in [0, 1, 4, 5, 6, 9, 10, 11, 19, 20, 21] + } + for bed_path in data_dir.glob("*.bed"): + for (s_name, (shifter, checker)) in shifters.items(): + (missing, spurious, different, msg) = check_shifter( + bed_path, s_name, shifter, checker) + self.assertFalse( + missing | spurious | different, + msg) + + +if __name__ == "__main__": + unittest.main() -- GitLab