Skip to content

Commit

Permalink
Add validation for assumed HLA Type.
Browse files Browse the repository at this point in the history
  • Loading branch information
abragtim committed Apr 19, 2023
1 parent f038b30 commit ec974a4
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 16 deletions.
44 changes: 44 additions & 0 deletions tests/web/test_do_crossmatch_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def test_theoretical_and_double_antibodies_not_implemented(self):
res.json['message'])

def test_do_crossmatch_for_assumed_hla_type(self):
# general case
json = {
"assumed_donor_hla_typing": [['DPA1*01:03', 'DPA1*01:04', 'DPA1*01:06'],
['DPA1*02:01'],
Expand Down Expand Up @@ -168,3 +169,46 @@ def test_do_crossmatch_for_assumed_hla_type(self):
[asdict(create_hla_type('DPA1*02:01'))]]
self.assertCountEqual(expected_assumed_hla_typing,
res_assumed_hla_typing)

# hla type is assumed in split/broad
json = {
"assumed_donor_hla_typing": [['DPA1*01:03', 'DPA1*01:04', 'DPA1*02:06'],
['DPA1*02:01'],
['DPA1*01:04']],
"recipient_antibodies": [{'mfi': 2100,
'name': 'DPA1*01:04',
'cutoff': 2000
},
{'mfi': 2100,
'name': 'DPA1*02:01',
'cutoff': 2000
}],
}

with self.app.test_client() as client:
res = client.post(f'{API_VERSION}/{CROSSMATCH_NAMESPACE}/do-crossmatch', json=json,
headers=self.auth_headers)
self.assertEqual(400, res.status_code) # ValueError
self.assertEqual('HLA Type can be assumed just in high resolution.',
res.json['message'])

# low res codes in assumed hla type
json = {
"assumed_donor_hla_typing": [['DPA1*01:03', 'DPA1*01:04', 'DPA1'],
['DPA1*02:01'],
['DPA1*01:04']],
"recipient_antibodies": [{'mfi': 2100,
'name': 'DPA1*01:04',
'cutoff': 2000
},
{'mfi': 2100,
'name': 'DPA1*02:01',
'cutoff': 2000
}],
}
with self.app.test_client() as client:
res = client.post(f'{API_VERSION}/{CROSSMATCH_NAMESPACE}/do-crossmatch', json=json,
headers=self.auth_headers)
self.assertEqual(400, res.status_code) # ValueError
self.assertEqual('Assumed HLA type is available only for HLA types in high resolution.',
res.json['message'])
7 changes: 6 additions & 1 deletion txmatching/utils/hla_system/hla_crossmatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ class AntibodyMatchForHLAType:
def __post_init__(self):
if self.is_hla_type_assumed() and not self.__is_hla_type_in_high_res():
raise ValueError("Assumed HLA type is available only"
" for HLA type in high resolution.")
" for HLA types in high resolution.")
if self.__is_hla_type_assumed_in_low_res():
raise ValueError("HLA Type can be assumed just in high resolution.")

def is_hla_type_assumed(self):
return len(self.hla_type) > 1
Expand All @@ -49,6 +51,9 @@ def __is_hla_type_in_high_res(self):
return len([hla_type for hla_type in self.hla_type
if not hla_type.code.is_in_high_res()]) == 0

def __is_hla_type_assumed_in_low_res(self):
return len({hla_type.code.get_low_res_code() for hla_type in self.hla_type}) > 1

def __hash__(self):
return hash(tuple(self.hla_type))

Expand Down
28 changes: 13 additions & 15 deletions txmatching/web/api/crossmatch_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,17 @@ def get_hla_types_correspond_antibody(assumed_hla_type: List[HLAType],
return [hla_type for hla_type in assumed_hla_type
if hla_type.code == hla_antibody.code]

def fulfill_with_common_matches(antibody_hla_match, antibody_group_match):
common_matched_hla_types: List[HLAType] = get_hla_types_correspond_antibody(
antibody_hla_match.hla_type, antibody_group_match.hla_antibody
)
if len(common_matched_hla_types) > 0:
antibody_hla_match.hla_type = common_matched_hla_types
antibody_hla_match.antibody_matches.append(antibody_group_match)
def fulfill_with_common_matches(antibody_matches, crossmatched_antibodies):
for match_per_group in crossmatched_antibodies:
for antibody_group_match in match_per_group.antibody_matches:
raise_not_implemented_if_theoretical_antibody(antibody_group_match.hla_antibody)
for antibody_hla_match in antibody_matches:
common_matched_hla_types: List[HLAType] = get_hla_types_correspond_antibody(
antibody_hla_match.hla_type, antibody_group_match.hla_antibody
)
if len(common_matched_hla_types) > 0:
antibody_hla_match.hla_type = common_matched_hla_types
antibody_hla_match.antibody_matches.append(antibody_group_match)

def solve_uncrossmatched_hla_types(antibody_hla_matches: List[AntibodyMatchForHLAType]):
def convert_assumed_hla_type_to_split(antibody_hla_match):
Expand All @@ -90,15 +94,9 @@ def convert_assumed_hla_type_to_split(antibody_hla_match):
antibody_matches_for_hla_type = [AntibodyMatchForHLAType(
hla_type=[create_hla_type(raw_code=hla) for hla in hla_typing],
antibody_matches=[]) for hla_typing in crossmatch_dto.assumed_donor_hla_typing]
# TODO: validate (1.
# - ALL IN HIGH RES
# - ALL HAVE THE SAME LOW RES)
for match_per_group in crossmatched_antibodies_per_group:
for antibody_group_match in match_per_group.antibody_matches:
raise_not_implemented_if_theoretical_antibody(antibody_group_match.hla_antibody)
for antibody_hla_match in antibody_matches_for_hla_type:
fulfill_with_common_matches(antibody_hla_match, antibody_group_match)

fulfill_with_common_matches(antibody_matches_for_hla_type,
crossmatched_antibodies_per_group)
solve_uncrossmatched_hla_types(antibody_matches_for_hla_type) # TODO: rename?

typing_parsing_issues, _ = parse_hla_typing_raw_and_return_parsing_issue_list(
Expand Down

0 comments on commit ec974a4

Please sign in to comment.