|
25 | 25 | import re |
26 | 26 | import sqlite3 |
27 | 27 | import sys |
| 28 | +from collections import Counter |
28 | 29 | from typing import Iterable, List |
29 | 30 |
|
30 | 31 | from . import broad_splits, smart_sort |
@@ -487,12 +488,38 @@ def is_mac(self, allele: str) -> bool: |
487 | 488 | :return: True if MAC |
488 | 489 | """ |
489 | 490 | if ":" in allele: |
490 | | - code = allele.split(":")[1] |
491 | | - try: |
| 491 | + allele_split = allele.split(":") |
| 492 | + if len(allele_split) == 2: # MACs have only single : |
| 493 | + locus_antigen, code = allele.split(":") |
492 | 494 | if code.isalpha(): |
493 | | - return db.is_valid_mac_code(self.db_connection, code) |
494 | | - except sqlite3.OperationalError as e: |
495 | | - print("Error: ", e) |
| 495 | + try: |
| 496 | + alleles = db.mac_code_to_alleles(self.db_connection, code) |
| 497 | + if alleles: |
| 498 | + if any(map(lambda a: ":" in a, alleles)): |
| 499 | + # allele specific antigen codes has ':' in the MAC mapping |
| 500 | + # e.g. CFWRN -> 15:01/15:98/15:157/15:202/ |
| 501 | + # 15:239/15:280/15:340/35:43/35:67/35:79/35:102/35:118/35:185/51:220 |
| 502 | + antigen_groups = map(lambda a: a.split(":")[0], alleles) |
| 503 | + # Rule 1: The 1st field with the most allele designations in the request is |
| 504 | + # the 1st field of the allele code designation |
| 505 | + # Rule 2: If there is a tie in the number of alleles designations sharing the 1st field, |
| 506 | + # the 1st field with the lowest numeric value is selected. |
| 507 | + antigen_counts = Counter(antigen_groups) |
| 508 | + # Create a table of antigen to it's counts |
| 509 | + # '15': 7 |
| 510 | + # '35': 6 |
| 511 | + # '51': 1 |
| 512 | + # Valid antigen is the first most common one. |
| 513 | + # As it's presorted in db, also satisfies Rule 2. |
| 514 | + valid_antigen = antigen_counts.most_common(1).pop()[0] |
| 515 | + # Get antigen value 15 from 'DRB1*15' |
| 516 | + provided_antigen = locus_antigen.split("*").pop() |
| 517 | + # The MAC is only valid if the given antigen satisfies the antigen matching Rule 1 and 2 |
| 518 | + return provided_antigen == valid_antigen |
| 519 | + # Valid when antigen group codes |
| 520 | + return True |
| 521 | + except sqlite3.OperationalError as e: |
| 522 | + print("Error: ", e) |
496 | 523 | return False |
497 | 524 |
|
498 | 525 | def is_v2(self, allele: str) -> bool: |
|
0 commit comments