Skip to content

Commit

Permalink
Update README and rename 'issues' in summary to 'details_and_issues'.
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubmonhart committed Jul 4, 2023
1 parent 69dbc76 commit 252877d
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 92 deletions.
17 changes: 17 additions & 0 deletions documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,23 @@ Priority is arranged in the following way:
For example, if some antibodies crossmatched at the `HIGH RES` level, others at the `SPLIT` level,
then the summary match type would be `HIGH RES` as the most important of these.

As the eight possible match types above do not always describe the situation exactly, we do not display it in the summary.
Instead, we send a message describing the crossmatch type together with some possible issues in the `details_and_issues`
property of the summary.
We do this mainly to distinguish two types of HIGH_RES match that can occur.

If the HIGH_RES match occurs due to a single HIGH RES antibody matching to single HIGH RES antigen, we send a message:
`There is a single positively crossmatched HIGH RES HLA type - HIGH RES antibody pair.`
, if there are multiple antibody - antigen pairs, we send a different message informing about this: `SPLIT HLA code
displayed in summary, but there are multiple positive crossmatches of HIGH RES HLA type - HIGH RES antibody pairs.`

HIGH_RES match can also occur if all positive HIGH RES antibodies correspond to an antigen on SPLIT level (satisfying
some more conditions, described as case 2. and 3. in the `HIGH_RES` match description above in this documentation).
In this case we send a message saying: `There is no exact match, but some of the HIGH RES antibodies corresponding to
the summary HLA code on SPLIT or BROAD level are positive.`

The rest of match types are described with corresponding messages in a straightforward manner.

#### How to choose summary HLA code?
For summary, we would like to take into account just frequent codes among all assumed HLA types.
When this code is the only one, then everything is quite simple, we consider this code as a summary,
Expand Down
54 changes: 27 additions & 27 deletions tests/web/test_do_crossmatch_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from txmatching.patients.hla_code import HLACode
from txmatching.patients.hla_model import HLATypeWithFrequencyRaw
from txmatching.utils.hla_system.hla_crossmatch import CrossmatchSummary, \
CadaverousCrossmatchIssueDetail
CadaverousCrossmatchDetailsIssues
from txmatching.utils.hla_system.hla_preparation_utils import create_hla_type_with_frequency
from txmatching.utils.hla_system.hla_transformations.parsing_issue_detail import \
ParsingIssueDetail
Expand Down Expand Up @@ -664,12 +664,12 @@ def test_do_crossmatch_for_assumed_hla_types(self):
res_assumed_hla_typing = [antibody_match['assumed_hla_types']
for antibody_match in res.json['hla_to_antibody']]
res_crossmatch_issues = [issue for antibody_match in res.json['hla_to_antibody']
for issue in antibody_match['summary']['issues']]
for issue in antibody_match['summary']['details_and_issues']]
expected_assumed_hla_typing = [
[asdict(create_hla_type_with_frequency(HLATypeWithFrequencyRaw('DPA1*01:03', True))),
asdict(create_hla_type_with_frequency(HLATypeWithFrequencyRaw('DPA1*01:06', True)))]
]
self.assertFalse(CadaverousCrossmatchIssueDetail.RARE_ALLELE_POSITIVE_CROSSMATCH
self.assertFalse(CadaverousCrossmatchDetailsIssues.RARE_ALLELE_POSITIVE_CROSSMATCH
in res_crossmatch_issues)
self.assertTrue(len(res_assumed_hla_typing) == len(json['potential_donor_hla_typing']))
self.assertCountEqual(expected_assumed_hla_typing,
Expand All @@ -696,13 +696,13 @@ def test_do_crossmatch_for_assumed_hla_types(self):

res_assumed_hla_types = res.json['hla_to_antibody'][0]['assumed_hla_types']
res_crossmatch_issues = [issue for antibody_match in res.json['hla_to_antibody']
for issue in antibody_match['summary']['issues']]
for issue in antibody_match['summary']['details_and_issues']]
# Here, the code is evaluated as infrequent because the potential typing comprises a mix of
# frequent and infrequent codes, and a crossmatch occurred only with the infrequent one.
expected_assumed_hla_types = \
[asdict(create_hla_type_with_frequency(HLATypeWithFrequencyRaw('DPA1*01:04', False))),
asdict(create_hla_type_with_frequency(HLATypeWithFrequencyRaw('DPA1*01:03', True)))]
self.assertTrue(CadaverousCrossmatchIssueDetail.RARE_ALLELE_POSITIVE_CROSSMATCH
self.assertTrue(CadaverousCrossmatchDetailsIssues.RARE_ALLELE_POSITIVE_CROSSMATCH
in res_crossmatch_issues)
self.assertTrue(len(res_assumed_hla_typing) == len(json['potential_donor_hla_typing']))
self.assertCountEqual(expected_assumed_hla_types,
Expand Down Expand Up @@ -762,8 +762,8 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res=None, split='DPA1'),
mfi=2075,
issues=[CadaverousCrossmatchIssueDetail.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchIssueDetail.ANTIBODIES_MIGHT_NOT_BE_DSA]
details_and_issues=[CadaverousCrossmatchDetailsIssues.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchDetailsIssues.ANTIBODIES_MIGHT_NOT_BE_DSA]
)
self.assertEqual(asdict(expected_summary),
res.json['hla_to_antibody'][0]['summary'])
Expand All @@ -778,7 +778,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=antibody_match_without_crossmatched_antibodies['assumed_hla_types'][0],
mfi=None,
issues=[CadaverousCrossmatchIssueDetail.NO_MATCHING_ANTIBODY]
details_and_issues=[CadaverousCrossmatchDetailsIssues.NO_MATCHING_ANTIBODY]
)
self.assertCountEqual(
asdict(expected_summary),
Expand Down Expand Up @@ -809,8 +809,8 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res=None, split='DPA1'),
mfi=2150,
issues=[CadaverousCrossmatchIssueDetail.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchIssueDetail.ANTIBODIES_MIGHT_NOT_BE_DSA]
details_and_issues=[CadaverousCrossmatchDetailsIssues.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchDetailsIssues.ANTIBODIES_MIGHT_NOT_BE_DSA]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -839,8 +839,8 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res='DPA1*01:03', split='DPA1'),
mfi=2200,
issues=[CadaverousCrossmatchIssueDetail.HIGH_RES_MATCH,
CadaverousCrossmatchIssueDetail.ANTIBODIES_MIGHT_NOT_BE_DSA]
details_and_issues=[CadaverousCrossmatchDetailsIssues.HIGH_RES_MATCH,
CadaverousCrossmatchDetailsIssues.ANTIBODIES_MIGHT_NOT_BE_DSA]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -868,7 +868,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res=None, split='DPA1'),
mfi=2100,
issues=[CadaverousCrossmatchIssueDetail.RARE_ALLELE_POSITIVE_CROSSMATCH]
details_and_issues=[CadaverousCrossmatchDetailsIssues.RARE_ALLELE_POSITIVE_CROSSMATCH]
)
self.assertEqual(res_summaries, [asdict(expected_summary)])

