Skip to content

Commit c7a0587

Browse files
committed
Map DRB3, DRB4 and DRB5 typings to DRBX.
1 parent 8c75898 commit c7a0587

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

pyard/drbx.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from typing import Tuple, List
2+
3+
4+
def map_drbx(drb_alleles: List, locus_in_allele_name: bool) -> Tuple:
5+
"""
6+
Generates a pair of DRBX Typings based on DRB3, DRB4 and DRB5 typings.
7+
Expects Type1 and Type2 DRB3, DRB4 and DRB5 typings in that order
8+
in `drb_alleles` list.
9+
10+
:param drb_alleles: Type1/Type2 DRB3, DRB4 and DRB5 typings.
11+
:param locus_in_allele_name: Does typing include DRBn prefix?
12+
:return: Tuple of DRBX type1/type2
13+
"""
14+
15+
nnnn = 'NNNN'
16+
if locus_in_allele_name:
17+
nnnn = 'DRBX*NNNN'
18+
19+
# Get the ones DRBs without NNNNs
20+
drbx_non_nns = list(filter(lambda x: x != '' and not x.endswith('NNNN'), drb_alleles))
21+
if len(drbx_non_nns) == 0:
22+
return nnnn, nnnn
23+
24+
# There can only be at most 2 DRBn loci present
25+
if len(drbx_non_nns) == 2:
26+
# If they are homozygous, return a single DRBn only
27+
if drbx_non_nns[0] == drbx_non_nns[1]:
28+
return drbx_non_nns[0], ''
29+
# Else return drbx_1 and drbx_2
30+
return tuple(drbx_non_nns)
31+
32+
# If there's only a single DRBn, return NNNN as the second typing
33+
if len(drbx_non_nns) == 1:
34+
return drbx_non_nns[0], nnnn
35+
36+
# Everything else is NNNNs
37+
return nnnn, nnnn

tests/features/drbx.feature

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Feature: DRBX Mapping
2+
3+
Create a single DRBX genotype from DRB3, DRB4, DRB5 alleles
4+
5+
Scenario Outline:
6+
7+
Given a subject has <DRB3_Type1> and <DRB3_Type2> DRB3 alleles
8+
And a subject has <DRB4 Type1> and <DRB4 Type2> DRB4 alleles
9+
And a subject has <DRB5 Type1> and <DRB5 Type2> DRB5 alleles
10+
When I create a DRBX genotype
11+
Then it should be <DRBX_Type1> and <DRBX_Type2>
12+
13+
Examples: All NNNS
14+
| DRB3_Type1 | DRB3_Type2 | DRB4 Type1 | DRB4 Type2 | DRB5 Type1 | DRB5 Type2 | DRBX_Type1 | DRBX_Type2 |
15+
| DRB3*NNNN | x | DRB4*NNNN | x | DRB5*NNNN | x | DRBX*NNNN | DRBX*NNNN |
16+
| DRB3*NNNN | x | x | x | x | x | DRBX*NNNN | DRBX*NNNN |
17+
| DRB3*NNNN | x | DRB4*NNNN | x | x | x | DRBX*NNNN | DRBX*NNNN |
18+
19+
Examples: Some NNNS
20+
| DRB3_Type1 | DRB3_Type2 | DRB4 Type1 | DRB4 Type2 | DRB5 Type1 | DRB5 Type2 | DRBX_Type1 | DRBX_Type2 |
21+
| DRB3*02:02 | x | x | x | x | x | DRB3*02:02 | DRBX*NNNN |
22+
| DRB3*02:02 | x | DRB4*01:01 | x | DRB5*NNNN | x | DRB3*02:02 | DRB4*01:01 |
23+
24+
Examples: No NNNS
25+
| DRB3_Type1 | DRB3_Type2 | DRB4 Type1 | DRB4 Type2 | DRB5 Type1 | DRB5 Type2 | DRBX_Type1 | DRBX_Type2 |
26+
| DRB3*02:02 | x | DRB4*01:01 | x | x | x | DRB3*02:02 | DRB4*01:01 |
27+
| DRB3*02:02 | DRB3*01:01 | x | x | x | x | DRB3*02:02 | DRB3*01:01 |
28+
| DRB3*01:01 | x | DRB4*01:01 | x | x | x | DRB3*01:01 | DRB4*01:01 |
29+
30+
Examples: Homozygous
31+
| DRB3_Type1 | DRB3_Type2 | DRB4 Type1 | DRB4 Type2 | DRB5 Type1 | DRB5 Type2 | DRBX_Type1 | DRBX_Type2 |
32+
| DRB3*02:02 | DRB3*02:02 | x | x | x | x | DRB3*02:02 | x |

tests/steps/generate_drbx.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from behave import *
2+
from hamcrest import assert_that, is_
3+
4+
from pyard.drbx import map_drbx
5+
6+
7+
@given("a subject has {arg0} and {arg1} DRB3 alleles")
8+
def step_impl(context, arg0, arg1):
9+
context.drb3_1 = '' if arg0 == 'x' else arg0
10+
context.drb3_2 = '' if arg1 == 'x' else arg1
11+
12+
13+
@step("a subject has {arg0} and {arg1} DRB4 alleles")
14+
def step_impl(context, arg0, arg1):
15+
context.drb4_1 = '' if arg0 == 'x' else arg0
16+
context.drb4_2 = '' if arg1 == 'x' else arg1
17+
18+
19+
@step("a subject has {arg0} and {arg1} DRB5 alleles")
20+
def step_impl(context, arg0, arg1):
21+
context.drb5_1 = '' if arg0 == 'x' else arg0
22+
context.drb5_2 = '' if arg1 == 'x' else arg1
23+
24+
25+
@when("I create a DRBX genotype")
26+
def step_impl(context):
27+
drbs = [
28+
context.drb3_1, context.drb3_2,
29+
context.drb4_1, context.drb4_2,
30+
context.drb5_1, context.drb5_2
31+
]
32+
context.drbx = map_drbx(drbs, True)
33+
34+
35+
@then("it should be {drbx1} and {drbx2}")
36+
def step_impl(context, drbx1, drbx2):
37+
expected_drbx_1 = '' if drbx1 == 'x' else drbx1
38+
expected_drbx_2 = '' if drbx2 == 'x' else drbx2
39+
expected_drbx = (expected_drbx_1, expected_drbx_2)
40+
assert_that(context.drbx, is_(expected_drbx))

0 commit comments

Comments
 (0)