loqusdb 2.7.2__py3-none-any.whl → 2.7.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- README.md +148 -0
- loqusdb/__init__.py +5 -3
- loqusdb/__main__.py +0 -0
- loqusdb/build_models/variant.py +12 -4
- loqusdb/commands/export.py +3 -4
- loqusdb/commands/identity.py +3 -4
- loqusdb/commands/view.py +5 -2
- loqusdb/plugins/mongo/case.py +3 -10
- loqusdb/resources/loqusdb.20181005.gz +0 -0
- loqusdb/resources/maf_50_sites_GRCh37.vcf.gz +0 -0
- loqusdb/resources/maf_50_sites_GRCh38.vcf.gz +0 -0
- {loqusdb-2.7.2.dist-info → loqusdb-2.7.8.dist-info}/METADATA +27 -42
- loqusdb-2.7.8.dist-info/RECORD +97 -0
- {loqusdb-2.7.2.dist-info → loqusdb-2.7.8.dist-info}/WHEEL +1 -2
- loqusdb-2.7.8.dist-info/entry_points.txt +3 -0
- tests/build_models/test_build_case.py +150 -0
- tests/build_models/test_build_variant.py +15 -0
- tests/build_models/test_is_greater.py +49 -0
- tests/commands/test_export.py +16 -0
- tests/commands/test_identity.py +22 -0
- tests/commands/test_view.py +17 -0
- tests/conftest.py +438 -0
- tests/fixtures/643594.clinical.SV.vcf +178 -0
- tests/fixtures/643594.clinical.vcf.gz +0 -0
- tests/fixtures/double_variant.vcf +21 -0
- tests/fixtures/funny_trio.ped +4 -0
- tests/fixtures/profile_snv.vcf +47 -0
- tests/fixtures/recessive_trio.ped +4 -0
- tests/fixtures/test.SV.vcf +178 -0
- tests/fixtures/test.vcf +26 -0
- tests/fixtures/test.vcf.gz +0 -0
- tests/fixtures/test.vcf.gz.tbi +0 -0
- tests/fixtures/unsorted.vcf +20 -0
- tests/functional/test_cli.py +213 -0
- tests/plugins/mongo/test_case_operations.py +143 -0
- tests/plugins/mongo/test_connect.py +8 -0
- tests/plugins/mongo/test_flask_extension.py +27 -0
- tests/plugins/mongo/test_get_sv.py +27 -0
- tests/plugins/mongo/test_load_svs.py +74 -0
- tests/plugins/mongo/test_variant_operations.py +278 -0
- tests/utils/test_case.py +34 -0
- tests/utils/test_delete.py +73 -0
- tests/utils/test_delete_family.py +30 -0
- tests/utils/test_delete_variant.py +74 -0
- tests/utils/test_get_family.py +13 -0
- tests/utils/test_load_database.py +52 -0
- tests/utils/test_load_family.py +69 -0
- tests/utils/test_load_variants.py +225 -0
- tests/utils/test_migrate.py +38 -0
- tests/utils/test_profiling.py +68 -0
- tests/vcf_tools/test_check_par.py +67 -0
- tests/vcf_tools/test_check_vcf.py +64 -0
- tests/vcf_tools/test_format_sv_variant.py +102 -0
- tests/vcf_tools/test_format_variant.py +113 -0
- tests/vcf_tools/test_vcf.py +63 -0
- loqusdb-2.7.2.dist-info/RECORD +0 -54
- loqusdb-2.7.2.dist-info/entry_points.txt +0 -3
- loqusdb-2.7.2.dist-info/top_level.txt +0 -1
- {loqusdb-2.7.2.dist-info → loqusdb-2.7.8.dist-info}/LICENSE +0 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from loqusdb.build_models.case import build_case, get_individual_positions
|
4
|
+
from loqusdb.exceptions import CaseError
|
5
|
+
|
6
|
+
|
7
|
+
def test_get_individual_positions():
|
8
|
+
## GIVEN a list with ids
|
9
|
+
inds = ["1", "2", "3"]
|
10
|
+
## WHEN getting the individual positions
|
11
|
+
ind_pos = get_individual_positions(inds)
|
12
|
+
## THEN assert they where given the correct position
|
13
|
+
assert ind_pos["1"] == 0
|
14
|
+
assert ind_pos["2"] == 1
|
15
|
+
assert ind_pos["3"] == 2
|
16
|
+
|
17
|
+
|
18
|
+
def test_get_individual_positions_no_inds():
|
19
|
+
## GIVEN a list with ids
|
20
|
+
inds = None
|
21
|
+
## WHEN getting the individual positions
|
22
|
+
ind_pos = get_individual_positions(inds)
|
23
|
+
## THEN assert an empty dict is returned
|
24
|
+
assert ind_pos == {}
|
25
|
+
|
26
|
+
|
27
|
+
def test_build_case_no_ped():
|
28
|
+
## GIVEN some vcf individuals
|
29
|
+
|
30
|
+
vcf_individuals = ["mother", "proband"]
|
31
|
+
case_id = "test"
|
32
|
+
|
33
|
+
## WHEN building a case object
|
34
|
+
case_obj = build_case(
|
35
|
+
case=None,
|
36
|
+
vcf_individuals=vcf_individuals,
|
37
|
+
case_id=case_id,
|
38
|
+
)
|
39
|
+
|
40
|
+
## THEN assert that the case got the right ID
|
41
|
+
assert case_obj["case_id"] == case_id
|
42
|
+
for ind_obj in case_obj["individuals"]:
|
43
|
+
assert ind_obj["name"] in vcf_individuals
|
44
|
+
assert ind_obj["ind_id"] in vcf_individuals
|
45
|
+
|
46
|
+
|
47
|
+
def test_build_case_no_ped_no_case_id():
|
48
|
+
## WHEN building a case object
|
49
|
+
|
50
|
+
## THEN assert a CaseError is raised
|
51
|
+
with pytest.raises(CaseError):
|
52
|
+
## GIVEN some vcf individuals
|
53
|
+
|
54
|
+
vcf_individuals = ["mother", "proband"]
|
55
|
+
|
56
|
+
case_obj = build_case(
|
57
|
+
case=None,
|
58
|
+
vcf_individuals=vcf_individuals,
|
59
|
+
)
|
60
|
+
|
61
|
+
|
62
|
+
def test_build_case_ped(family_obj, vcf_path):
|
63
|
+
## GIVEN a ped parser family_obj
|
64
|
+
vcf_inds = [ind_id for ind_id in family_obj.individuals]
|
65
|
+
nr_variants = 10
|
66
|
+
|
67
|
+
## WHEN building a case object
|
68
|
+
case_obj = build_case(
|
69
|
+
case=family_obj,
|
70
|
+
vcf_individuals=vcf_inds,
|
71
|
+
vcf_path=vcf_path,
|
72
|
+
nr_variants=nr_variants,
|
73
|
+
)
|
74
|
+
|
75
|
+
## THEN assert that the case has the correct id
|
76
|
+
assert case_obj["case_id"] == family_obj.family_id
|
77
|
+
|
78
|
+
for ind_obj in case_obj["individuals"]:
|
79
|
+
assert ind_obj["ind_id"] in vcf_inds
|
80
|
+
|
81
|
+
## THEN assert that the vcf_path was added
|
82
|
+
assert case_obj["vcf_path"] == vcf_path
|
83
|
+
|
84
|
+
## THEN assert that the nr variants is correct
|
85
|
+
assert case_obj["nr_variants"] == nr_variants
|
86
|
+
|
87
|
+
|
88
|
+
def test_build_case_ped_sv(family_obj, sv_vcf_path):
|
89
|
+
## GIVEN a ped parser family_obj
|
90
|
+
vcf_inds = [ind_id for ind_id in family_obj.individuals]
|
91
|
+
nr_sv_variants = 10
|
92
|
+
|
93
|
+
## WHEN building a case object
|
94
|
+
case_obj = build_case(
|
95
|
+
case=family_obj,
|
96
|
+
sv_individuals=vcf_inds,
|
97
|
+
vcf_sv_path=sv_vcf_path,
|
98
|
+
nr_sv_variants=nr_sv_variants,
|
99
|
+
)
|
100
|
+
|
101
|
+
## THEN assert that the case has the correct id
|
102
|
+
assert case_obj["case_id"] == family_obj.family_id
|
103
|
+
|
104
|
+
case_obj["individuals"] == []
|
105
|
+
for ind_obj in case_obj["sv_individuals"]:
|
106
|
+
assert ind_obj["ind_id"] in vcf_inds
|
107
|
+
|
108
|
+
## THEN assert that the vcf_path was added
|
109
|
+
assert case_obj["vcf_path"] is None
|
110
|
+
assert case_obj["vcf_sv_path"] == sv_vcf_path
|
111
|
+
|
112
|
+
## THEN assert that the nr variants is correct
|
113
|
+
assert case_obj["nr_variants"] is None
|
114
|
+
assert case_obj["nr_sv_variants"] == nr_sv_variants
|
115
|
+
|
116
|
+
|
117
|
+
def test_build_case_ped_sv_and_snv(family_obj, sv_vcf_path, vcf_path):
|
118
|
+
## GIVEN a ped parser family_obj
|
119
|
+
vcf_inds = [ind_id for ind_id in family_obj.individuals]
|
120
|
+
sv_vcf_inds = [ind_id for ind_id in family_obj.individuals]
|
121
|
+
nr_sv_variants = 10
|
122
|
+
nr_variants = 20
|
123
|
+
|
124
|
+
## WHEN building a case object
|
125
|
+
case_obj = build_case(
|
126
|
+
case=family_obj,
|
127
|
+
sv_individuals=vcf_inds,
|
128
|
+
vcf_sv_path=sv_vcf_path,
|
129
|
+
nr_sv_variants=nr_sv_variants,
|
130
|
+
vcf_individuals=vcf_inds,
|
131
|
+
vcf_path=vcf_path,
|
132
|
+
nr_variants=nr_variants,
|
133
|
+
)
|
134
|
+
|
135
|
+
## THEN assert that the case has the correct id
|
136
|
+
assert case_obj["case_id"] == family_obj.family_id
|
137
|
+
|
138
|
+
for ind_obj in case_obj["individuals"]:
|
139
|
+
assert ind_obj["ind_id"] in vcf_inds
|
140
|
+
|
141
|
+
for ind_obj in case_obj["sv_individuals"]:
|
142
|
+
assert ind_obj["ind_id"] in sv_vcf_inds
|
143
|
+
|
144
|
+
## THEN assert that the vcf_path was added
|
145
|
+
assert case_obj["vcf_path"] == vcf_path
|
146
|
+
assert case_obj["vcf_sv_path"] == sv_vcf_path
|
147
|
+
|
148
|
+
## THEN assert that the nr variants is correct
|
149
|
+
assert case_obj["nr_variants"] == nr_variants
|
150
|
+
assert case_obj["nr_sv_variants"] == nr_sv_variants
|
@@ -0,0 +1,15 @@
|
|
1
|
+
from loqusdb.build_models.variant import get_coords, build_variant
|
2
|
+
|
3
|
+
|
4
|
+
def test_build_het_variant(het_variant, case_obj):
|
5
|
+
variant_obj = build_variant(variant=het_variant, case_obj=case_obj)
|
6
|
+
assert variant_obj["chrom"] == het_variant.CHROM
|
7
|
+
assert variant_obj["homozygote"] == 0
|
8
|
+
assert variant_obj["hemizygote"] == 0
|
9
|
+
|
10
|
+
|
11
|
+
def test_get_coords_for_BND(bnd_variant):
|
12
|
+
coords = get_coords(bnd_variant)
|
13
|
+
assert coords["pos"] == coords["end"]
|
14
|
+
assert coords["sv_length"] == float("inf")
|
15
|
+
assert coords["sv_type"] == "BND"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from loqusdb.build_models.variant import Position, is_greater
|
2
|
+
|
3
|
+
|
4
|
+
def test_is_greater_different_chrom():
|
5
|
+
## GIVEN two positions where a is smaller than b. Different chroms
|
6
|
+
a = Position("1", 100)
|
7
|
+
b = Position("3", 100)
|
8
|
+
|
9
|
+
## WHEN testing if a is greater than b
|
10
|
+
res = is_greater(a, b)
|
11
|
+
## THEN assert a was not greater than b
|
12
|
+
assert res is False
|
13
|
+
|
14
|
+
## WHEN testing if b is greater than a
|
15
|
+
res = is_greater(b, a)
|
16
|
+
## THEN assert b was greater than a
|
17
|
+
assert res is True
|
18
|
+
|
19
|
+
|
20
|
+
def test_is_greater_same_chrom():
|
21
|
+
## GIVEN two positions where a is smaller than b. Same chroms
|
22
|
+
a = Position("1", 100)
|
23
|
+
b = Position("1", 300)
|
24
|
+
|
25
|
+
## WHEN testing if a is greater than b
|
26
|
+
res = is_greater(a, b)
|
27
|
+
## THEN assert a was not greater than b
|
28
|
+
assert res is False
|
29
|
+
|
30
|
+
## WHEN testing if b is greater than a
|
31
|
+
res = is_greater(b, a)
|
32
|
+
## THEN assert b was greater than a
|
33
|
+
assert res is True
|
34
|
+
|
35
|
+
|
36
|
+
def test_is_greater_wierd_chrom():
|
37
|
+
## GIVEN two positions where one chrom is unknown b
|
38
|
+
a = Position("1", 100)
|
39
|
+
b = Position("GRLrs2", 300)
|
40
|
+
|
41
|
+
## WHEN testing if a is greater than b
|
42
|
+
res = is_greater(a, b)
|
43
|
+
## THEN assert a was not greater than b
|
44
|
+
assert res is False
|
45
|
+
|
46
|
+
## WHEN testing if b is greater than a
|
47
|
+
res = is_greater(b, a)
|
48
|
+
## THEN assert a was not greater than b
|
49
|
+
assert res is False
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from click.testing import CliRunner
|
2
|
+
|
3
|
+
from loqusdb.commands.cli import cli as base_command
|
4
|
+
|
5
|
+
def test_export_base(real_db_name:str):
|
6
|
+
"""Test the base command that exports variants."""
|
7
|
+
|
8
|
+
runner = CliRunner()
|
9
|
+
|
10
|
+
# WHEN the base command to export cases is run
|
11
|
+
command = ["--database", real_db_name, "export"]
|
12
|
+
|
13
|
+
## THEN it should return success
|
14
|
+
result = runner.invoke(base_command, command)
|
15
|
+
assert result.exit_code == 0
|
16
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from click.testing import CliRunner
|
2
|
+
|
3
|
+
from loqusdb.commands.cli import cli as base_command
|
4
|
+
|
5
|
+
def test_identity(real_db_name:str):
|
6
|
+
"""Test the SV identity base command."""
|
7
|
+
|
8
|
+
runner = CliRunner()
|
9
|
+
|
10
|
+
# WHEN the base identity command is run on an empty database
|
11
|
+
command = ["--database", real_db_name, "identity", "-v", "1_7890024_TGA_GGG"]
|
12
|
+
|
13
|
+
# THEN the command should return success
|
14
|
+
result = runner.invoke(base_command, command)
|
15
|
+
assert result.exit_code == 0
|
16
|
+
|
17
|
+
# AND no variant found message
|
18
|
+
assert "No hits for variant" in result.output
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from click.testing import CliRunner
|
2
|
+
from loqusdb.plugins.mongo.adapter import MongoAdapter
|
3
|
+
from loqusdb.commands.cli import cli as base_command
|
4
|
+
|
5
|
+
def test_view_cases_base(real_mongo_adapter: MongoAdapter, real_db_name:str):
|
6
|
+
"""Test the base command that returns database cases."""
|
7
|
+
|
8
|
+
## GIVEN an empty database
|
9
|
+
assert sum([1 for _ in real_mongo_adapter.cases()]) == 0
|
10
|
+
|
11
|
+
runner = CliRunner()
|
12
|
+
|
13
|
+
# THEN the case command should return No cases found error
|
14
|
+
command = ["--database", real_db_name, "cases" ]
|
15
|
+
result = runner.invoke(base_command, command)
|
16
|
+
assert result.exit_code == 1
|
17
|
+
assert "No cases found in database" in result.output
|
tests/conftest.py
ADDED
@@ -0,0 +1,438 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
import cyvcf2
|
4
|
+
import pytest
|
5
|
+
|
6
|
+
from loqusdb.build_models.case import build_case
|
7
|
+
from loqusdb.build_models.variant import build_variant
|
8
|
+
from loqusdb.log import init_log
|
9
|
+
from loqusdb.models import Case
|
10
|
+
from loqusdb.plugins.mongo.adapter import MongoAdapter
|
11
|
+
from loqusdb.utils.load import update_case
|
12
|
+
from mongomock import MongoClient as MockClient
|
13
|
+
from ped_parser import FamilyParser
|
14
|
+
from pymongo import MongoClient
|
15
|
+
|
16
|
+
logger = logging.getLogger(".")
|
17
|
+
|
18
|
+
init_log(logger, loglevel="DEBUG")
|
19
|
+
|
20
|
+
REAL_DATABASE = "loqus-test"
|
21
|
+
TEST_DATABASE = "test"
|
22
|
+
|
23
|
+
|
24
|
+
class CyvcfVariant(object):
|
25
|
+
"""Mock a cyvcf variant
|
26
|
+
|
27
|
+
Default is to return a variant with three individuals high genotype
|
28
|
+
quality.
|
29
|
+
"""
|
30
|
+
|
31
|
+
def __init__(
|
32
|
+
self,
|
33
|
+
chrom="1",
|
34
|
+
pos=80000,
|
35
|
+
ref="A",
|
36
|
+
alt="C",
|
37
|
+
end=None,
|
38
|
+
gt_quals=[60, 60, 60],
|
39
|
+
gt_types=[1, 1, 0],
|
40
|
+
var_type="snv",
|
41
|
+
var_id=None,
|
42
|
+
info_dict={},
|
43
|
+
):
|
44
|
+
super(CyvcfVariant, self).__init__()
|
45
|
+
self.CHROM = chrom
|
46
|
+
self.POS = pos
|
47
|
+
self.REF = ref
|
48
|
+
self.ALT = [alt]
|
49
|
+
self.end = end or pos
|
50
|
+
self.gt_quals = gt_quals
|
51
|
+
self.gt_types = gt_types
|
52
|
+
self.var_type = var_type
|
53
|
+
self.INFO = info_dict
|
54
|
+
if var_id is None:
|
55
|
+
var_id = "."
|
56
|
+
self.ID = var_id
|
57
|
+
|
58
|
+
|
59
|
+
@pytest.fixture(scope="function")
|
60
|
+
def real_db_name(request):
|
61
|
+
"""Return the name of the real mongo test db"""
|
62
|
+
return REAL_DATABASE
|
63
|
+
|
64
|
+
|
65
|
+
@pytest.fixture(scope="function")
|
66
|
+
def mongo_client(request):
|
67
|
+
"""Return a mongomock client"""
|
68
|
+
client = MockClient(directConnection=True)
|
69
|
+
return client
|
70
|
+
|
71
|
+
|
72
|
+
@pytest.fixture(scope="function")
|
73
|
+
def real_mongo_client(request):
|
74
|
+
"""Return a mongomock client"""
|
75
|
+
client = MongoClient(directConnection=True)
|
76
|
+
|
77
|
+
def teardown():
|
78
|
+
print("\n")
|
79
|
+
logger.info("Deleting database")
|
80
|
+
client.drop_database(REAL_DATABASE)
|
81
|
+
logger.info("Database deleted")
|
82
|
+
|
83
|
+
request.addfinalizer(teardown)
|
84
|
+
|
85
|
+
return client
|
86
|
+
|
87
|
+
|
88
|
+
@pytest.fixture(scope="function")
|
89
|
+
def mongo_adapter(request, mongo_client):
|
90
|
+
"""Return a mongo adapter"""
|
91
|
+
db_name = TEST_DATABASE
|
92
|
+
adapter = MongoAdapter(mongo_client, db_name)
|
93
|
+
|
94
|
+
return adapter
|
95
|
+
|
96
|
+
|
97
|
+
@pytest.fixture(scope="function")
|
98
|
+
def real_mongo_adapter(request, real_mongo_client):
|
99
|
+
"""Return a mongo adapter"""
|
100
|
+
db_name = REAL_DATABASE
|
101
|
+
adapter = MongoAdapter(real_mongo_client, db_name)
|
102
|
+
|
103
|
+
return adapter
|
104
|
+
|
105
|
+
|
106
|
+
@pytest.fixture(scope="function")
|
107
|
+
def simplest_variant(request):
|
108
|
+
variant = {
|
109
|
+
"_id": "test",
|
110
|
+
}
|
111
|
+
return variant
|
112
|
+
|
113
|
+
|
114
|
+
@pytest.fixture(scope="function")
|
115
|
+
def homozygous_variant(request):
|
116
|
+
variant = {"_id": "test", "homozygote": 1, "case_id": "1"}
|
117
|
+
return variant
|
118
|
+
|
119
|
+
|
120
|
+
@pytest.fixture(scope="function")
|
121
|
+
def simple_case(request):
|
122
|
+
case = Case("test", "./test.vcf")
|
123
|
+
|
124
|
+
return case
|
125
|
+
|
126
|
+
|
127
|
+
@pytest.fixture(scope="function")
|
128
|
+
def vcf_path(request):
|
129
|
+
file_path = "tests/fixtures/test.vcf"
|
130
|
+
return file_path
|
131
|
+
|
132
|
+
|
133
|
+
@pytest.fixture(scope="function")
|
134
|
+
def sv_vcf_path(request):
|
135
|
+
file_path = "tests/fixtures/test.SV.vcf"
|
136
|
+
return file_path
|
137
|
+
|
138
|
+
|
139
|
+
@pytest.fixture(scope="function")
|
140
|
+
def double_vcf_path(request):
|
141
|
+
"This will return a vcf with the same variant two times"
|
142
|
+
file_path = "tests/fixtures/double_variant.vcf"
|
143
|
+
return file_path
|
144
|
+
|
145
|
+
|
146
|
+
@pytest.fixture(scope="function")
|
147
|
+
def unsorted_vcf_path(request):
|
148
|
+
"This will return a vcf with unsorted variants"
|
149
|
+
file_path = "tests/fixtures/unsorted.vcf"
|
150
|
+
return file_path
|
151
|
+
|
152
|
+
|
153
|
+
@pytest.fixture(scope="function")
|
154
|
+
def zipped_vcf_path(request):
|
155
|
+
"Returns a VCF that is gzipped and have a index companion"
|
156
|
+
file_path = "tests/fixtures/test.vcf.gz"
|
157
|
+
return file_path
|
158
|
+
|
159
|
+
|
160
|
+
@pytest.fixture(scope="function")
|
161
|
+
def profile_vcf_path(request):
|
162
|
+
"Returns a VCF containing profile variants"
|
163
|
+
file_path = "tests/fixtures/profile_snv.vcf"
|
164
|
+
return file_path
|
165
|
+
|
166
|
+
|
167
|
+
@pytest.fixture(scope="function")
|
168
|
+
def ped_path(request):
|
169
|
+
file_path = "tests/fixtures/recessive_trio.ped"
|
170
|
+
return file_path
|
171
|
+
|
172
|
+
|
173
|
+
@pytest.fixture(scope="function")
|
174
|
+
def funny_ped_path(request):
|
175
|
+
"Returns a ped file with incorrect family relations"
|
176
|
+
return "tests/fixtures/funny_trio.ped"
|
177
|
+
|
178
|
+
|
179
|
+
@pytest.fixture(scope="function")
|
180
|
+
def ind_positions(request):
|
181
|
+
return {"proband": 0, "mother": 1, "father": 2}
|
182
|
+
|
183
|
+
|
184
|
+
@pytest.fixture(scope="function")
|
185
|
+
def case_lines(request, ped_path):
|
186
|
+
"""Return ped formated case lines"""
|
187
|
+
case = []
|
188
|
+
with open(ped_path, "r") as f:
|
189
|
+
for line in f:
|
190
|
+
case.append(line)
|
191
|
+
|
192
|
+
return case
|
193
|
+
|
194
|
+
|
195
|
+
@pytest.fixture(scope="function")
|
196
|
+
def case_id(request, ped_path):
|
197
|
+
"""Return ped formated case lines"""
|
198
|
+
case_id = None
|
199
|
+
with open(ped_path, "r") as f:
|
200
|
+
for line in f:
|
201
|
+
case_id = line.split("\t")[0]
|
202
|
+
|
203
|
+
return case_id
|
204
|
+
|
205
|
+
|
206
|
+
@pytest.fixture(scope="function")
|
207
|
+
def vcf_obj(request, vcf_path):
|
208
|
+
"""return a cyvcf2.VCF obj"""
|
209
|
+
return cyvcf2.VCF(vcf_path)
|
210
|
+
|
211
|
+
|
212
|
+
@pytest.fixture(scope="function")
|
213
|
+
def sv_vcf_obj(request, sv_vcf_path):
|
214
|
+
"""return a cyvcf2.VCF obj"""
|
215
|
+
return cyvcf2.VCF(sv_vcf_path)
|
216
|
+
|
217
|
+
|
218
|
+
@pytest.fixture(scope="function")
|
219
|
+
def profile_list(request):
|
220
|
+
return ["AA", "CC", "GG", "TT"]
|
221
|
+
|
222
|
+
|
223
|
+
@pytest.fixture(scope="function")
|
224
|
+
def case_obj(request, case_lines, vcf_obj, vcf_path, profile_list):
|
225
|
+
"""Return a case obj"""
|
226
|
+
family_parser = FamilyParser(case_lines, family_type="ped")
|
227
|
+
families = list(family_parser.families.keys())
|
228
|
+
family = family_parser.families[families[0]]
|
229
|
+
vcf_individuals = vcf_obj.samples
|
230
|
+
nr_variants = 0
|
231
|
+
for nr_variants, variant in enumerate(vcf_obj, 1):
|
232
|
+
continue
|
233
|
+
return build_case(
|
234
|
+
case=family,
|
235
|
+
vcf_individuals=vcf_individuals,
|
236
|
+
vcf_path=vcf_path,
|
237
|
+
nr_variants=nr_variants,
|
238
|
+
profiles={individual: profile_list for individual in vcf_individuals},
|
239
|
+
)
|
240
|
+
|
241
|
+
|
242
|
+
@pytest.fixture(scope="function")
|
243
|
+
def sv_case_obj(request, case_lines, sv_vcf_obj, sv_vcf_path):
|
244
|
+
"""Return a case obj"""
|
245
|
+
family_parser = FamilyParser(case_lines, family_type="ped")
|
246
|
+
families = list(family_parser.families.keys())
|
247
|
+
family = family_parser.families[families[0]]
|
248
|
+
vcf_individuals = sv_vcf_obj.samples
|
249
|
+
nr_variants = 0
|
250
|
+
for nr_variants, variant in enumerate(sv_vcf_obj, 1):
|
251
|
+
continue
|
252
|
+
return build_case(
|
253
|
+
case=family,
|
254
|
+
sv_individuals=vcf_individuals,
|
255
|
+
vcf_sv_path=sv_vcf_path,
|
256
|
+
nr_sv_variants=nr_variants,
|
257
|
+
)
|
258
|
+
|
259
|
+
|
260
|
+
@pytest.fixture(scope="function")
|
261
|
+
def complete_case_obj(request, case_obj, sv_case_obj):
|
262
|
+
"""Return a case obj with both sv and snv information"""
|
263
|
+
return update_case(case_obj, sv_case_obj)
|
264
|
+
|
265
|
+
|
266
|
+
@pytest.fixture(scope="function")
|
267
|
+
def family_obj(request, case_lines):
|
268
|
+
"""Return a case obj"""
|
269
|
+
family_parser = FamilyParser(case_lines, family_type="ped")
|
270
|
+
families = list(family_parser.families.keys())
|
271
|
+
return family_parser.families[families[0]]
|
272
|
+
|
273
|
+
|
274
|
+
@pytest.fixture(scope="function")
|
275
|
+
def case_id(request, case_lines):
|
276
|
+
"""Return a case id"""
|
277
|
+
family_parser = FamilyParser(case_lines, family_type="ped")
|
278
|
+
families = list(family_parser.families.keys())
|
279
|
+
family = family_parser.families[families[0]]
|
280
|
+
return family.family_id
|
281
|
+
|
282
|
+
|
283
|
+
@pytest.fixture(scope="function")
|
284
|
+
def individuals(request, case_obj):
|
285
|
+
"""Return a case obj"""
|
286
|
+
|
287
|
+
return case_obj.individuals
|
288
|
+
|
289
|
+
|
290
|
+
@pytest.fixture(scope="function")
|
291
|
+
def two_cases(request):
|
292
|
+
"""Return ped formated case lines"""
|
293
|
+
return [
|
294
|
+
"#FamilyID\tSampleID\tFather\tMother\tSex\tPhenotype\n",
|
295
|
+
"1\tproband\t0\t0\t1\t2\n",
|
296
|
+
"2\tproband\t0\t0\t2\t1\n",
|
297
|
+
]
|
298
|
+
|
299
|
+
|
300
|
+
## Variant fixtures:
|
301
|
+
|
302
|
+
# chrom='1',
|
303
|
+
# pos=80000,
|
304
|
+
# ref='A',
|
305
|
+
# alt='C',
|
306
|
+
# end=None,
|
307
|
+
# gt_quals=[60, 60, 60],
|
308
|
+
# gt_types=[1, 1, 0],
|
309
|
+
# var_type='snv',
|
310
|
+
# info_dict={}
|
311
|
+
|
312
|
+
### Variant objects
|
313
|
+
|
314
|
+
|
315
|
+
@pytest.fixture(scope="function")
|
316
|
+
def variant_obj(request, het_variant, ind_positions, individuals):
|
317
|
+
return build_variant(
|
318
|
+
variant=het_variant,
|
319
|
+
individuals=individuals,
|
320
|
+
ind_positions=ind_positions,
|
321
|
+
case_id="test",
|
322
|
+
gq_threshold=None,
|
323
|
+
)
|
324
|
+
|
325
|
+
|
326
|
+
### CYVCF2 variants
|
327
|
+
### SNVs:
|
328
|
+
@pytest.fixture(scope="function")
|
329
|
+
def hem_variant(request):
|
330
|
+
return CyvcfVariant(chrom="X", pos=60000)
|
331
|
+
|
332
|
+
|
333
|
+
@pytest.fixture(scope="function")
|
334
|
+
def variant_chr(request):
|
335
|
+
return CyvcfVariant(chrom="chrX", pos=60000)
|
336
|
+
|
337
|
+
|
338
|
+
@pytest.fixture(scope="function")
|
339
|
+
def par_variant(request):
|
340
|
+
return CyvcfVariant(chrom="X", pos=60001)
|
341
|
+
|
342
|
+
|
343
|
+
@pytest.fixture(scope="function")
|
344
|
+
def het_variant(request):
|
345
|
+
return CyvcfVariant()
|
346
|
+
|
347
|
+
|
348
|
+
@pytest.fixture(scope="function")
|
349
|
+
def bnd_variant(request):
|
350
|
+
return CyvcfVariant(
|
351
|
+
chrom="1",
|
352
|
+
pos=80000,
|
353
|
+
alt="N[1:80000[",
|
354
|
+
ref="N",
|
355
|
+
end=80000,
|
356
|
+
info_dict={"SVTYPE": "BND"},
|
357
|
+
)
|
358
|
+
|
359
|
+
|
360
|
+
@pytest.fixture(scope="function")
|
361
|
+
def variant_no_gq(request):
|
362
|
+
return CyvcfVariant(gt_quals=[-1, -1, -1])
|
363
|
+
|
364
|
+
|
365
|
+
@pytest.fixture(scope="function")
|
366
|
+
def hom_variant(request):
|
367
|
+
return CyvcfVariant(gt_types=[3, 1, 1])
|
368
|
+
|
369
|
+
|
370
|
+
@pytest.fixture(scope="function")
|
371
|
+
def variant_no_call(request):
|
372
|
+
return CyvcfVariant(gt_types=[2, 2, 2])
|
373
|
+
|
374
|
+
|
375
|
+
### SVs:
|
376
|
+
@pytest.fixture(scope="function")
|
377
|
+
def del_variant(request):
|
378
|
+
return CyvcfVariant(
|
379
|
+
chrom="1",
|
380
|
+
ref="G",
|
381
|
+
alt="<DEL>",
|
382
|
+
pos=1285001,
|
383
|
+
end=1287000,
|
384
|
+
var_type="sv",
|
385
|
+
info_dict={"END": 1287000, "SVLEN": -20000, "SVTYPE": "DEL"},
|
386
|
+
)
|
387
|
+
|
388
|
+
|
389
|
+
@pytest.fixture(scope="function")
|
390
|
+
def small_insert_variant(request):
|
391
|
+
return CyvcfVariant(
|
392
|
+
chrom="1",
|
393
|
+
ref="G",
|
394
|
+
alt="GGGACGGGGGTTCTGAGATAAGCAAGCCCCCACCAGGTGAGACCGGCGGAGCTGTGGCCACCGAGGTCCCGGGAGCTGGTGCT",
|
395
|
+
pos=3021145,
|
396
|
+
end=3021145,
|
397
|
+
var_type="sv",
|
398
|
+
info_dict={"END": 3021145, "SVLEN": 82, "SVTYPE": "INS"},
|
399
|
+
)
|
400
|
+
|
401
|
+
|
402
|
+
@pytest.fixture(scope="function")
|
403
|
+
def insertion_variant(request):
|
404
|
+
return CyvcfVariant(
|
405
|
+
chrom="1",
|
406
|
+
ref="A",
|
407
|
+
alt="<INS>",
|
408
|
+
pos=3177306,
|
409
|
+
end=3177306,
|
410
|
+
var_type="sv",
|
411
|
+
info_dict={"END": 3177306, "SVLEN": None, "SVTYPE": "INS"},
|
412
|
+
)
|
413
|
+
|
414
|
+
|
415
|
+
@pytest.fixture(scope="function")
|
416
|
+
def duptandem_variant(request):
|
417
|
+
return CyvcfVariant(
|
418
|
+
chrom="1",
|
419
|
+
ref="A",
|
420
|
+
alt="<DUP:TANDEM>",
|
421
|
+
pos=3092626,
|
422
|
+
end=3092849,
|
423
|
+
var_type="sv",
|
424
|
+
info_dict={"END": 3092849, "SVLEN": 223, "SVTYPE": "DUP"},
|
425
|
+
)
|
426
|
+
|
427
|
+
|
428
|
+
@pytest.fixture(scope="function")
|
429
|
+
def translocation_variant(request):
|
430
|
+
return CyvcfVariant(
|
431
|
+
chrom="1",
|
432
|
+
ref="N",
|
433
|
+
alt="N[11:119123896[",
|
434
|
+
pos=3754913,
|
435
|
+
end=3754913,
|
436
|
+
var_type="sv",
|
437
|
+
info_dict={"END": None, "SVLEN": None, "SVTYPE": "BND"},
|
438
|
+
)
|