def setUp(self): """ define a family and variant, and start the Autosomal class """ # generate a test family child_gender = "F" mom_aff = "1" dad_aff = "1" self.trio = self.create_family(child_gender, mom_aff, dad_aff) # generate a test variant child_var = self.create_snv(child_gender, "0/1") mom_var = self.create_snv("F", "0/0") dad_var = self.create_snv("M", "0/0") var = TrioGenotypes(child_var) var.add_mother_variant(mom_var) var.add_father_variant(dad_var) self.variants = [var] # make sure we've got known genes data self.known_genes = { "TEST": { "inh": ["Monoallelic"], "confirmed_status": ["Confirmed DD Gene"] } } self.inh = Autosomal(self.variants, self.trio, self.known_genes, "TEST") self.inh.is_lof = var.child.is_lof()
def setUp(self): """ define a family and variant, and start the Inheritance class """ # generate a test family child_gender = "F" mom_aff = "1" dad_aff = "1" self.trio = self.create_family(child_gender, mom_aff, dad_aff) # generate list of variants self.variants = [self.create_variant(child_gender)] self.variants.append(self.create_variant(child_gender)) # make sure we've got known genes data self.known_genes = { "TEST": { "inheritance": ["Monoallelic"], "confirmed_status": ["Confirmed DD Gene"] } } gene_inh = self.known_genes[self.variants[0].get_gene()]["inheritance"] self.inh = Autosomal(self.variants, self.trio, gene_inh)
def setUp(self): """ define a family and variant, and start the Autosomal class """ # generate a test family sex = "F" mom_aff = "1" dad_aff = "1" self.trio = self.create_family(sex, mom_aff, dad_aff) # generate a test variant child = create_snv(sex, "0/1") mom = create_snv("F", "0/0") dad = create_snv("M", "0/0") var = TrioGenotypes(child.get_chrom(), child.get_position(), child, mom, dad) self.variants = [var] # make sure we've got known genes data self.known_gene = { "inh": ["Monoallelic"], "confirmed_status": ["confirmed dd gene"] } self.inh = Autosomal(self.variants, self.trio, self.known_gene, "1001") self.inh.is_lof = var.child.is_lof()
def find_variants(self, variants, gene): """ finds variants that fit inheritance models Args: variants: list of TrioGenotype objects gene: gene ID as string Returns: list of variants that pass inheritance checks """ # get the inheritance for the gene (monoalleleic, biallelic, hemizygous # etc), but allow for times when we haven't specified a list of genes # to use gene_inh = None if self.known_genes is not None and gene in self.known_genes: gene_inh = self.known_genes[gene]["inh"] # If we are looking for variants in a set of known genes, and the gene # isn't part of that set, then we don't ant to examine the variant for # that gene, UNLESS the variant is a CNV, since CNVs can be included # purely from size thresholds, regardless of which gene they overlap. if self.known_genes is not None and gene not in self.known_genes: variants = [x for x in variants if x.is_cnv()] # ignore intergenic variants if gene is None: for var in variants: if var.get_chrom() == self.debug_chrom and var.get_position( ) == self.debug_pos: print(var, "lacks HGNC/gene symbol") return [] # Now that we are examining a single gene, check that the consequences # for the gene are in the required functional categories. variants = [ var for var in variants if var.child.is_lof(gene) or var.child.is_missense(gene) ] if variants == []: return [] logging.debug("{} {} {} {}".format(self.family.child.get_id(), gene, variants, gene_inh)) chrom_inheritance = variants[0].get_inheritance_type() if chrom_inheritance == "autosomal": finder = Autosomal(variants, self.family, self.known_genes, gene, self.cnv_regions) elif chrom_inheritance in ["XChrMale", "XChrFemale", "YChrMale"]: finder = Allosomal(variants, self.family, self.known_genes, gene, self.cnv_regions) variants = finder.get_candidate_variants() variants = [(x[0], list(x[1]), list(x[2]), [gene]) for x in variants] return variants
def find_variants(self, variants, gene, family): """ finds variants that fit inheritance models Args: variants: list of TrioGenotype objects gene: gene ID as string Returns: list of variants that pass inheritance checks """ # get the inheritance for the gene (monoalleleic, biallelic, hemizygous # etc), but allow for times when we haven't specified a list of genes # to use known_gene = None gene_inh = None if self.known_genes is not None and gene in self.known_genes: known_gene = self.known_genes[gene] gene_inh = known_gene['inh'] chrom_inheritance = variants[0].get_inheritance_type() # If we are looking for variants in a set of known genes, and the gene # isn't part of that set, then we don't ant to examine the variant for # that gene, UNLESS the variant is a CNV, since CNVs can be included # purely from size thresholds, regardless of which gene they overlap. if self.known_genes is not None and gene not in self.known_genes: variants = [ x for x in variants if x.is_cnv() ] # ignore intergenic variants if gene is None: for var in variants: if var.get_chrom() == self.debug_chrom and var.get_position() == self.debug_pos: print(var, "lacks HGNC/gene symbol") return [] # Now that we are examining a single gene, check that the consequences # for the gene are in the required functional categories. variants = [ var for var in variants if var.child.is_lof(gene) or var.child.is_missense(var.child.is_cnv(), gene) ] if variants == []: return [] for x in variants[0].child.info.symbols: try: symbol = x.get(gene, ['HGNC', 'SYMBOL', 'ENSG']) break except KeyError: continue logging.info("{}\t{}\tvariants: {}\trequired_mode: {}".format( family.child.get_id(), symbol, [str(x) for x in variants], gene_inh)) if chrom_inheritance == "autosomal": finder = Autosomal(variants, family, known_gene, gene, self.cnv_regions) elif chrom_inheritance in ["XChrMale", "XChrFemale", "YChrMale"]: finder = Allosomal(variants, family, known_gene, gene, self.cnv_regions) return finder.get_candidate_variants()
def test_get_candidate_variants_compound_het(self): """ test that get_candidate_variants() works for biallelic variants """ inh = {"inh": ["Biallelic"], "confirmed_status": ["confirmed dd gene"]} var1 = self.create_variant(position='150', cq='stop_gained', geno=['0/1', '0/1', '0/0']) var2 = self.create_variant(position='151', cq='stop_gained', geno=['0/1', '0/0', '1/0']) self.inh = Autosomal([var1, var2], self.trio, inh, "TEST") self.assertEqual( sorted(self.inh.get_candidate_variants()), sorted([(var1, ['compound_het'], ['Biallelic'], ['TEST']), (var2, ['compound_het'], ['Biallelic'], ['TEST'])])) # check that a single variant isn't included in the compound hets self.inh = Autosomal([var1], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), [])
def test_check_compound_hets(self): """ test that check_compound_hets() works correctly for autosomal vars """ # set some variants, so we can alter them later var1 = self.create_variant("F", chrom="1", position="15000000", cq="stop_gained") var2 = self.create_variant("F", chrom="1", position="16000000", cq="stop_gained") var3 = self.create_variant("F", chrom="1", position="17000000", cq="stop_gained") # set the inheritance type, the compound het type ("compound_het" # for autosomal variants, and start autosomal inheritance) # known_genes = "Biallelic" known_genes = { "TEST": { "inh": ["Biallelic"], "confirmed_status": ["Confirmed DD Gene"] } } self.inh = Autosomal([var1, var2, var3], self.trio, known_genes, "TEST") variants = [(), ()] # check the expected "110, 101" combo passes variants[0] = (self.set_compound_het_var(var1, "110"), ) variants[1] = (self.set_compound_het_var(var2, "101"), ) self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that > 2 valid compound hets passes all variants variants = [(), (), ()] variants[0] = (self.set_compound_het_var(var1, "110"), ) variants[1] = (self.set_compound_het_var(var2, "101"), ) variants[2] = (self.set_compound_het_var(var3, "110"), ) self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that a single var fails to give compound hets single_var = variants[:1] self.assertEqual(self.inh.check_compound_hets(single_var), []) # check that zero length list gives no compound hets no_vars = [] self.assertEqual(self.inh.check_compound_hets(no_vars), [])
def test_get_candidate_variants_monoallelic(self): """ test that get_candidate_variants() works for a monoallelic variant """ inh = { "inh": ["Monoallelic"], "confirmed_status": ["confirmed dd gene"] } var = self.create_variant(position='150', cq='stop_gained', geno=['0/1', '0/0', '0/0']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual( self.inh.get_candidate_variants(), [(var, ['single_variant'], ['Monoallelic'], ['TEST'])]) # check a variant that shouldn't pass the monoallelic route var = self.create_variant(position='150', cq='stop_gained', geno=['0/1', '0/1', '0/0']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), [])
def test_is_compound_pair_proband_only(self): """ check that is_compound_pair() includes proband-only pairs """ fam = Family("test") fam.add_child("child", 'dad_id', 'mom_id', 'F', '2', "child_vcf") fam.set_child() # set some variants, so we can alter them later var1 = self.create_variant(chrom="1", position="150", sex="F", cq="stop_gained") var2 = self.create_variant(chrom="1", position="160", sex="F", cq="stop_gained") inh = Autosomal([var1, var2], fam, self.known_gene, "TEST") # check that a proband-only passes, regardless of the parental genotypes self.assertTrue(inh.is_compound_pair(var1, var2))
def setUp(self): """ define a family and variant, and start the Inheritance class """ # generate a test family sex = "F" mom_aff = "1" dad_aff = "1" self.trio = self.create_family(sex, mom_aff, dad_aff) # generate list of variants self.variants = [self.create_variant(sex)] self.variants.append(self.create_variant(sex)) # make sure we've got known genes data self.known_gene = { "inh": ["Monoallelic"], "confirmed_status": ["confirmed dd gene"] } self.inh = Autosomal(self.variants, self.trio, self.known_gene, "1001")
def find_variants(self, variants, gene): """ finds variants that fit inheritance models Args: variants: list of TrioGenotype objects gene: gene ID as string Returns: list of variants that pass inheritance checks """ # get the inheritance for the gene (monoalleleic, biallelic, hemizygous # etc), but allow for times when we haven't specified a list of genes # to use gene_inh = None if self.known_genes is not None and gene in self.known_genes: gene_inh = self.known_genes[gene]["inh"] # ignore intergenic variants if gene is None: for var in variants: if var.get_chrom() == self.debug_chrom and var.get_position( ) == self.debug_pos: print(var, "lacks HGNC/gene symbol") return [] logging.debug(self.family.child.get_id() + " " + gene + " " + \ str(variants) + " " + str(gene_inh)) chrom_inheritance = variants[0].get_inheritance_type() if chrom_inheritance == "autosomal": finder = Autosomal(variants, self.family, self.known_genes, gene_inh, self.cnv_regions) elif chrom_inheritance in ["XChrMale", "XChrFemale", "YChrMale"]: finder = Allosomal(variants, self.family, self.known_genes, gene_inh, self.cnv_regions) return finder.get_candidate_variants()
def test_get_candidate_variants_imprinted(self): """ test that get_candidate_variants() works for imprinted variants """ # check a variant where the imprinting route should work inh = {"inh": ["Imprinted"], "confirmed_status": ["confirmed dd gene"]} var = self.create_variant(position='150', cq='stop_gained', geno=['0/1', '0/1', '0/0']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), [(var, ['single_variant'], ['Imprinted'], ['TEST'])]) # de novos should now pass the imprinted route var = self.create_variant(position='150', cq='stop_gained', geno=['0/1', '0/0', '0/0']) self.inh = Autosomal([var], self.trio, inh, "TEST") #self.assertEqual(self.inh.get_candidate_variants(), []) self.assertEqual(self.inh.get_candidate_variants(), [(var, ['single_variant'], ['Imprinted'], ['TEST'])]) # check a variant that shouldn't pass the imprinted route due to there # not being a known gene. # NOTE: this behavior differs differs slightly from other inheritance # modes when there isn't any known gene. Since there are so few known # imprinting genes, it makes sense to only allow for these when we know # the mode is correct var = self.create_variant(position='150', cq='stop_gained', geno=['0/1', '0/1', '0/0']) self.inh = Autosomal([var], self.trio, None, "TEST") self.assertEqual(self.inh.get_candidate_variants(), []) # also check imprinting requires loss-of-function consequences var = self.create_variant(position='150', cq='missense_variant', geno=['0/1', '0/1', '0/0']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), []) # check loss-of-function requirement for a paternally inherited variant var = self.create_variant(position='150', cq='missense_variant', geno=['0/1', '0/0', '0/1']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), []) # check imprinting for a biallelic variant var = self.create_variant(position='150', cq='stop_gained', geno=['1/1', '0/1', '0/1']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), [(var, ['single_variant'], ['Imprinted'], ['TEST'])]) # check imprinting for a biallelic variant var = self.create_variant(position='150', cq='missense_variant', geno=['1/1', '0/1', '0/1']) self.inh = Autosomal([var], self.trio, inh, "TEST") self.assertEqual(self.inh.get_candidate_variants(), [])
def test_check_compound_hets_autosomal(self): """ test that check_compound_hets() works correctly for autosomal vars """ # set some variants, so we can alter them later var1 = self.create_variant("F", chrom="1", position="15000000") var2 = self.create_variant("F", chrom="1", position="16000000") var3 = self.create_variant("F", chrom="1", position="17000000") # set the inheritance type, the compound het type ("compound_het" # for autosomal variants, and start autosomal inheritance) inh = "Biallelic" compound = "compound_het" self.inh = Autosomal([var1, var2, var3], self.trio, inh) variants = ["", ""] # check the expected "110, 101" combo passes variants[0] = self.set_compound_het_var(var1, "110", compound) variants[1] = self.set_compound_het_var(var2, "101", compound) if IS_PYTHON3: self.assertCountEqual(self.inh.check_compound_hets(variants), variants) elif IS_PYTHON2: self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that "110, 110" combo fails variants[0] = self.set_compound_het_var(var1, "110", compound) variants[1] = self.set_compound_het_var(var2, "110", compound) self.assertEqual(self.inh.check_compound_hets(variants), []) # check that "101, 101" combo fails variants[0] = self.set_compound_het_var(var1, "101", compound) variants[1] = self.set_compound_het_var(var2, "101", compound) self.assertEqual(self.inh.check_compound_hets(variants), []) # check that > 2 valid compound hets passes all variants variants = ["", "", ""] variants[0] = self.set_compound_het_var(var1, "110", compound) variants[1] = self.set_compound_het_var(var2, "101", compound) variants[2] = self.set_compound_het_var(var3, "110", compound) if IS_PYTHON3: self.assertCountEqual(self.inh.check_compound_hets(variants), variants) elif IS_PYTHON2: self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that a single var fails to give compound hets single_var = variants[:1] self.assertEqual(self.inh.check_compound_hets(single_var), []) # check that zero length list gives no compound hets no_vars = [] self.assertEqual(self.inh.check_compound_hets(no_vars), []) # check that de novo containing "110, 100" combos give compound hets variants = ["", ""] variants[0] = self.set_compound_het_var(var1, "110", compound) variants[1] = self.set_compound_het_var(var2, "100", compound) if IS_PYTHON3: self.assertCountEqual(self.inh.check_compound_hets(variants), variants) elif IS_PYTHON2: self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that de novo "100, 100" combos give compound hets variants[0] = self.set_compound_het_var(var1, "100", compound) variants[1] = self.set_compound_het_var(var2, "100", compound) if IS_PYTHON3: self.assertCountEqual(self.inh.check_compound_hets(variants), variants) elif IS_PYTHON2: self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that "111, 111" combos require affected parents variants[0] = self.set_compound_het_var(var1, "111", compound) variants[1] = self.set_compound_het_var(var2, "111", compound) self.assertEqual(self.inh.check_compound_hets(variants), []) # check "111, 111" combo with a single affected parent self.inh.mother_affected = True self.assertEqual(self.inh.check_compound_hets(variants), []) # check "111, 111" combo with both parents affected self.inh.father_affected = True if IS_PYTHON3: self.assertCountEqual(self.inh.check_compound_hets(variants), variants) elif IS_PYTHON2: self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants)) # check that without parents, all variants are included, even if they # wouldn't pass normally self.inh.trio.mother = None self.inh.trio.father = None variants[0] = self.set_compound_het_var(var1, "101", compound) variants[1] = self.set_compound_het_var(var2, "101", compound) if IS_PYTHON3: self.assertCountEqual(self.inh.check_compound_hets(variants), variants) elif IS_PYTHON2: self.assertEqual(sorted(self.inh.check_compound_hets(variants)), sorted(variants))