Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance general output of acmg prediction #128

Merged
merged 10 commits into from
Jun 10, 2024
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: 7 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ If you want to **use** auto-acmg, the best place is to start at :ref:`dev_quicks
acmg_pvs1
acmg_pvs1_algorithm_details

.. toctree::
:maxdepth: 2
:caption: Usage:

usage

.. toctree::
:maxdepth: 2
:caption: Development:
Expand All @@ -28,4 +34,4 @@ If you want to **use** auto-acmg, the best place is to start at :ref:`dev_quicks
:maxdepth: 2
:caption: API Documentation:

api_reference
api_reference
269 changes: 269 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
.. _usage:

=====
Usage
=====

The following section describe the usage of the AutoACMG package.

.. _installation:

Installation
------------
TODO

.. _configuration:

Configuration
-------------

To run the AutoACMG package, you'll need to create config. Example one can be found in
`.env.dev`. Change the settings to match your environment.

.. code-block:: bash

cp .env.dev .env

.. _running:

Running
-------

To run the AutoACMG package, you'll need to run the following command:

.. code-block:: bash

make run VAR=<variant_name> GR=<genome_release>

Where:
- ``<variant_name>`` is the name of the variant you want to analyze.
- ``<genome_release>`` is the genome release you want to use.

Alternatively you can use it inline:

.. code-block:: python

from src.auto_acmg import AutoACMG

autoacmg = AutoACMG(variant_name, genome_release)
prediction = autoacmg.predict()

Note that the ``predict`` method will return a dictionary with the prediction.
This dictionary contains all ACMG criteria with their:
- ``name``: the name of the ACMG criteria.
- ``prediction``: the prediction of the ACMG criteria.
- ``summary``: the details of the prediction.
- ``description``: the description of the ACMG criteria.

The valid values for the ``prediction`` are:
- ``NotSet``: the ACMG criteria was not set (also due to errors).
- ``Positive``: the ACMG criteria is positive.
- ``Negative``: the ACMG criteria is negative.
- ``NotAutomated``: the ACMG criteria is not automated (e.g. due to the need of manual curation).
- ``NotApplicable``: the ACMG criteria is not applicable.
- ``Depricated``: the ACMG criteria is depricated (e.g. PP5 or BP6).

The evidence level and the prediction path for the PVS1 ACMG criteria is returned at the summary
field in regards to "PVS1 Paper". The values represent the following:

For evidence level:
- ``NotSet``: the evidence level was not set (also due to errors).
- ``PVS1``: the strongest evidence level.
- ``PVS1_Strong``: the strong evidence level.
- ``PVS1_Moderate``: the moderate evidence level.
- ``PVS1_Supporting``: the supporting evidence level.
- ``NotPVS1``: the evidence level is not PVS1.
- ``UnsupportedConsequence``: PVS1 is not applicable due to unsupported consequence.

For prediction path:

.. code-block:: python

