Skip to content

Commit aa3d1a7

Browse files
authored
Merge pull request #82 from pbashyal-nmdp/map_drbx
Map DRB3, DRB4 and DRB5 typings to DRBX.
2 parents 8c75898 + e6dde30 commit aa3d1a7

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

pyard/drbx.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
Reference:
11+
World Marrow Donor Association guidelines for use of HLA nomenclature
12+
and its validation in the data exchange among hematopoietic
13+
stem cell donor registries and cord blood banks
14+
https://www.nature.com/articles/1705672
15+
16+
:param drb_alleles: Type1/Type2 DRB3, DRB4 and DRB5 typings.
17+
:param locus_in_allele_name: Does typing include DRBn prefix?
18+
:return: Tuple of DRBX type1/type2
19+
"""
20+
21+
nnnn = 'NNNN'
22+
if locus_in_allele_name:
23+
nnnn = 'DRBX*NNNN'
24+
25+
# Get the ones DRBs without NNNNs
26+
drbx_non_nns = list(filter(lambda x: x != '' and not x.endswith('NNNN'), drb_alleles))
27+
if len(drbx_non_nns) == 0:
28+
return nnnn, nnnn
29+
30+
# There can only be at most 2 DRBn loci present
31+
if len(drbx_non_nns) == 2:
32+
# If they are homozygous, return a single DRBn only
33+
if drbx_non_nns[0] == drbx_non_nns[1]:
34+
return drbx_non_nns[0], ''
35+
# Else return drbx_1 and drbx_2
36+
return tuple(drbx_non_nns)
37+
38+
# If there's only a single DRBn, return NNNN as the second typing
39+
if len(drbx_non_nns) == 1:
40+
return drbx_non_nns[0], nnnn
41+
42+
# Everything else is NNNNs
43+
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)