Expand Down Expand Up @@ -899,7 +899,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res=None, split='DPA1'),
mfi=3333,
issues=[CadaverousCrossmatchIssueDetail.SPLIT_BROAD_MATCH]
details_and_issues=[CadaverousCrossmatchDetailsIssues.SPLIT_BROAD_MATCH]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -930,7 +930,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res=None, split='DPA1'),
mfi=3500,
issues=[CadaverousCrossmatchIssueDetail.HIGH_RES_MATCH_ON_SPLIT_LEVEL]
details_and_issues=[CadaverousCrossmatchDetailsIssues.HIGH_RES_MATCH_ON_SPLIT_LEVEL]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -960,7 +960,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA2', high_res=None, split='DPA2'),
mfi=5000,
issues=[CadaverousCrossmatchIssueDetail.HIGH_RES_MATCH_ON_SPLIT_LEVEL]
details_and_issues=[CadaverousCrossmatchDetailsIssues.HIGH_RES_MATCH_ON_SPLIT_LEVEL]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -991,8 +991,8 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='B7', high_res=None, split='B7'),
mfi=3000,
issues=[CadaverousCrossmatchIssueDetail.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchIssueDetail.ANTIBODIES_MIGHT_NOT_BE_DSA]
details_and_issues=[CadaverousCrossmatchDetailsIssues.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchDetailsIssues.ANTIBODIES_MIGHT_NOT_BE_DSA]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -1023,8 +1023,8 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='B7', high_res=None, split='B7'),
mfi=3000,
issues=[CadaverousCrossmatchIssueDetail.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchIssueDetail.AMBIGUITY_IN_HLA_TYPIZATION]
details_and_issues=[CadaverousCrossmatchDetailsIssues.MULTIPLE_HIGH_RES_MATCH,
CadaverousCrossmatchDetailsIssues.AMBIGUITY_IN_HLA_TYPIZATION]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand All @@ -1046,7 +1046,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res='DPA1*01:03', split='DPA1'),
mfi=2000,
issues=[CadaverousCrossmatchIssueDetail.HIGH_RES_MATCH]
details_and_issues=[CadaverousCrossmatchDetailsIssues.HIGH_RES_MATCH]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand All @@ -1068,7 +1068,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='DPA1', high_res=None, split='DPA1'),
mfi=1000,
issues=[CadaverousCrossmatchIssueDetail.NEGATIVE_ANTIBODY_IN_SUMMARY]
details_and_issues=[CadaverousCrossmatchDetailsIssues.NEGATIVE_ANTIBODY_IN_SUMMARY]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand All @@ -1093,7 +1093,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='B7', high_res=None, split='B7'),
mfi=1500,
issues=[CadaverousCrossmatchIssueDetail.NEGATIVE_ANTIBODY_IN_SUMMARY]
details_and_issues=[CadaverousCrossmatchDetailsIssues.NEGATIVE_ANTIBODY_IN_SUMMARY]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand All @@ -1117,7 +1117,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='B7', high_res=None, split='B7'),
mfi=1500,
issues=[CadaverousCrossmatchIssueDetail.NEGATIVE_ANTIBODY_IN_SUMMARY]
details_and_issues=[CadaverousCrossmatchDetailsIssues.NEGATIVE_ANTIBODY_IN_SUMMARY]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand All @@ -1138,7 +1138,7 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad=None, high_res='A*01:01N', split=None),
mfi=None,
issues=[CadaverousCrossmatchIssueDetail.NO_MATCHING_ANTIBODY]
details_and_issues=[CadaverousCrossmatchDetailsIssues.NO_MATCHING_ANTIBODY]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down Expand Up @@ -1166,8 +1166,8 @@ def test_summary(self):
expected_summary = CrossmatchSummary(
hla_code=HLACode(broad='A2', high_res=None, split='A2'),
mfi=3000,
issues=[CadaverousCrossmatchIssueDetail.SPLIT_BROAD_MATCH,
CadaverousCrossmatchIssueDetail.ANTIBODIES_MIGHT_NOT_BE_DSA]
details_and_issues=[CadaverousCrossmatchDetailsIssues.SPLIT_BROAD_MATCH,
CadaverousCrossmatchDetailsIssues.ANTIBODIES_MIGHT_NOT_BE_DSA]
)
self.assertEqual(res_summary, [asdict(expected_summary)])

