Coverage for linkage/matchresult.py: 81%

16 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-08-27 10:34 -0500

1r""" 

2crate_anon/linkage/matchresult.py 

3 

4=============================================================================== 

5 

6 Copyright (C) 2015, University of Cambridge, Department of Psychiatry. 

7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk). 

8 

9 This file is part of CRATE. 

10 

11 CRATE is free software: you can redistribute it and/or modify 

12 it under the terms of the GNU General Public License as published by 

13 the Free Software Foundation, either version 3 of the License, or 

14 (at your option) any later version. 

15 

16 CRATE is distributed in the hope that it will be useful, 

17 but WITHOUT ANY WARRANTY; without even the implied warranty of 

18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

19 GNU General Public License for more details. 

20 

21 You should have received a copy of the GNU General Public License 

22 along with CRATE. If not, see <https://www.gnu.org/licenses/>. 

23 

24=============================================================================== 

25 

26**Match result for fuzzy matching.** 

27 

28""" 

29 

30# ============================================================================= 

31# Imports 

32# ============================================================================= 

33 

34from crate_anon.linkage.constants import MINUS_INFINITY 

35from crate_anon.linkage.person import Person 

36 

37 

38# ============================================================================= 

39# Result of a match attempt 

40# ============================================================================= 

41 

42 

43class MatchResult: 

44 """ 

45 Result of a comparison between a proband (person) and a sample (group of 

46 people). 

47 """ 

48 

49 def __init__( 

50 self, 

51 winner: Person = None, 

52 best_log_odds: float = MINUS_INFINITY, 

53 second_best_log_odds: float = MINUS_INFINITY, 

54 best_candidate: Person = None, 

55 second_best_candidate: Person = None, 

56 proband: Person = None, 

57 ): 

58 """ 

59 Args: 

60 winner: 

61 The person in the sample (candidate) who matches the proband, 

62 if there is a winner by our rules; ``None`` if there is no 

63 winner. 

64 best_log_odds: 

65 Natural log odds of the best candidate being the same as the 

66 proband, –∞ if there are no candidates 

67 second_best_log_odds: 

68 The log odds of the closest other contender, which may be –∞. 

69 best_candidate: 

70 The person in the sample (candidate) who is the closest match 

71 to the proband. May be ``None``. If there is a winner, this is 

72 also the best person -- but the best person may not be the 

73 winner (if they are not likely enough, or if there is another 

74 close contender). 

75 second_best_candidate: 

76 The runner-up (second-best) candidate person, or ``None``. 

77 proband: 

78 The proband used for the comparison. (Helpful for parallel 

79 processing.) 

80 """ 

81 self.winner = winner 

82 self.best_log_odds = best_log_odds 

83 self.second_best_log_odds = second_best_log_odds 

84 self.best_candidate = best_candidate 

85 self.second_best_candidate = second_best_candidate 

86 self.proband = proband 

87 

88 @property 

89 def matched(self) -> bool: 

90 return self.winner is not None 

91 

92 def __repr__(self) -> str: 

93 attrs = [ 

94 f"winner={self.winner}", 

95 f"best_log_odds={self.best_log_odds}", 

96 f"second_best_log_odds={self.second_best_log_odds}", 

97 f"best_candidate={self.best_candidate}", 

98 f"second_best_candidate={self.second_best_candidate}", 

99 f"proband={self.proband}", 

100 ] 

101 return f"MatchResult({', '.join(attrs)}"