File size: 7,129 Bytes
c7b1d79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
"""
This module provides a function to calculate ACGS points for a given variant based on
the ACGS 2020 Best Practice Guidelines. Each criterion (e.g., PVS1, PS1, BS1, BP1, etc.)
is mapped to a point score reflecting its weight in the ACGS system.
"""

from typing import List, Dict

# Mapping of criteria to their ACGS points, strengths, and short descriptions.
ACGS_CRITERIA = {
    "PVS1": {
        "score": 8,
        "classification": "Pathogenic",
        "strength": "Very Strong",
        "description": "Predicted null variant in a gene where LOF is a known mechanism",
    },
    "PS1": {
        "score": 4,
        "classification": "Pathogenic",
        "strength": "Strong",
        "description": "Same amino acid change as a known pathogenic variant",
    },
    "PS2": {
        "score": 4,
        "classification": "Pathogenic",
        "strength": "Strong",
        "description": "De novo (confirmed parentage) in a patient with the disease",
    },
    "PS3": {
        "score": 4,
        "classification": "Pathogenic",
        "strength": "Strong",
        "description": "Well-established functional studies show damaging effect",
    },
    "PS4": {
        "score": 4,
        "classification": "Pathogenic",
        "strength": "Strong",
        "description": "Significantly increased prevalence in affected individuals vs. controls",
    },
    "PM1": {
        "score": 2,
        "classification": "Pathogenic",
        "strength": "Moderate",
        "description": "Located in a critical functional domain/hot spot",
    },
    "PM2": {
        "score": 2,
        "classification": "Pathogenic",
        "strength": "Moderate",
        "description": "Absent (or extremely low frequency) in population databases",
    },
    "PM3": {
        "score": 2,
        "classification": "Pathogenic",
        "strength": "Moderate",
        "description": "For recessive disorders: in trans with a known pathogenic variant",
    },
    "PM4": {
        "score": 2,
        "classification": "Pathogenic",
        "strength": "Moderate",
        "description": "Protein length changes due to in-frame indels/stop-loss",
    },
    "PM5": {
        "score": 2,
        "classification": "Pathogenic",
        "strength": "Moderate",
        "description": "Novel missense change at a residue where a different pathogenic missense has been seen",
    },
    "PM6": {
        "score": 2,
        "classification": "Pathogenic",
        "strength": "Moderate",
        "description": "Assumed de novo without confirmation of parentage",
    },
    "PP1": {
        "score": 1,
        "classification": "Pathogenic",
        "strength": "Supporting",
        "description": "Cosegregation with disease in multiple affected family members",
    },
    "PP2": {
        "score": 1,
        "classification": "Pathogenic",
        "strength": "Supporting",
        "description": "Missense variant in a gene with low benign missense rate and known disease mechanism",
    },
    "PP3": {
        "score": 1,
        "classification": "Pathogenic",
        "strength": "Supporting",
        "description": "Multiple computational predictions support a deleterious effect",
    },
    "PP4": {
        "score": 1,
        "classification": "Pathogenic",
        "strength": "Supporting",
        "description": "Patient phenotype or family history highly specific for this disease",
    },
    "PP5": {
        "score": 1,
        "classification": "Pathogenic",
        "strength": "Supporting",
        "description": "Reputable source reports variant as pathogenic without accessible data",
    },
    "BA1": {
        "score": -8,
        "classification": "Benign",
        "strength": "Stand-alone",
        "description": "Allele frequency >5% in general population databases",
    },
    "BS1": {
        "score": -4,
        "classification": "Benign",
        "strength": "Strong",
        "description": "Allele frequency higher than expected for disorder",
    },
    "BS2": {
        "score": -4,
        "classification": "Benign",
        "strength": "Strong",
        "description": "Observed in healthy adult (homozygous or hemizygous) for fully penetrant disease",
    },
    "BS3": {
        "score": -4,
        "classification": "Benign",
        "strength": "Strong",
        "description": "Well-established functional studies show no damaging effect",
    },
    "BS4": {
        "score": -4,
        "classification": "Benign",
        "strength": "Strong",
        "description": "Lack of segregation in affected family members",
    },
    "BP1": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "Missense variant in a gene where truncating variants cause disease",
    },
    "BP2": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "Observed in trans with a pathogenic variant for a dominant disorder or in cis with a pathogenic variant",
    },
    "BP3": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "In-frame indel/dup in a repetitive region without known function",
    },
    "BP4": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "Multiple computational predictions support no impact",
    },
    "BP5": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "Variant found in a case with an alternate molecular explanation",
    },
    "BP6": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "Reputable source reports variant as benign without accessible data",
    },
    "BP7": {
        "score": -1,
        "classification": "Benign",
        "strength": "Supporting",
        "description": "Silent or non-coding variant with no predicted splice impact and not highly conserved",
    },
}


def calculate_acgs_points(criteria_list: List[str]) -> Dict[str, object]:
    """
    Calculate the cumulative ACGS points for a variant based on the criteria codes provided.

    Parameters:
        criteria_list (List[str]): A list of criterion codes (e.g., ["PVS1", "PM2", "BS1"]).

    Returns:
        Dict[str, object]: A dictionary containing a breakdown of points by criterion and the total score.
        Example:
        {
            "points_breakdown": {"PVS1": 8, "PM2": 2},
            "total_points": 10
        }
    """
    points_breakdown = {}
    total_points = 0

    for criterion in criteria_list:
        # Retrieve the point score if available; otherwise assume 0 for unknown codes.
        if criterion in ACGS_CRITERIA:
            score = ACGS_CRITERIA[criterion]["score"]
            points_breakdown[criterion] = score
            total_points += score
        else:
            # Unknown codes are flagged with 0 points.
            points_breakdown[criterion] = 0

    return {"points_breakdown": points_breakdown, "total_points": total_points}