Skip to content

Commit d111474

Browse files
committed
rename references to ASI2 in HCV test cases
1 parent fa23ccd commit d111474

File tree

3 files changed

+199
-13
lines changed

3 files changed

+199
-13
lines changed

pyvdrm/hcvr.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
ASI2 Parser definition
2+
HCV Drug Resistance Rule Parser definition
33
"""
44

55
from functools import reduce, total_ordering
@@ -42,6 +42,7 @@ class Score(object):
4242

4343
residues = set([])
4444
score = None
45+
flags = [] # allow a score expression to raise a user defined string
4546

4647
def __init__(self, score, residues):
4748
""" Initialize.
@@ -132,7 +133,7 @@ def __call__(self, mutations):
132133

133134

134135
class EqualityExpr(AsiExpr):
135-
"""ASI2 inequality expressions"""
136+
"""ASI2 style inequality expressions"""
136137

137138
def __init__(self, label, pos, children):
138139
super().__init__(label, pos, children)
@@ -240,8 +241,8 @@ def __call__(self, env):
240241
return None
241242

242243

243-
class ASI2(DRMParser):
244-
"""ASI2 Syntax definition"""
244+
class HCVR(DRMParser):
245+
"""HCV Resistance Syntax definition"""
245246

246247
def parser(self, rule):
247248

@@ -274,7 +275,7 @@ def parser(self, rule):
274275
# integer + l_par + not_ + Regex(r'[A-Z]+') + r_par
275276
# roll this next rule into the mutation object
276277

277-
# Syntax of ASI expressions
278+
# Syntax of expressions
278279
excludestatement = except_ + residue
279280

280281
quantifier = exactly | atleast | notmorethan

pyvdrm/tests/test_asi2.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,6 @@ def test_bool_and(self):
8181
self.assertEqual(rule(VariantCalls("7Y 1G 2T")), True)
8282
self.assertEqual(rule([]), False)
8383

84-
def test_bool_constants(self):
85-
rule = ASI2("TRUE OR 1G")
86-
self.assertEqual(rule(VariantCalls("2G")), True)
87-
rule = ASI2("FALSE AND 1G")
88-
self.assertEqual(rule(VariantCalls("1G")), False)
89-
rule = ASI2("TRUE OR (FALSE AND TRUE)")
90-
self.assertEqual(rule(VariantCalls("1G")), True)
91-
9284
def test_bool_or(self):
9385
rule = ASI2("1G OR (2T OR 7Y)")
9486
self.assertTrue(rule(VariantCalls("2T")))

