Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 16 additions & 20 deletions classification/admin/classification_admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from collections.abc import Callable
from datetime import timedelta
from typing import Optional, Union

Expand Down Expand Up @@ -738,7 +739,9 @@ def cs_to_index():
return EvidenceKeyMap.cached_key(SpecialEKeys.CLINICAL_SIGNIFICANCE).option_dictionary_property("vg")

@staticmethod
def _less_more_certain(summary: DiscordanceLabSummary):
def _describe_movement(summary: DiscordanceLabSummary, describe: Callable[[int, int], str]) -> str:
""" Handles the cases where the two clinical significances can't be compared (withdrawn, unchanged,
or one of them not on the vg scale), otherwise describe() names the direction travelled """
cs_to_index = DiscordanceReportAdminExport.cs_to_index()
from_value = int(cs_to_index.get(summary.clinical_significance_from, "0"))
to_value = int(cs_to_index.get(summary.clinical_significance_to, "0"))
Expand All @@ -749,29 +752,22 @@ def _less_more_certain(summary: DiscordanceLabSummary):
return "same"
elif from_value == 0 or to_value == 0:
return "?"
else:
if abs(to_value - 3) > abs(from_value - 3):
return "more"
else:
return "less"
return describe(from_value, to_value)

@staticmethod
def _less_more_certain(summary: DiscordanceLabSummary):
# VUS is the middle of the vg scale, so distance from it is how certain the call is
def describe(from_value: int, to_value: int) -> str:
return "more" if abs(to_value - 3) > abs(from_value - 3) else "less"

return DiscordanceReportAdminExport._describe_movement(summary, describe)

@staticmethod
def _up_down_for(summary: DiscordanceLabSummary):
cs_to_index = DiscordanceReportAdminExport.cs_to_index()
from_value = int(cs_to_index.get(summary.clinical_significance_from, "0"))
to_value = int(cs_to_index.get(summary.clinical_significance_to, "0"))
def describe(from_value: int, to_value: int) -> str:
return "upgrade" if to_value > from_value else "downgrade"

if summary.clinical_significance_to == 'withdrawn':
return "withdrawn"
elif from_value == to_value:
return "same"
elif from_value == 0 or to_value == 0:
return "?"
else:
if to_value > from_value:
return "upgrade"
else:
return "downgrade"
return DiscordanceReportAdminExport._describe_movement(summary, describe)

def __init__(self, discordance_report: DiscordanceReport, perspective: LabPickerData):
self.discordance_report = discordance_report
Expand Down
49 changes: 0 additions & 49 deletions classification/management/commands/evidence_key_cleaner.py

This file was deleted.

41 changes: 0 additions & 41 deletions classification/models/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -2028,47 +2028,6 @@ def get_visible_evidence(self, evidence, lowest_share_level: ShareLevel) -> dict
visible_evidence[k] = {'value': "(hidden)", 'hidden': True}
return visible_evidence

def get_allele_info_dict(self) -> Optional[dict[str, Any]]:
allele_info_dict = {}
if allele_info := self.allele_info:
resolved_dict = {
"allele_id": allele_info.allele_id,
"allele_info_id": allele_info.id,
"allele_info_status": allele_info.status,
"status": allele_info.status,
"include": allele_info.latest_validation.include if allele_info.latest_validation else None,
"variant_coordinate": allele_info.variant_coordinate
}

if (genome_build := self.get_genome_build_opt()) and \
(preferred_build := allele_info[genome_build]) and \
(c_hgvs := preferred_build.c_hgvs_display):
resolved_dict.update(c_hgvs.to_json())
elif c_hgvs_raw := self.get(SpecialEKeys.C_HGVS):
resolved_dict.update(HGVSDisplay.parse(c_hgvs_raw).to_json())

include = False
if latest_validation := allele_info.latest_validation:
include = latest_validation.include

resolved_dict["include"] = include
if warning_icon := ImportedAlleleInfo.icon_for(status=allele_info.status, include=include):
resolved_dict.update(warning_icon.as_json())

allele_info_dict["resolved"] = resolved_dict

genome_builds = {}
for variant_info in allele_info.resolved_builds:
genome_builds[variant_info.genome_build.name] = {
'variant_id': variant_info.variant_id,
SpecialEKeys.C_HGVS: variant_info.c_hgvs
}

if genome_builds:
allele_info_dict["genome_builds"] = genome_builds

return allele_info_dict

@staticmethod
def get_url_for_pk(pk):
return reverse('view_classification', kwargs={'classification_id': pk})
Expand Down
22 changes: 2 additions & 20 deletions classification/models/classification_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from more_itertools import first

