Skip to content

Commit

Permalink
Merge pull request #1 from cfe-lab/new-hivdb
Browse files Browse the repository at this point in the history
Update OR syntax
  • Loading branch information
CBeelen authored Jun 6, 2023
2 parents 5839279 + 6d62904 commit fefa963
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 45 deletions.
24 changes: 9 additions & 15 deletions pyvdrm/asi2.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from functools import reduce, total_ordering
from pyparsing import (Literal, nums, Word, Forward, Optional, Regex,
infixNotation, delimitedList, opAssoc, ParseException)
from pyvdrm.drm import AsiExpr, AsiBinaryExpr, DRMParser, MissingPositionError
from pyvdrm.drm import AsiExpr, AsiMultipleExpr, DRMParser, MissingPositionError
from pyvdrm.vcf import MutationSet


Expand Down Expand Up @@ -74,22 +74,16 @@ def __call__(self, mutations):
return Score(True, residues)


class OrExpr(AsiBinaryExpr):
"""Boolean OR on children (binary only)"""
class OrExpr(AsiMultipleExpr):
"""Boolean OR on children (not necessarily binary)"""

def __call__(self, mutations):
arg1, arg2 = self.children

score1 = arg1(mutations)
score2 = arg2(mutations)

if score1 is None:
score1 = Score(False, [])
if score2 is None:
score2 = Score(False, [])

return Score(score1.score or score2.score,
score1.residues | score2.residues)
for arg in self.children:
score = arg(mutations)
if score is not None and score.score:
return score
else:
return Score(False, [])


class EqualityExpr(AsiExpr):
Expand Down
10 changes: 1 addition & 9 deletions pyvdrm/drm.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,13 @@ def __call__(self, args):
return self.children(args)


class AsiBinaryExpr(AsiExpr):
class AsiMultipleExpr(AsiExpr):
"""Subclass with syntactic sugar for boolean ops"""

def __init__(self, label, pos, tokens):
super().__init__(label, pos, tokens)
self.children = tokens[0]

def typecheck(self, tokens):
if len(tokens[0]) != 2:
raise AsiParseError

def __repr__(self):
arg1, arg2 = self.children
return "{} {} {}".format(arg1, type(self), arg2)


class AsiUnaryExpr(AsiExpr):
"""Subclass for atoms and unary ops"""
Expand Down
24 changes: 9 additions & 15 deletions pyvdrm/hcvr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
infixNotation, delimitedList, opAssoc, ParseException)

from pyvdrm.drm import MissingPositionError
from pyvdrm.drm import AsiExpr, AsiBinaryExpr, DRMParser
from pyvdrm.drm import AsiExpr, AsiMultipleExpr, DRMParser
from pyvdrm.vcf import MutationSet


Expand Down Expand Up @@ -98,22 +98,16 @@ def __call__(self, mutations):
return Score(True, residues)


class OrExpr(AsiBinaryExpr):
"""Boolean OR on children (binary only)"""
class OrExpr(AsiMultipleExpr):
"""Boolean OR on children (not necessarily binary)"""

def __call__(self, mutations):
arg1, arg2 = self.children

score1 = arg1(mutations)
score2 = arg2(mutations)

if score1 is None:
score1 = Score(False, [])
if score2 is None:
score2 = Score(False, [])

return Score(score1.score or score2.score,
score1.residues | score2.residues)
for arg in self.children:
score = arg(mutations)
if score is not None and score.score:
return score
else:
return Score(False, [])


class EqualityExpr(AsiExpr):
Expand Down
10 changes: 8 additions & 2 deletions pyvdrm/tests/test_asi2.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ def test_bool_or(self):
self.assertFalse(rule(VariantCalls("1d 2d 7d")))
self.assertTrue(rule(VariantCalls("1G 2d 7d")))

def test_bool_or_no_brackets(self):
rule = ASI2("1G OR 2T OR 7Y")
self.assertTrue(rule(VariantCalls("1d 2T 7d")))
self.assertFalse(rule(VariantCalls("1d 2d 7d")))
self.assertTrue(rule(VariantCalls("1G 2d 7d")))

def test_select_from_atleast(self):
rule = ASI2("SELECT ATLEAST 2 FROM (2T, 7Y, 3G)")
self.assertTrue(rule(VariantCalls("2T 7Y 3d")))
Expand All @@ -111,7 +117,7 @@ def test_score_from_exactly(self):

def test_parse_exception(self):
expected_error_message = (
"Error in ASI2: SCORE FROM ( 10R => 2>!<;0 ) (at char 21), (line:1, col:22)")
"Error in ASI2: SCORE FROM ( 10R => 2>!<;0 ), found ';' (at char 21), (line:1, col:22)")

with self.assertRaises(ParseException) as context:
ASI2("SCORE FROM ( 10R => 2;0 )")
Expand All @@ -125,7 +131,7 @@ def test_parse_exception_multiline(self):
)
"""
expected_error_message = (
"Error in ASI2: 10R => 2>!<;0 (at char 25), (line:2, col:13)")
"Error in ASI2: 10R => 2>!<;0, found ';' (at char 25), (line:2, col:13)")

with self.assertRaises(ParseException) as context:
ASI2(rule)
Expand Down
15 changes: 11 additions & 4 deletions pyvdrm/tests/test_hcvr.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ def test_score_from_min_neg(self):
rule = HCVR("SCORE FROM (MIN (100G => -10, 101D => -20, 102D => 30))")
self.assertEqual(-20, rule(VariantCalls("100G 101D 102d")))



def test_bool_and(self):
rule = HCVR("1G AND (2T AND 7Y)")
self.assertEqual(rule(VariantCalls("2T 7Y 1G")), True)
Expand All @@ -128,6 +126,15 @@ def test_bool_or(self):
r"Missing position 1"):
rule([])

def test_bool_or_no_brackets(self):
rule = HCVR("1G OR 2T OR 7Y")
self.assertTrue(rule(VariantCalls("1d 2T 7d")))
self.assertFalse(rule(VariantCalls("1d 2d 7d")))
self.assertTrue(rule(VariantCalls("1G 2d 7d")))
with self.assertRaisesRegex(MissingPositionError,
r"Missing position 1"):
rule([])

def test_select_from_atleast(self):
rule = HCVR("SELECT ATLEAST 2 FROM (2T, 7Y, 3G)")
self.assertTrue(rule(VariantCalls("2T 7Y 3d")))
Expand All @@ -148,7 +155,7 @@ def test_score_comment(self):

def test_parse_exception(self):
expected_error_message = (
"Error in HCVR: SCORE FROM ( 10R => 2>!<;0 ) (at char 21), (line:1, col:22)")
"Error in HCVR: SCORE FROM ( 10R => 2>!<;0 ), found ';' (at char 21), (line:1, col:22)")

with self.assertRaises(ParseException) as context:
HCVR("SCORE FROM ( 10R => 2;0 )")
Expand All @@ -162,7 +169,7 @@ def test_parse_exception_multiline(self):
)
"""
expected_error_message = (
"Error in HCVR: 10R => 2>!<;0 (at char 25), (line:2, col:13)")
"Error in HCVR: 10R => 2>!<;0, found ';' (at char 25), (line:2, col:13)")

with self.assertRaises(ParseException) as context:
HCVR(rule)
Expand Down

0 comments on commit fefa963

Please sign in to comment.