Skip to content

Commit

Permalink
Permit Het-Female-X variants in Biallelic disease (#432)
Browse files Browse the repository at this point in the history
* allow for x-linked imprinting assessment

* Bump version: 5.3.1 → 5.4.0
  • Loading branch information
MattWellie authored Sep 26, 2024
1 parent 3be989a commit da280c5
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 5.3.1
current_version = 5.4.0
commit = True
tag = False

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/index_page_builder.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest

env:
VERSION: 5.3.1
VERSION: 5.4.0

steps:

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def read_reqs(filename: str) -> list[str]:
name='talos',
description='Centre for Population Genomics Variant Prioritisation',
long_description=readme,
version='5.3.1',
version='5.4.0',
author='Matthew Welland, CPG',
author_email='[email protected], [email protected]',
package_data={'talos': ['templates/*.jinja', 'example_config.toml']},
Expand Down
107 changes: 106 additions & 1 deletion src/talos/moi_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ def __init__(self, pedigree: Pedigree, target_moi: str):
XRecessiveMale(pedigree=pedigree),
XRecessiveFemaleHom(pedigree=pedigree),
XRecessiveFemaleCH(pedigree=pedigree),
XPseudoDominantFemale(pedigree=pedigree),
]

else:
Expand Down Expand Up @@ -202,7 +203,7 @@ def check_familial_inheritance(self, sample_id: str, called_variants: set[str],

this_member = self.pedigree.by_id[sample_id]

# iterate through all family members, no interested in directionality of relationships at the moment
# check for valid inheritance within the immediate trio, if possible
for member_id in [this_member.father, this_member.mother]:
if member_id is None:
continue
Expand Down Expand Up @@ -673,6 +674,110 @@ def run(
return classifications


class XPseudoDominantFemale(BaseMoi):
"""
X-Dominant method which only evaluates females, on the basis that a healthy allele could be inactivated
A special case of X-Dominant, where we consider Het. variants, used to assess genes which are on X and in genes
associated with a Biallelic MOI
Basically a Dominant MOI to be applied to Recessive genes, and results will be labelled as cautionary
"""

def __init__(self, pedigree: Pedigree, applied_moi: str = 'X_Dominant'):
"""
accept male hets and homs, and female hets without support
Args:
pedigree ():
applied_moi ():
"""
self.ad_threshold = config_retrieve(['ValidateMOI', GNOMAD_RARE_THRESHOLD])
self.ac_threshold = config_retrieve(['ValidateMOI', GNOMAD_AD_AC_THRESHOLD])
self.hom_threshold = config_retrieve(['ValidateMOI', GNOMAD_DOM_HOM_THRESHOLD])

self.freq_tests = {
SmallVariant.__name__: {key: self.hom_threshold for key in INFO_HOMS}
| {'gnomad_ac': self.ac_threshold, 'gnomad_af': self.ad_threshold},
StructuralVariant.__name__: {key: self.hom_threshold for key in SV_HOMS},
}

super().__init__(pedigree=pedigree, applied_moi=applied_moi)

def run(
self,
principal: VARIANT_MODELS,
comp_het: CompHetDict | None = None, # noqa: ARG002
partial_pen: bool = False,
) -> list[ReportVariant]:
"""
if variant is present and sufficiently rare, we take it
discarded if support
Args:
principal ():
comp_het ():
partial_pen ():
"""

_unused = partial_pen

classifications = []

if principal.support_only:
return classifications

# never apply dominant MOI to support variants
# more stringent Pop.Freq checks for dominant - hemi restriction
if not self.check_frequency_passes(principal.info, self.freq_tests[principal.__class__.__name__]):
return classifications

# all females which have a variant call
females_under_consideration = {sam for sam in principal.het_samples if self.pedigree.by_id[sam].sex == '2'}
all_with_variant = principal.het_samples.union(principal.hom_samples)
for sample_id in females_under_consideration:
# skip primary analysis for unaffected members
# we require this specific sample to be categorised
# force minimum depth
if (
not (
principal.sample_category_check(sample_id, allow_support=False)
and self.pedigree.by_id[sample_id].affected == '2'
)
) or principal.check_read_depth(sample_id, self.minimum_depth, principal.info.get('categoryboolean1')):
continue

# check if this is a candidate for dominant inheritance
# as we're allowing for flexible 'penetrance' in females, we send all het and hom variants, but allow for a
# partial penetrance check - the participants can have the variant, but not be affected. They may not be
# affected without the variant call.
# There's a slight breakdown here as the males should be interpreted under a full penetrance model, and
# females under partial penetrance, but that's not trivial without creating a second familial check method.
# Leaving that aside now as the current implementation is pretty central to the algorithm. Will revisit if
# this is noisy.
if not self.check_familial_inheritance(
sample_id=sample_id,
called_variants=all_with_variant,
partial_pen=True,
):
continue

classifications.append(
ReportVariant(
sample=sample_id,
family=self.pedigree.by_id[sample_id].family,
gene=principal.info.get('gene_id'),
var_data=principal,
categories=principal.category_values(sample_id),
reasons={self.applied_moi},
genotypes=self.get_family_genotypes(variant=principal, sample_id=sample_id),
flags=principal.get_sample_flags(sample_id)
| {'Affected female with heterozygous variant in XLR gene'},
independent=True,
),
)
return classifications


class XRecessiveMale(BaseMoi):
"""
accept all male non-ref GTs - male variants HOM because GATK
Expand Down
2 changes: 1 addition & 1 deletion src/talos/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
"""

# Do not edit this file manually
__version__ = '5.3.1'
__version__ = '5.4.0'
29 changes: 29 additions & 0 deletions test/test_moi_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
RecessiveAutosomalCH,
RecessiveAutosomalHomo,
XDominant,
XPseudoDominantFemale,
XRecessiveFemaleCH,
XRecessiveFemaleHom,
XRecessiveMale,
Expand Down Expand Up @@ -434,6 +435,34 @@ def test_x_dominant_info_fails(info, pedigree_path):
assert len(x_dom.run(passing_variant)) == 0


def test_x_dominant_female_inactivation_passes(pedigree_path):
"""
check that a het female, but not a het male, is accepted as dominant
current test implementation doesn't include family consideration
"""
info_dict = {
'gnomad_af': 0.0001,
'gnomad_ac': 0,
'gnomad_hom': 0,
'gene_id': 'TEST1',
'categoryboolean1': True,
}
passing_variant = SmallVariant(
depths={'female': 100, 'male': 100},
info=info_dict,
het_samples={'female', 'male'},
hom_samples={'male'},
boolean_categories=['categoryboolean1'],
coordinates=TEST_COORDS_X_1,
transcript_consequences=[],
)
x_dom = XPseudoDominantFemale(pedigree=make_flexible_pedigree(pedigree_path))
results = x_dom.run(passing_variant)
assert len(results) == 1
assert results[0].reasons == {'X_Dominant'}
assert 'Affected female with heterozygous variant in XLR gene' in results[0].flags


def test_x_recessive_male_hom_passes(pedigree_path):
passing_variant = SmallVariant(
hom_samples={'female', 'male'},
Expand Down

0 comments on commit da280c5

Please sign in to comment.