diff --git a/pyard/ard.py b/pyard/ard.py index 6881393..7a43a25 100644 --- a/pyard/ard.py +++ b/pyard/ard.py @@ -43,6 +43,7 @@ VALID_REDUCTION_TYPES, expression_chars, DEFAULT_CACHE_SIZE, + G_GROUP_LOCI, ) default_config = { @@ -388,6 +389,10 @@ def redux(self, glstring: str, redux_type: VALID_REDUCTION_TYPES) -> str: loc_allele = glstring.split(":") loc_antigen, code = loc_allele[0], loc_allele[1] else: + if "*" in glstring: + locus, _ = glstring.split("*") + if locus not in G_GROUP_LOCI: + return glstring raise InvalidTypingError( f"{glstring} is not a valid V2 or Serology typing." ) @@ -535,6 +540,7 @@ def is_v2(self, allele: str) -> bool: self._config["reduce_v2"] and "*" in allele and ":" not in allele + and allele.split("*")[0] not in ["MICA", "MICB", "HFE"] and allele != self._map_v2_to_v3(allele) ) diff --git a/pyard/constants.py b/pyard/constants.py index 824f227..2d5cefe 100644 --- a/pyard/constants.py +++ b/pyard/constants.py @@ -25,7 +25,32 @@ HLA_regex = re.compile("^HLA-") -VALID_REDUCTION_TYPES = ["G", "P", "lg", "lgx", "W", "exon", "U2", "S"] -expression_chars = ["N", "Q", "L", "S"] +VALID_REDUCTION_TYPES = ("G", "P", "lg", "lgx", "W", "exon", "U2", "S") +expression_chars = ("N", "Q", "L", "S") # List of P and G characters -PandG_chars = ["P", "G"] +P_and_G_chars = ("P", "G") + +# Loci with G group data +# Retrieved from lgx_group +# sqlite> select distinct(substr(allele, 1, instr(allele, '*') - 1)) from lgx_group; +G_GROUP_LOCI = ( + "A", + "B", + "C", + "DMA", + "DMB", + "DOA", + "DOB", + "DPA1", + "DPB1", + "DQA1", + "DQB1", + "DRA", + "DRB1", + "DRB3", + "DRB4", + "DRB5", + "E", + "F", + "G", +) diff --git a/pyard/misc.py b/pyard/misc.py index 9a110ab..b4fc950 100644 --- a/pyard/misc.py +++ b/pyard/misc.py @@ -24,7 +24,7 @@ import tempfile from typing import List -from pyard.constants import VALID_REDUCTION_TYPES, expression_chars, PandG_chars +from pyard.constants import VALID_REDUCTION_TYPES, expression_chars, P_and_G_chars def get_n_field_allele(allele: str, n: int, preserve_expression=False) -> str: @@ -47,7 +47,7 @@ def get_n_field_allele(allele: str, n: int, preserve_expression=False) -> str: def get_3field_allele(a: str) -> str: last_char = a[-1] - if last_char in PandG_chars: + if last_char in P_and_G_chars: a = a[:-1] return get_n_field_allele(a, 3) @@ -55,7 +55,7 @@ def get_3field_allele(a: str) -> str: def get_2field_allele(a: str) -> str: last_char = a[-1] - if last_char in PandG_chars: + if last_char in P_and_G_chars: a = a[:-1] return get_n_field_allele(a, 2) @@ -76,7 +76,7 @@ def is_2_field_allele(allele: str) -> bool: def get_G_name(a: str) -> str: a = a.split("/")[0] last_char = a[-1] - if last_char in PandG_chars + expression_chars: + if last_char in P_and_G_chars + expression_chars: a = a[:-1] if len(a.split(":")) == 2: return ":".join([a, "01"]) + "G" @@ -88,7 +88,7 @@ def get_G_name(a: str) -> str: def get_P_name(a: str) -> str: a = a.split("/")[0] last_char = a[-1] - if last_char in PandG_chars + expression_chars: + if last_char in P_and_G_chars + expression_chars: a = a[:-1] return ":".join(a.split(":")[0:2]) + "P" diff --git a/tests/features/allele.feature b/tests/features/allele.feature index 3629b4c..0be6be1 100644 --- a/tests/features/allele.feature +++ b/tests/features/allele.feature @@ -71,3 +71,19 @@ Feature: Alleles | Allele | Level | Redux Allele | | A*24:329 | lgx | A*24:329Q | | DQB1*03:276 | lgx | DQB1*03:01 | + + + Scenario Outline: Single field MICA, MICB Alleles + + For MICA, MICB alleles with single field, their reduced version is self. + + Given the allele as + When reducing on the level + Then the reduced allele is found to be + + Examples: + | Allele | Level | Redux Allele | + | HFE*002 | lgx | HFE*002 | + | MICA*040 | lgx | MICA*040 | + | MICB*006 | lgx | MICB*006 | + | MICB*029 | lgx | MICB*029 |