Expand Down
12 changes: 6 additions & 6 deletions txmatching/data_transfer_objects/base_patient_swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@
'split': 'A1'
},
'mfi': 3000,
'issues': ['Antibodies against this HLA Type might not be DSA, for more '
'see detailed section.']
'details_and_issues': ['Antibodies against this HLA Type might not be DSA, for more '
'see detailed section.']
}
},
{
Expand Down Expand Up @@ -247,7 +247,7 @@
'split': 'B7'
},
'mfi': 2000,
'issues': []
'details_and_issues': []
}
},
{
Expand Down Expand Up @@ -332,8 +332,8 @@
'split': 'DR15'
},
'mfi': 3000,
'issues': ['Antibodies against this HLA Type might not be DSA, for more '
'see detailed section.']
'details_and_issues': ['Antibodies against this HLA Type might not be DSA, for more '
'see detailed section.']
}
},
{
Expand Down Expand Up @@ -418,7 +418,7 @@
'split': 'DPA2'
},
'mfi': 3000,
'issues': []
'details_and_issues': []
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
ParsingIssueBaseJson
from txmatching.data_transfer_objects.matchings.matching_swagger import \
AntibodyMatchJson
from txmatching.utils.hla_system.hla_crossmatch import CadaverousCrossmatchIssueDetail
from txmatching.utils.hla_system.hla_crossmatch import CadaverousCrossmatchDetailsIssues
from txmatching.web.web_utils.namespaces import crossmatch_api

HLACode = crossmatch_api.clone('HlaCode', HLACode)
Expand All @@ -34,8 +34,8 @@
{
'hla_code': fields.Nested(HLACode, required=True),
'mfi': fields.Integer(reqired=False),
'issues': fields.List(required=False, cls_or_instance=fields.String(
required=False, enum=[issue.value for issue in CadaverousCrossmatchIssueDetail]))
'details_and_issues': fields.List(required=False, cls_or_instance=fields.String(
required=False, enum=[issue.value for issue in CadaverousCrossmatchDetailsIssues]))
}
)

Expand Down
Loading

0 comments on commit 252877d

Please sign in to comment.