#: Mapping of PVS1 prediction path to description for sequence variant
PVS1PredictionPathMapping: Dict[
Union[PVS1PredictionSeqVarPath, PVS1PredictionStrucVarPath], str
] = {
PVS1PredictionSeqVarPath.NotSet: "Not Set",
PVS1PredictionSeqVarPath.PTEN: "Special guideline for PTEN -> Predicted to undergo NMD",
PVS1PredictionSeqVarPath.NF1: (
"Predicted to undergo NMD -> Exon is present in biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.NF2: (
"Predicted to undergo NMD -> Exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.NF3: (
"Not predicted to undergo NMD -> "
"Truncated/altered region is critical to protein function"
),
PVS1PredictionSeqVarPath.NF4: (
"Not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are frequent in the general population and/or "
"exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.NF5: (
"Not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes >10% of protein"
),
PVS1PredictionSeqVarPath.NF6: (
"Not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes <10% of protein"
),
PVS1PredictionSeqVarPath.SS1: (
"Exon skipping or use of a cryptic slice site disrupts reading frame and "
"is predicted to undergo NMD -> "
"Exon is present in biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.SS2: (
"Exon skipping or use of a cryptic slice site disrupts reading frame and "
"is predicted to undergo NMD -> "
"Exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.SS3: (
"Exon skipping or use of a cryptic slice site disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Truncated/altered region is critical to protein function"
),
PVS1PredictionSeqVarPath.SS4: (
"Exon skipping or use of a cryptic slice site disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are frequent in the general population and/or "
"exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.SS5: (
"Exon skipping or use of a cryptic slice site disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes >10% of protein"
),
PVS1PredictionSeqVarPath.SS6: (
"Exon skipping or use of a cryptic slice site disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes <10% of protein"
),
PVS1PredictionSeqVarPath.SS7: (
"Exon skipping or use of a cryptic slice site preserves reading frame -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are frequent in the general population and/or "
"exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionSeqVarPath.SS8: (
"Exon skipping or use of a cryptic slice site preserves reading frame -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes >10% of protein"
),
PVS1PredictionSeqVarPath.SS9: (
"Exon skipping or use of a cryptic slice site preserves reading frame -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes <10% of protein"
),
PVS1PredictionSeqVarPath.SS10: (
"Exon skipping or use of a cryptic slice site preserves reading frame -> "
"Truncated/altered region is critical to protein function"
),
PVS1PredictionSeqVarPath.IC1: (
"No known alternative start codon in other transcripts -> "
">=1 pathogenic variant(s) upstream of closest potential in-frame start codon"
),
PVS1PredictionSeqVarPath.IC2: (
"No known alternative start codon in other transcripts -> "
"No pathogenic variant(s) upstream of closest potential in-frame start codon"
),
PVS1PredictionSeqVarPath.IC3: "Different functional transcript uses alternative start codon",
PVS1PredictionStrucVarPath.NotSet: "Not Set",
PVS1PredictionStrucVarPath.DEL1: "Full gene deletion",
PVS1PredictionStrucVarPath.DEL2: (
"Single to multi exon deletion disrupts reading frame and "
"is predicted to undergo NMD -> "
"Exon is present in biologically-relevant transcript(s)"
),
PVS1PredictionStrucVarPath.DEL3: (
"Single to multi exon deletion disrupts reading frame and "
"is predicted to undergo NMD -> "
"Exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionStrucVarPath.DEL4: (
"Single to multi exon deletion disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Truncated/altered region is critical to protein function"
),
PVS1PredictionStrucVarPath.DEL5_1: (
"Single to multi exon deletion disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are frequent in the general population and/or "
"exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionStrucVarPath.DEL6_1: (
"Single to multi exon deletion disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes >10% of protein"
),
PVS1PredictionStrucVarPath.DEL7_1: (
"Single to multi exon deletion disrupts reading frame and "
"is not predicted to undergo NMD -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes <10% of protein"
),
PVS1PredictionStrucVarPath.DEL5_2: (
"Single to multi exon deletion preserves reading frame -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are frequent in the general population and/or "
"exon is absent from biologically-relevant transcript(s)"
),
PVS1PredictionStrucVarPath.DEL6_2: (
"Single to multi exon deletion preserves reading frame -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes >10% of protein"
),
PVS1PredictionStrucVarPath.DEL7_2: (
"Single to multi exon deletion preserves reading frame -> "
"Role of region in protein function is unknown -> "
"LoF variants in this exon are not frequent in the general population and "
"exon is present in biologically-relevant transcript(s) -> "
"Variant removes <10% of protein"
),
PVS1PredictionStrucVarPath.DEL8: (
"Single to multi exon deletion preserves reading frame -> "
"Truncated/altered region is critical to protein function"
),
PVS1PredictionStrucVarPath.DUP1: (
"Proven in tandem -> " "Reading frame disrupted and NMD predicted to occur"
),
PVS1PredictionStrucVarPath.DUP2_1: (
"Proven in tandem -> " "No or unknown impact on reading frame and NMD"
),
PVS1PredictionStrucVarPath.DUP2_2: (
"Presumed in tandem -> " "No or unknown impact on reading frame and NMD"
),
PVS1PredictionStrucVarPath.DUP3: (
"Proven in tandem -> " "Reading frame presumed disrupted and NMD predicted to occur"
),
PVS1PredictionStrucVarPath.DUP4: "Proven not in tandem",
}



63 changes: 32 additions & 31 deletions src/auto_acmg.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from src.core.config import Config
from src.criteria.auto_criteria import AutoACMGCriteria
from src.defs.auto_acmg import ACMGPrediction, AutoACMGResult
from src.defs.auto_acmg import ACMGPrediction, AutoACMGPrediction, AutoACMGResult
from src.defs.auto_pvs1 import PVS1Prediction, PVS1PredictionPathMapping, PVS1PredictionStrucVarPath
from src.defs.exceptions import AutoAcmgBaseException, ParseError
from src.defs.genome_builds import GenomeRelease
Expand Down Expand Up @@ -138,25 +138,9 @@ def predict(self) -> Optional[AutoACMGResult]:
self.seqvar: SeqVar = variant
self.prediction: AutoACMGResult = AutoACMGResult()

