deepvaa-webapp / tools /acgs_points.py
Hong Ong
Implement One shot ACMG classification
c7b1d79
"""
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}