pyvdrm/tests/test_hcvr.py

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import unittest
2+
from pyvdrm.hcvr import HCVR, AsiMutations, Score
3+
from pyvdrm.vcf import Mutation, MutationSet, VariantCalls
4+
5+
6+
# noinspection SqlNoDataSourceInspection,SqlDialectInspection
7+
class TestRuleParser(unittest.TestCase):
8+
9+
def test_stanford_ex1(self):
10+
HCVR("151M OR 69i")
11+
12+
def test_stanford_ex2(self):
13+
rule = HCVR("SELECT ATLEAST 2 FROM (41L, 67N, 70R, 210W, 215F, 219Q)")
14+
m1 = MutationSet('41L')
15+
m2 = MutationSet('67N')
16+
m3 = MutationSet('70N')
17+
self.assertTrue(rule([m1, m2]))
18+
self.assertFalse(rule([m1, m3]))
19+
20+
def test_stanford_ex3(self):
21+
HCVR("SELECT ATLEAST 2 AND NOTMORETHAN 2 FROM (41L, 67N, 70R, 210W, 215FY, 219QE)")
22+
23+
def test_stanford_ex4(self):
24+
HCVR("215FY AND NOT 184VI")
25+
26+
def test_stanford_rest(self):
27+
examples = ["SCORE FROM (65R => 20, 74V => 20, 184VI => 20)",
28+
"151M AND EXCLUDE 69i",
29+
# "69(NOT TDN)",
30+
"215F OR 215Y",
31+
"SCORE FROM (101P => 40, 101E => 30, 101HN => 15, 101Q => 5 )",
32+
"SCORE FROM ( MAX (101P => 40, 101E => 30, 101HN => 15, 101Q => 5 ))",
33+
"(184V AND 115F) => 20"
34+
"3N AND 9N",
35+
"2N OR 9N AND 2N",
36+
"3N AND (2N AND (4N OR 2N))"]
37+
38+
for ex in examples:
39+
x = HCVR(ex)
40+
self.assertEqual(ex, x.rule)
41+
42+
def test_asi2_compat(self):
43+
q = "SCORE FROM ( 98G => 10, 100I => 40,\
44+
MAX (101P => 40, 101E => 30, 101HN => 15, 101Q => 5) )"
45+
HCVR(q)
46+
47+
48+
# noinspection SqlNoDataSourceInspection,SqlDialectInspection
49+
class TestRuleSemantics(unittest.TestCase):
50+
def test_score_from(self):
51+
rule = HCVR("SCORE FROM ( 100G => 10, 101D => 20 )")
52+
self.assertEqual(rule(VariantCalls("100G 102G")), 10)
53+
54+
def test_score_negate(self):
55+
rule = HCVR("SCORE FROM ( NOT 100G => 10, NOT 101SD => 20 )")
56+
self.assertEqual(rule(VariantCalls("100G 102G")), 20)
57+
self.assertEqual(rule(VariantCalls("100S 101S")), 10)
58+
59+
def test_score_residues(self):
60+
rule = HCVR("SCORE FROM ( 100G => 10, 101D => 20 )")
61+
expected_residue = repr({Mutation('S100G')})
62+
63+
result = rule.dtree(VariantCalls("S100G R102G"))
64+
65+
self.assertEqual(expected_residue, repr(result.residues))
66+
67+
def test_score_from_max(self):
68+
rule = HCVR("SCORE FROM (MAX (100G => 10, 101D => 20, 102D => 30))")
69+
self.assertEqual(rule(VariantCalls("100G 101D")), 20)
70+
self.assertEqual(rule(VariantCalls("10G 11D")), False)
71+
72+
def test_score_from_max_neg(self):
73+
rule = HCVR("SCORE FROM (MAX (100G => -10, 101D => -20, 102D => 30))")
74+
self.assertEqual(rule(VariantCalls("100G 101D")), -10)
75+
self.assertEqual(rule(VariantCalls("10G 11D")), False)
76+
77+
def test_bool_and(self):
78+
rule = HCVR("1G AND (2T AND 7Y)")
79+
self.assertEqual(rule(VariantCalls("2T 7Y 1G")), True)
80+
self.assertEqual(rule(VariantCalls("2T 3Y 1G")), False)
81+
self.assertEqual(rule(VariantCalls("7Y 1G 2T")), True)
82+
self.assertEqual(rule([]), False)
83+
84+
def test_bool_constants(self):
85+
rule = HCVR("TRUE OR 1G")
86+
self.assertEqual(rule(VariantCalls("2G")), True)
87+
rule = HCVR("FALSE AND 1G")
88+
self.assertEqual(rule(VariantCalls("1G")), False)
89+
rule = HCVR("TRUE OR (FALSE AND TRUE)")
90+
self.assertEqual(rule(VariantCalls("1G")), True)
91+
92+
def test_bool_or(self):
93+
rule = HCVR("1G OR (2T OR 7Y)")
94+
self.assertTrue(rule(VariantCalls("2T")))
95+
self.assertFalse(rule(VariantCalls("3T")))
96+
self.assertTrue(rule(VariantCalls("1G")))
97+
self.assertFalse(rule([]))
98+
99+
def test_select_from_atleast(self):
100+
rule = HCVR("SELECT ATLEAST 2 FROM (2T, 7Y, 3G)")
101+
self.assertTrue(rule(VariantCalls("2T 7Y 1G")))
102+
self.assertFalse(rule(VariantCalls("2T 4Y 5G")))
103+
self.assertTrue(rule(VariantCalls("3G 9Y 2T")))
104+
105+
def test_score_from_exactly(self):
106+
rule = HCVR("SELECT EXACTLY 1 FROM (2T, 7Y)")
107+
score = rule(VariantCalls("2T 7Y 1G"))
108+
self.assertEqual(0, score)
109+
110+
111+
class TestActualRules(unittest.TestCase):
112+
def test_hivdb_rules_parse(self):
113+
for line in open("pyvdrm/tests/HIVDB.rules"):
114+
r = HCVR(line)
115+
self.assertEqual(line, r.rule)
116+
117+
def test_chained_and(self):
118+
rule = HCVR("""
119+
SCORE FROM(41L => 5, 62V => 5, MAX ( 65E => 10, 65N =>
120+
30, 65R => 45 ), MAX ( 67E => 5, 67G => 5, 67H => 5, 67N => 5, 67S =>
121+
5, 67T => 5, 67d => 30 ), 68d => 15, MAX ( 69G => 10, 69i => 60, 69d =>
122+
15 ), MAX ( 70E => 15, 70G => 15, 70N => 15, 70Q => 15, 70R => 5, 70S
123+
=> 15, 70T => 15, 70d => 15 ), MAX ( 74I => 30, 74V => 30 ), 75I => 5,
124+
77L => 5, 115F => 60, 116Y => 10, MAX ( 151L => 30, 151M => 60 ), MAX(
125+
184I => 15, 184V => 15 ), 210W => 5, MAX ( 215A => 5, 215C => 5, 215D
126+
=> 5, 215E => 5, 215F => 10, 215I => 5, 215L => 5, 215N => 5, 215S =>
127+
5, 215V => 5, 215Y => 10 ), MAX ( 219E => 5, 219N => 5, 219Q => 5, 219R
128+
=> 5 ), (40F AND 41L AND 210W AND 215FY) => 5, (41L AND 210W) => 10,
129+
(41L AND 210W AND 215FY) => 5, (41L AND 44AD AND 210W AND 215FY) => 5,
130+
(41L AND 67EGN AND 215FY) => 5, (67EGN AND 215FY AND 219ENQR) => 5,
131+
(67EGN AND 70R AND 184IV AND 219ENQR) => 20, (67EGN AND 70R AND
132+
219ENQR) => 10, (70R AND 215FY) => 5, (74IV AND 184IV) => 15, (77L AND
133+
116Y AND 151M) => 10, MAX ((210W AND 215ACDEILNSV) => 5, (210W AND
134+
215FY) => 10), MAX ((41L AND 215ACDEILNSV) => 5, (41L AND 215FY) =>
135+
15))
136+
""")
137+
self.assertEqual(rule(VariantCalls("40F 41L 210W 215Y")), 65)
138+
self.assertEqual(rule(VariantCalls("41L 210W 215F")), 60)
139+
self.assertEqual(rule(VariantCalls("40F 210W 215Y")), 25)
140+
self.assertEqual(rule(VariantCalls("40F 67G 215Y")), 15)
141+
142+
143+
class TestAsiMutations(unittest.TestCase):
144+
def test_init_args(self):
145+
expected_mutation_set = MutationSet('Q80KR')
146+
m = AsiMutations(args='Q80KR')
147+
148+
self.assertEqual(expected_mutation_set, m.mutations)
149+
self.assertEqual(expected_mutation_set.wildtype, m.mutations.wildtype)
150+
151+
def test_init_none(self):
152+
m = AsiMutations()
153+
154+
self.assertIsNone(m.mutations)
155+
156+
def test_repr(self):
157+
expected_repr = "AsiMutations(args='Q80KR')"
158+
m = AsiMutations(args='Q80KR')
159+
160+
r = repr(m)
161+
162+
self.assertEqual(expected_repr, r)
163+
164+
def test_repr_none(self):
165+
expected_repr = "AsiMutations()"
166+
m = AsiMutations()
167+
168+
r = repr(m)
169+
170+
self.assertEqual(expected_repr, r)
171+
172+
173+
class TestScore(unittest.TestCase):
174+
def test_init(self):
175+
expected_value = 10
176+
expected_mutations = {Mutation('A23R')}
177+
178+
score = Score(expected_value, expected_mutations)
179+
180+
self.assertEqual(expected_value, score.score)
181+
self.assertEqual(expected_mutations, score.residues)
182+
183+
def test_repr(self):
184+
expected_repr = "Score(10, {Mutation('A23R')})"
185+
score = Score(10, {Mutation('A23R')})
186+
187+
r = repr(score)
188+
189+
self.assertEqual(expected_repr, r)
190+
191+
192+
if __name__ == '__main__':
193+
unittest.main()

0 commit comments

Comments
 (0)