Skip to content
Merged
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
8 changes: 8 additions & 0 deletions src/ga4gh/va_spec/ccv_2022/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
"""Module to load and init namespace at package level."""

from .derived_evidence import (
CODE_PREFIX_TO_SCORE_MAP,
CODE_SUFFIX_TO_STRENGTH_MAP,
derive_onco_evidence_attributes,
)
from .models import (
VariantOncogenicityEvidenceLine,
VariantOncogenicityStatement,
)

__all__ = [
"CODE_PREFIX_TO_SCORE_MAP",
"CODE_SUFFIX_TO_STRENGTH_MAP",
"derive_onco_evidence_attributes",
"VariantOncogenicityEvidenceLine",
"VariantOncogenicityStatement",
]
86 changes: 86 additions & 0 deletions src/ga4gh/va_spec/ccv_2022/derived_evidence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""Provide derived evidence attributes for an onco evidence code.

Can be used to populate `evidenceOutcome`, `strengthOfEvidenceProvided`, and
`scoreOfEvidenceProvided` fields in `VariantOncogenicityEvidenceLine`.
"""

from types import MappingProxyType

from pydantic import BaseModel

from ga4gh.core.models import Coding, MappableConcept, code
from ga4gh.va_spec.base import (
StrengthOfEvidenceProvided,
)
from ga4gh.va_spec.base.enums import System
from ga4gh.va_spec.ccv_2022.models import VariantOncogenicityEvidenceLine


class EvidenceAttributes(BaseModel):
"""Define derived evidence attributes for an onco evidence code."""

evidenceOutcome: MappableConcept
strengthOfEvidenceProvided: MappableConcept
scoreOfEvidenceProvided: int


# IMPORTANT: Don't change the order. Longer suffixes must be evaluated first.
CODE_SUFFIX_TO_STRENGTH_MAP = MappingProxyType(
{
"VS": StrengthOfEvidenceProvided.VERY_STRONG,
"S": StrengthOfEvidenceProvided.STRONG,
"M": StrengthOfEvidenceProvided.MODERATE,
"P": StrengthOfEvidenceProvided.SUPPORTING,
}
)


CODE_PREFIX_TO_SCORE_MAP = MappingProxyType(
{
"OVS": 8,
"SBVS": -8,
"OS": 4,
"SBS": -4,
"OM": 2,
"SBM": -2,
"OP": 1,
"SBP": -1,
}
)


def derive_onco_evidence_attributes(
evidence: VariantOncogenicityEvidenceLine.Criterion,
) -> EvidenceAttributes:
"""Derive evidence attributes given a CCV 2022 evidence code.

:param evidence: CCV 2022 evidence code
:return: Derived evidence attributes (evidenceOutcome, strengthOfEvidenceProvided,
scoreOfEvidenceProvided)
"""
evidence_code = evidence.value
normalized_evidence_code = evidence_code.rstrip("1234")

code_suffix = next(
suffix
for suffix in CODE_SUFFIX_TO_STRENGTH_MAP
if normalized_evidence_code.endswith(suffix)
)
code_prefix = next(
prefix
for prefix in CODE_PREFIX_TO_SCORE_MAP
if normalized_evidence_code.startswith(prefix)
)
system = System.CCV

return EvidenceAttributes(
evidenceOutcome=MappableConcept(
primaryCoding=Coding(code=code(evidence_code), system=system)
),
strengthOfEvidenceProvided=MappableConcept(
primaryCoding=Coding(
code=code(CODE_SUFFIX_TO_STRENGTH_MAP[code_suffix]), system=system
)
),
scoreOfEvidenceProvided=CODE_PREFIX_TO_SCORE_MAP[code_prefix],
)
116 changes: 116 additions & 0 deletions tests/test_ccv_derived_evidence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""Test that CCV 2022 derived evidence is working correctly"""

import pytest

from ga4gh.va_spec.ccv_2022 import (
VariantOncogenicityEvidenceLine,
derive_onco_evidence_attributes,
)


@pytest.mark.parametrize(
("criterion", "expected_strength", "expected_score"),
[
(
VariantOncogenicityEvidenceLine.Criterion.OP1,
"supporting",
1,
),
(
VariantOncogenicityEvidenceLine.Criterion.OP2,
"supporting",
1,
),
(
VariantOncogenicityEvidenceLine.Criterion.OP3,
"supporting",
1,
),
(
VariantOncogenicityEvidenceLine.Criterion.OP4,
"supporting",
1,
),
(
VariantOncogenicityEvidenceLine.Criterion.OM1,
"moderate",
2,
),
(
VariantOncogenicityEvidenceLine.Criterion.OM2,
"moderate",
2,
),
(
VariantOncogenicityEvidenceLine.Criterion.OM3,
"moderate",
2,
),
(
VariantOncogenicityEvidenceLine.Criterion.OM4,
"moderate",
2,
),
(
VariantOncogenicityEvidenceLine.Criterion.OS1,
"strong",
4,
),
(
VariantOncogenicityEvidenceLine.Criterion.OS2,
"strong",
4,
),
(
VariantOncogenicityEvidenceLine.Criterion.OS3,
"strong",
4,
),
(
VariantOncogenicityEvidenceLine.Criterion.OVS1,
"very strong",
8,
),
(
VariantOncogenicityEvidenceLine.Criterion.SBP1,
"supporting",
-1,
),
(
VariantOncogenicityEvidenceLine.Criterion.SBP2,
"supporting",
-1,
),
(
VariantOncogenicityEvidenceLine.Criterion.SBS1,
"strong",
-4,
),
(
VariantOncogenicityEvidenceLine.Criterion.SBS2,
"strong",
-4,
),
(
VariantOncogenicityEvidenceLine.Criterion.SBVS1,
"very strong",
-8,
),
],
)
def test_derive_onco_evidence_attributes(
criterion,
expected_strength,
expected_score,
):
"""Test that derive_onco_evidence_attributes works correctly"""
onco_evidence_attrs = derive_onco_evidence_attributes(criterion)

assert (
onco_evidence_attrs.evidenceOutcome.primaryCoding.code.root == criterion.value
)
assert (
onco_evidence_attrs.strengthOfEvidenceProvided.primaryCoding.code.root
== expected_strength
)
assert onco_evidence_attrs.scoreOfEvidenceProvided == expected_score
Loading