# PP5 and BP6 criteria
self.prediction.pp5.prediction = ACMGPrediction.NotSet
self.prediction.pp5.comment = "PP5 prediction is deprecated."
self.prediction.bp6.prediction = ACMGPrediction.NotSet
self.prediction.bp6.comment = "BP6 prediction is deprecated."
# PP5 and BP6 criteria are depricated
logger.warning("Note, that PP5 and BP6 criteria are depricated and not predicted.")

# Not implemented criteria
for crit in NOT_IMPLEMENTED_CRITERIA:
setattr(
getattr(self.prediction, crit.lower()),
"prediction",
ACMGPrediction.NotSet,
)
setattr(
getattr(self.prediction, crit.lower()),
"comment",
f"{crit} prediction is not implemented.",
)
logger.warning(
"Some criteria are not implemented yet: {}",
NOT_IMPLEMENTED_CRITERIA,
Expand All @@ -166,26 +150,33 @@ def predict(self) -> Optional[AutoACMGResult]:
try:
logger.info("Predicting PVS1.")
pvs1 = AutoPVS1(self.seqvar, self.genome_release, config=self.config)
seqvar_prediction, seqvar_prediction_path = pvs1.predict()
seqvar_prediction, seqvar_prediction_path, comment = pvs1.predict()
if seqvar_prediction is None or seqvar_prediction_path is None:
raise AutoAcmgBaseException(
"PVS1 prediction failed: prediction or prediction path is None."
)
else:
if seqvar_prediction == PVS1Prediction.NotSet:
raise AutoAcmgBaseException("PVS1 prediction failed: prediction NotSet.")
self.prediction.pvs1.prediction = (
ACMGPrediction.Positive
if seqvar_prediction in PVS1_POSITIVE_SEQVAR_PREDICTIONS
else ACMGPrediction.Negative
)
self.prediction.pvs1.comment = (
f"PVS1 strength: {seqvar_prediction.name}. "
f"PVS1 prediction path: {PVS1PredictionPathMapping[seqvar_prediction_path]}."
)
elif seqvar_prediction == PVS1Prediction.UnsupportedConsequence:
self.prediction.pvs1.prediction = AutoACMGPrediction.NotApplicable
self.prediction.pvs1.summary = "Unsupported consequence"
self.prediction.pvs1.description = comment
else:
self.prediction.pvs1.prediction = (
AutoACMGPrediction.Positive
if seqvar_prediction in PVS1_POSITIVE_SEQVAR_PREDICTIONS
else AutoACMGPrediction.Negative
)
self.prediction.pvs1.summary = (
f"PVS1 strength: {seqvar_prediction.name}. "
f"PVS1 prediction path: {PVS1PredictionPathMapping[seqvar_prediction_path]}."
)
self.prediction.pvs1.description = comment
except AutoAcmgBaseException as e:
self.prediction.pvs1.prediction = ACMGPrediction.NotSet
self.prediction.pvs1.comment = "PVS1 prediction failed."
self.prediction.pvs1.prediction = AutoACMGPrediction.NotSet
self.prediction.pvs1.description = "PVS1 prediction failed."
self.comment = f"Error: {e}"
logger.error("Failed to predict PVS1 criteria. Error: {}", e)

# Other criteria
Expand All @@ -202,12 +193,22 @@ def predict(self) -> Optional[AutoACMGResult]:
setattr(
getattr(self.prediction, criteria.lower()),
"prediction",
ACMGPrediction.Positive if prediction else ACMGPrediction.Negative,
(
AutoACMGPrediction.Positive
if prediction["prediction"] == ACMGPrediction.Positive
else AutoACMGPrediction.Negative
),
)
setattr(
getattr(self.prediction, criteria.lower()),
"summary",
prediction["comment"],
)
except AutoAcmgBaseException as e:
logger.error("Failed to predict other ACMG criteria. Error: {}", e)

logger.info("ACMG criteria prediction completed.")
logger.debug("ACMG criteria prediction result: {}", self.prediction)
return self.prediction

elif isinstance(variant, StrucVar):
Expand Down
Loading