from classification.criteria_strengths import CriteriaStrength
from classification.enums import CriteriaEvaluation, ShareLevel, SpecialEKeys
from classification.enums import ShareLevel, SpecialEKeys
from classification.models import (
ClassificationModification,
ConditionResolved,
Expand Down Expand Up @@ -371,25 +371,7 @@ def count(self) -> int:

@cached_property
def acmg_criteria(self) -> MultiValues[CriteriaStrength]:

def criteria_converter(cm: ClassificationModification) -> set[CriteriaStrength]:
strengths: set[CriteriaStrength] = set()
for e_key in EvidenceKeyMap.cached().criteria():
strength = cm.get(e_key.key)
if CriteriaEvaluation.is_met(strength):
strengths.add(CriteriaStrength(e_key, strength))
for amp_level, letter in SpecialEKeys.AMP_LEVELS_TO_LEVEL.items():
if value := cm.get_value_list(amp_level):
e_key = EvidenceKeyMap.cached_key(amp_level)
for sub_value in value:
sub_value_label = e_key.pretty_value(sub_value)
strengths.add(CriteriaStrength(
ekey=EvidenceKeyMap.cached_key(amp_level),
custom_strength=f"{letter}_{sub_value_label}")
)
return strengths
output = MultiValues.convert([criteria_converter(cm) for cm in self.modifications])
return output
return MultiValues.convert([cm.met_criteria_strengths() for cm in self.modifications])

def _evidence_key_set(self, key: str) -> list[str]:
all_values = set()
Expand Down
20 changes: 19 additions & 1 deletion classification/models/evidence_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from annotation.models import CitationFetchRequest
from annotation.models.models_citations import CitationFetchResponse
from classification.criteria_strengths import CriteriaStrength, CriteriaStrengths
from classification.enums import AlleleOriginBucket, SpecialEKeys
from classification.enums import AlleleOriginBucket, CriteriaEvaluation, SpecialEKeys
from genes.hgvs import HGVSComponents, PHGVS
from library.log_utils import report_message
from library.utils import empty_to_none
Expand Down Expand Up @@ -221,6 +221,24 @@ def criteria_strengths(self, e_keys: Optional['EvidenceKeyMap'] = None) -> Crite

return CriteriaStrengths(strengths=criteria, is_acmg_standard=self.is_likely_acmg)

def met_criteria_strengths(self) -> set[CriteriaStrength]:
""" Criteria that were actually met, plus one per somatic AMP level value selected """
from classification.models import EvidenceKeyMap

strengths: set[CriteriaStrength] = set()
for e_key in EvidenceKeyMap.cached().criteria():
strength = self.get(e_key.key)
if CriteriaEvaluation.is_met(strength):
strengths.add(CriteriaStrength(e_key, strength))
for amp_level, letter in SpecialEKeys.AMP_LEVELS_TO_LEVEL.items():
if value := self.get_value_list(amp_level):
e_key = EvidenceKeyMap.cached_key(amp_level)
for sub_value in value:
sub_value_label = e_key.pretty_value(sub_value)
strengths.add(CriteriaStrength(ekey=e_key,
custom_strength=f"{letter}_{sub_value_label}"))
return strengths

def criteria_strength_summary(self, ekeys: Optional['EvidenceKeyMap'] = None, only_acmg: bool = False) -> str:
strengths = self.criteria_strengths(e_keys=ekeys)
return strengths.summary_string(acmg_only=only_acmg)
Expand Down
21 changes: 2 additions & 19 deletions classification/models/evidence_mixin_summary_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
from functools import cached_property
from typing import Optional, Self, TypedDict

from classification.criteria_strengths import CriteriaStrength
from classification.enums import AlleleOriginBucket, CriteriaEvaluation, SpecialEKeys
from classification.enums import AlleleOriginBucket, SpecialEKeys
from classification.models.evidence_key import EvidenceKeyMap
from library.utils import strip_json

Expand Down Expand Up @@ -207,20 +206,4 @@ def somatic_sort(self) -> Optional[int]:

@cached_property
def criteria_labels(self) -> list[str]:
from classification.models import EvidenceKeyMap
cm = self.cm
strengths: set[CriteriaStrength] = set()
for e_key in EvidenceKeyMap.cached().criteria():
strength = cm.get(e_key.key)
if CriteriaEvaluation.is_met(strength):
strengths.add(CriteriaStrength(e_key, strength))
for amp_level, letter in SpecialEKeys.AMP_LEVELS_TO_LEVEL.items():
if value := cm.get_value_list(amp_level):
e_key = EvidenceKeyMap.cached_key(amp_level)
for sub_value in value:
sub_value_label = e_key.pretty_value(sub_value)
strengths.add(CriteriaStrength(
ekey=EvidenceKeyMap.cached_key(amp_level),
custom_strength=f"{letter}_{sub_value_label}")
)
return list(str(x) for x in sorted(strengths))
return [str(x) for x in sorted(self.cm.met_criteria_strengths())]
Loading