def setUp(self): """ define a family and variant, and start the Allosomal 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 = create_snv(child_gender, "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 = Allosomal(self.variants, self.trio, self.known_gene, "1001") self.inh.is_lof = var.child.is_lof()
def setUp(self): """ define a family and variant, and start the Allosomal 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 = Allosomal(self.variants, self.trio, self.known_genes, "TEST") self.inh.is_lof = var.child.is_lof()
def test_check_homozygous_male(self): """ test that check_homozygous() works correctly for males """ # check for trio with de novo on male X chrom var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom de novo") # check for trio = 210, with unaffected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 210, with affected mother, which should also pass self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with affected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/1"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with unaffected mother, which should not pass self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that homozygous X-linked over-dominance doesn't pass self.assertEqual(self.inh.check_homozygous("X-linked over-dominance"), 'nothing') # check we raise errors with unknown inheritance modes with self.assertRaises(ValueError): self.inh.check_homozygous("Digenic")
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 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 test_check_variant_without_parents_male(self): """ test that check_variant_without_parents() works correctly for males """ var = TrioGenotypes('X', 100, create_snv('M', "1/1"), None, None) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual( self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant")
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_check_compound_hets_allosomal(self): """ test that check_compound_hets() works correctly for allosomal vars """ # set some X chrom variants, so we can alter them later var1 = self.create_variant("F", chrom="X", position="15000000") var2 = self.create_variant("F", chrom="X", position="16000000") # set the inheritance type, the compound het type ("hemizygous" # for allosomal variants, and start allosomal inheritance) inh = "Hemizygous" compound = "hemizygous" self.inh = Allosomal([var1, var2], self.trio, inh) variants = ["", ""] # check that de novo containing "110, 100" combos pass 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 "110, 102" combo fails if the father is unaffected variants[0] = self.set_compound_het_var(var1, "110", compound) variants[1] = self.set_compound_het_var(var2, "102", compound) self.assertEqual(self.inh.check_compound_hets(variants), []) # check that "110, 102" combo passes if the father is 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)) # make sure we can't set the father as het on the X chrom with self.assertRaises(ValueError): self.set_compound_het_var(var2, "101", compound)
def test_check_variant_without_parents_male(self): """ test that check_variant_without_parents() works correctly for males """ var = TrioGenotypes('X', 100, create_snv('M', "1/1"), None, None) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant")
def test_check_homozygous_male(self): """ test that check_homozygous() works correctly for males """ # check for trio with de novo on male X chrom var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom de novo") # check for trio = 210, with unaffected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 210, with affected mother, which should also pass self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with affected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/1"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with unaffected mother, which should not pass self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that homozygous X-linked over-dominance doesn't pass self.assertEqual(self.inh.check_homozygous("X-linked over-dominance"), 'nothing') # check we raise errors with unknown inheritance modes with self.assertRaises(ValueError): self.inh.check_homozygous("Digenic")
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 setUp(self): """ define a family and variant, and start the Allosomal 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 = create_snv(child_gender, "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 = Allosomal(self.variants, self.trio, self.known_gene, "1001") self.inh.is_lof = var.child.is_lof()
class TestAllosomalPy(unittest.TestCase): """ test the Allosomal class """ def setUp(self): """ define a family and variant, and start the Allosomal 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 = create_snv(child_gender, "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 = Allosomal(self.variants, self.trio, self.known_gene, "1001") self.inh.is_lof = var.child.is_lof() def create_family(self, child_gender, mom_aff, dad_aff): """ create a default family, with optional gender and parental statuses """ fam = Family('test') fam.add_child('child', 'mother', 'father', child_gender, '2', 'child_vcf') fam.add_mother('mother', '0', '0', 'female', mom_aff, 'mother_vcf') fam.add_father('father', '0', '0', 'male', dad_aff, 'father_vcf') fam.set_child() return fam def set_trio_genos(self, var, geno): """ convenience function to set the trio genotypes for a variant """ genos = {"0": "0/0", "1": "0/1", "2": "1/1"} # convert the geno codes to allele codes child = genos[geno[0]] mom = genos[geno[1]] dad = genos[geno[2]] # set the genotype field for each individual var.child.format["GT"] = child var.mother.format["GT"] = mom var.father.format["GT"] = dad # and set th genotype for each individual var.child.set_genotype() var.mother.set_genotype() var.father.set_genotype() # set the trio genotypes for the inheritance object self.inh.set_trio_genotypes(var) def test_check_variant_without_parents_female(self): """ test that check_variant_without_parents() works correctly for female """ var = TrioGenotypes('X', 100, create_snv('F', "1/0"), None, None) self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "allosomal without parents") var = TrioGenotypes('X', 100, create_snv('F', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "hemizygous") var = TrioGenotypes('X', 100, create_snv('F', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant") def test_check_variant_without_parents_male(self): """ test that check_variant_without_parents() works correctly for males """ var = TrioGenotypes('X', 100, create_snv('M', "1/1"), None, None) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant") def test_check_heterozygous_de_novo(self): """ test that check_heterozygous() works correctly for de novos """ # all of these tests are run for female X chrom de novos, since male # X chrom hets don't exist var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "female x chrom de novo") # check for biallelic inheritance self.assertEqual(self.inh.check_heterozygous("Hemizygous"), "single_variant") # check for X-linked over dominance self.assertEqual(self.inh.check_heterozygous("X-linked over-dominance"), 'single_variant') # check we raise errors with unknown inheritance modes with self.assertRaises(ValueError): self.inh.check_heterozygous("Digenic") genos = {'0': '0/0', '1': '1/0', '2': '1/1'} for (child, mom, dad) in ["102", "110", "112", "122"]: var = TrioGenotypes('X', 100, create_snv('F', genos[child]), create_snv('F', genos[mom]), create_snv('M', genos[dad])) self.inh.set_trio_genotypes(var) self.inh.check_heterozygous("X-linked dominant") self.assertNotEqual(self.inh.log_string, "female x chrom de novo") def test_check_heterozygous_affected_mother(self): """ test that check_heterozygous() works correctly for affected mothers """ # check that trio with het affected mother is captured var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "1/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.inh.mother_affected = True self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # check that when the other parent is also non-ref, the variant is no # longer captured, unless the parent is affected var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "1/0"), create_snv('M', "1/1")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") self.inh.father_affected = True self.inh.check_heterozygous("X-linked dominant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # and check that hemizgygous vars return as "compound_het" self.assertEqual(self.inh.check_heterozygous("Hemizygous"), "compound_het") def test_check_heterozygous_affected_father(self): """ test that check_heterozygous() works correctly for affected fathers """ # set the father as non-ref genotype and unaffected var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "0/0"), create_snv('M', "1/1")) self.inh.set_trio_genotypes(var) # check that the het proband, with het unaffected father is passes self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that the het proband, with het affected father is captured self.inh.father_affected = True self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # check that when the other parent is also non-ref, the variant is no # longer captured, unless the parent is affected var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "1/0"), create_snv('M', "1/1")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") self.inh.mother_affected = True self.inh.check_heterozygous("X-linked dominant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") def test_check_homozygous_male(self): """ test that check_homozygous() works correctly for males """ # check for trio with de novo on male X chrom var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom de novo") # check for trio = 210, with unaffected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 210, with affected mother, which should also pass self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with affected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/1"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with unaffected mother, which should not pass self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that homozygous X-linked over-dominance doesn't pass self.assertEqual(self.inh.check_homozygous("X-linked over-dominance"), 'nothing') # check we raise errors with unknown inheritance modes with self.assertRaises(ValueError): self.inh.check_homozygous("Digenic") def test_check_homozygous_female(self): """ test that check_homozygous() works correctly for females """ var = self.variants[0] # check for trio = 200, which is non-mendelian self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check for trio = 210, which is non-mendelian self.set_trio_genos(var, "210") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check for trio = 202, which is non-mendelian self.set_trio_genos(var, "202") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # and check for trio = 212, without affected parents self.set_trio_genos(var, "212") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # and check for trio = 212, with affected father self.set_trio_genos(var, "212") self.inh.father_affected = True self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 212, with affected mother self.set_trio_genos(var, "212") self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 222, with affected mother self.set_trio_genos(var, "222") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 222, with affected mother self.set_trio_genos(var, "222") self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") def test_check_homozygous_with_cnv(self): """ test that check_homozygous() works correctly for variant lists with CNVs """ # generate a test variant chrom = "X" pos = '160' child = create_cnv('F', 'unknown', chrom=chrom, pos=pos) mom = create_cnv('F', 'unknown', chrom=chrom, pos=pos) dad = create_cnv('F', 'unknown', chrom=chrom, pos=pos) cnv = TrioGenotypes(chrom, pos, child, mom, dad) var = self.variants[0] # check for trio = 200, which is non-mendelian self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check when a CNV is in the variants list self.inh.variants.append(cnv) self.assertEqual(self.inh.check_homozygous("Hemizygous"), "compound_het") self.assertEqual(self.inh.log_string, "non-mendelian, but CNV might affect call")
class TestAllosomalPy(unittest.TestCase): """ test the Allosomal class """ def setUp(self): """ define a family and variant, and start the Allosomal 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 = create_snv(child_gender, "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 = Allosomal(self.variants, self.trio, self.known_gene, "1001") self.inh.is_lof = var.child.is_lof() def create_family(self, child_gender, mom_aff, dad_aff): """ create a default family, with optional gender and parental statuses """ fam = Family('test') fam.add_child('child', 'mother', 'father', child_gender, '2', 'child_vcf') fam.add_mother('mother', '0', '0', 'female', mom_aff, 'mother_vcf') fam.add_father('father', '0', '0', 'male', dad_aff, 'father_vcf') fam.set_child() return fam def set_trio_genos(self, var, geno): """ convenience function to set the trio genotypes for a variant """ genos = {"0": "0/0", "1": "0/1", "2": "1/1"} # convert the geno codes to allele codes child = genos[geno[0]] mom = genos[geno[1]] dad = genos[geno[2]] # set the genotype field for each individual var.child.format["GT"] = child var.mother.format["GT"] = mom var.father.format["GT"] = dad # and set th genotype for each individual var.child.set_genotype() var.mother.set_genotype() var.father.set_genotype() # set the trio genotypes for the inheritance object self.inh.set_trio_genotypes(var) def test_check_variant_without_parents_female(self): """ test that check_variant_without_parents() works correctly for female """ var = TrioGenotypes('X', 100, create_snv('F', "1/0"), None, None) self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual( self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "allosomal without parents") var = TrioGenotypes('X', 100, create_snv('F', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual( self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "hemizygous") var = TrioGenotypes('X', 100, create_snv('F', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant") def test_check_variant_without_parents_male(self): """ test that check_variant_without_parents() works correctly for males """ var = TrioGenotypes('X', 100, create_snv('M', "1/1"), None, None) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual( self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant") def test_check_heterozygous_de_novo(self): """ test that check_heterozygous() works correctly for de novos """ # all of these tests are run for female X chrom de novos, since male # X chrom hets don't exist var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "0/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) # check for X-linked dominant inheritance self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "female x chrom de novo") # check for biallelic inheritance self.assertEqual(self.inh.check_heterozygous("Hemizygous"), "single_variant") # check for X-linked over dominance self.assertEqual( self.inh.check_heterozygous("X-linked over-dominance"), 'single_variant') # check we raise errors with unknown inheritance modes with self.assertRaises(ValueError): self.inh.check_heterozygous("Digenic") genos = {'0': '0/0', '1': '1/0', '2': '1/1'} for (child, mom, dad) in ["102", "110", "112", "122"]: var = TrioGenotypes('X', 100, create_snv('F', genos[child]), create_snv('F', genos[mom]), create_snv('M', genos[dad])) self.inh.set_trio_genotypes(var) self.inh.check_heterozygous("X-linked dominant") self.assertNotEqual(self.inh.log_string, "female x chrom de novo") def test_check_heterozygous_affected_mother(self): """ test that check_heterozygous() works correctly for affected mothers """ # check that trio with het affected mother is captured var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "1/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.inh.mother_affected = True self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # check that when the other parent is also non-ref, the variant is no # longer captured, unless the parent is affected var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "1/0"), create_snv('M', "1/1")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") self.inh.father_affected = True self.inh.check_heterozygous("X-linked dominant") self.assertEqual( self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # and check that hemizgygous vars return as "compound_het" self.assertEqual(self.inh.check_heterozygous("Hemizygous"), "compound_het") def test_check_heterozygous_affected_father(self): """ test that check_heterozygous() works correctly for affected fathers """ # set the father as non-ref genotype and unaffected var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "0/0"), create_snv('M', "1/1")) self.inh.set_trio_genotypes(var) # check that the het proband, with het unaffected father is passes self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that the het proband, with het affected father is captured self.inh.father_affected = True self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # check that when the other parent is also non-ref, the variant is no # longer captured, unless the parent is affected var = TrioGenotypes('X', 100, create_snv('F', "1/0"), create_snv('F', "1/0"), create_snv('M', "1/1")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") self.inh.mother_affected = True self.inh.check_heterozygous("X-linked dominant") self.assertEqual( self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") def test_check_homozygous_male(self): """ test that check_homozygous() works correctly for males """ # check for trio with de novo on male X chrom var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "0/0"), create_snv('M', "0/0")) trio = self.create_family('male', '1', '1') self.inh = Allosomal([var], trio, self.known_gene, "TEST") self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom de novo") # check for trio = 210, with unaffected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/0"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 210, with affected mother, which should also pass self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with affected mother var = TrioGenotypes('X', 100, create_snv('M', "1/1"), create_snv('F', "1/1"), create_snv('M', "0/0")) self.inh.set_trio_genotypes(var) self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual( self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with unaffected mother, which should not pass self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that homozygous X-linked over-dominance doesn't pass self.assertEqual(self.inh.check_homozygous("X-linked over-dominance"), 'nothing') # check we raise errors with unknown inheritance modes with self.assertRaises(ValueError): self.inh.check_homozygous("Digenic") def test_check_homozygous_female(self): """ test that check_homozygous() works correctly for females """ var = self.variants[0] # check for trio = 200, which is non-mendelian self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check for trio = 210, which is non-mendelian self.set_trio_genos(var, "210") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check for trio = 202, which is non-mendelian self.set_trio_genos(var, "202") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # and check for trio = 212, without affected parents self.set_trio_genos(var, "212") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # and check for trio = 212, with affected father self.set_trio_genos(var, "212") self.inh.father_affected = True self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 212, with affected mother self.set_trio_genos(var, "212") self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 222, with affected mother self.set_trio_genos(var, "222") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 222, with affected mother self.set_trio_genos(var, "222") self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") def test_check_homozygous_with_cnv(self): """ test that check_homozygous() works correctly for variant lists with CNVs """ # generate a test variant chrom = "X" pos = '160' child = create_cnv('F', 'unknown', chrom=chrom, pos=pos) mom = create_cnv('F', 'unknown', chrom=chrom, pos=pos) dad = create_cnv('F', 'unknown', chrom=chrom, pos=pos) cnv = TrioGenotypes(chrom, pos, child, mom, dad) var = self.variants[0] # check for trio = 200, which is non-mendelian self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check when a CNV is in the variants list self.inh.variants.append(cnv) self.assertEqual(self.inh.check_homozygous("Hemizygous"), "compound_het") self.assertEqual(self.inh.log_string, "non-mendelian, but CNV might affect call")
class TestAllosomalPy(unittest.TestCase): """ test the Allosomal class """ def setUp(self): """ define a family and variant, and start the Allosomal 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 = Allosomal(self.variants, self.trio, self.known_genes, "TEST") self.inh.is_lof = var.child.is_lof() def create_snv(self, gender, genotype): """ create a default variant """ chrom = "X" pos = "15000000" snp_id = "." ref = "A" alt = "G" filt = "PASS" # set up a SNV object, since SNV inherits VcfInfo var = SNV(chrom, pos, snp_id, ref, alt, filt) info = "HGNC=TEST;CQ=missense_variant;random_tag" format_keys = "GT:DP" sample_values = genotype + ":50" var.add_info(info) var.add_format(format_keys, sample_values) var.set_gender(gender) var.set_genotype() return var def create_cnv(self, gender, inh, chrom, pos): """ create a default variant """ snp_id = "." ref = "A" alt = "<DUP>" filt = "PASS" # set up a SNV object, since SNV inherits VcfInfo var = CNV(chrom, pos, snp_id, ref, alt, filt) info = "HGNC=TEST;HGNC_ALL=TEST;END=16000000;SVLEN=5000" format_keys = "INHERITANCE:DP" sample_values = inh + ":50" var.add_info(info) var.add_format(format_keys, sample_values) var.set_gender(gender) var.set_genotype() return var def create_family(self, child_gender, mom_aff, dad_aff): """ create a default family, with optional gender and parental statuses """ fam = Family("test") fam.add_child("child", "child_vcf", "2", child_gender) fam.add_mother("mother", "mother_vcf", mom_aff, "2") fam.add_father("father", "father_vcf", dad_aff, "1") fam.set_child() return fam def set_trio_genos(self, var, geno): """ convenience function to set the trio genotypes for a variant """ genos = {"0": "0/0", "1": "0/1", "2": "1/1"} # convert the geno codes to allele codes child = genos[geno[0]] mom = genos[geno[1]] dad = genos[geno[2]] # set the genotype field for each individual var.child.format["GT"] = child var.mother.format["GT"] = mom var.father.format["GT"] = dad # and set th genotype for each individual var.child.set_genotype() var.mother.set_genotype() var.father.set_genotype() # set the trio genotypes for the inheritance object self.inh.set_trio_genotypes(var) def test_check_variant_without_parents_female(self): """ test that check_variant_without_parents() works correctly for female """ var = self.variants[0] var.child.set_gender("F") self.set_trio_genos(var, "100") # remove the parents, so it appears the var lacks parental information self.inh.trio.mother = None self.inh.trio.father = None # check for X-linked dominant inheritance self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "allosomal without parents") self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance self.set_trio_genos(var, "100") self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "hemizygous") self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant") def test_check_variant_without_parents_male(self): """ test that check_variant_without_parents() works correctly for males """ var = self.variants[0] var.child.set_gender("M") self.set_trio_genos(var, "200") # remove the parents, so it appears the var lacks parental information self.inh.trio.mother = None self.inh.trio.father = None # check for X-linked dominant inheritance self.assertEqual(self.inh.check_variant_without_parents("X-linked dominant"), "single_variant") # and check for hemizygous inheritance self.assertEqual(self.inh.check_variant_without_parents("Hemizygous"), "single_variant") def test_check_heterozygous_de_novo(self): """ test that check_heterozygous() works correctly for de novos """ # all of these tests are run for female X chrom de novos, since male # X chrom hets don't exist var = self.variants[0] self.set_trio_genos(var, "100") # check for X-linked dominant inheritance self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "female x chrom de novo") # check for biallelic inheritance self.assertEqual(self.inh.check_heterozygous("Hemizygous"), "single_variant") with self.assertRaises(ValueError): self.inh.check_heterozygous("X-linked over-dominance") for geno in ["102", "110", "112", "122"]: self.set_trio_genos(var, geno) self.inh.check_heterozygous("X-linked dominant") self.assertNotEqual(self.inh.log_string, "female x chrom de novo") def test_check_heterozygous_affected_mother(self): """ test that check_heterozygous() works correctly for affected mothers """ var = self.variants[0] # check that trio = 110, with het affected mother is captured self.set_trio_genos(var, "110") self.inh.mother_affected = True self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # check that when the other parent is also non-ref, the variant is no # longer captured, unless the parent is affected self.set_trio_genos(var, "112") self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") self.inh.father_affected = True self.inh.check_heterozygous("X-linked dominant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # and check that hemizgygous vars return as "compound_het" self.assertEqual(self.inh.check_heterozygous("Hemizygous"), "compound_het") def test_check_heterozygous_affected_father(self): """ test that check_heterozygous() works correctly for affected fathers """ var = self.variants[0] # set the father as non-ref genotype and affected self.set_trio_genos(var, "102") # check that the het proband, with het unaffected father is passes self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that the het proband, with het affected father is captured self.inh.father_affected = True self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") # check that when the other parent is also non-ref, the variant is no # longer captured, unless the parent is affected self.set_trio_genos(var, "112") self.assertEqual(self.inh.check_heterozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") self.inh.mother_affected = True self.inh.check_heterozygous("X-linked dominant") self.assertEqual(self.inh.log_string, "x chrom transmitted from aff, other parent non-carrier or aff") def test_check_homozygous_male(self): """ test that check_homozygous() works correctly for males """ var = self.variants[0] self.trio.child.gender = "M" # check for trio = 200, which is de novo on male X chrom self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom de novo") # check for trio = 210, with unaffected mother self.set_trio_genos(var, "210") self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 210, with affected mother, which should not pass self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check for trio = 220, with affected mother self.set_trio_genos(var, "220") self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "single_variant") self.assertEqual(self.inh.log_string, "male X chrom inherited from het mother or hom affected mother") # check for trio = 220, with unaffected mother, which should not pass self.set_trio_genos(var, "220") self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("X-linked dominant"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # check that non-standard inheritance modes raise errors with self.assertRaises(ValueError): self.inh.check_homozygous("X-linked over-dominance") def test_check_homozygous_female(self): """ test that check_homozygous() works correctly for females """ var = self.variants[0] # check for trio = 200, which is non-mendelian self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check for trio = 210, which is non-mendelian self.set_trio_genos(var, "210") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check for trio = 202, which is non-mendelian self.set_trio_genos(var, "202") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # and check for trio = 212, without affected parents self.set_trio_genos(var, "212") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") # and check for trio = 212, with affected father self.set_trio_genos(var, "212") self.inh.father_affected = True self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 212, with affected mother self.set_trio_genos(var, "212") self.inh.mother_affected = True self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 222, with affected mother self.set_trio_genos(var, "222") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "single_variant") self.assertEqual(self.inh.log_string, "testing") # and check for trio = 222, with affected mother self.set_trio_genos(var, "222") self.inh.mother_affected = False self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "variant not compatible with being causal") def test_check_homozygous_with_cnv(self): """ test that check_homozygous() works correctly for variant lists with CNVs """ # generate a test variant chrom = "X" position = "60000" child_var = self.create_cnv("F", "unknown", chrom, position) mom_var = self.create_cnv("F", "unknown", chrom, position) dad_var = self.create_cnv("M", "unknown", chrom, position) cnv_var = TrioGenotypes(child_var) cnv_var.add_mother_variant(mom_var) cnv_var.add_father_variant(dad_var) var = self.variants[0] # check for trio = 200, which is non-mendelian self.set_trio_genos(var, "200") self.assertEqual(self.inh.check_homozygous("Hemizygous"), "nothing") self.assertEqual(self.inh.log_string, "non-mendelian trio") # check when a CNV is in the variants list self.inh.variants.append(cnv_var) self.assertEqual(self.inh.check_homozygous("Hemizygous"), "compound_het") self.assertEqual(self.inh.log_string, "non-mendelian, but CNV might affect call")
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))
class TestInheritancePy(unittest.TestCase): """ test the Inheritance class """ 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 create_snv(self, gender, genotype, chrom, pos): """ create a default variant """ snp_id = "." ref = "A" alt = "G" filt = "PASS" # set up a SNV object, since SNV inherits VcfInfo var = SNV(chrom, pos, snp_id, ref, alt, filt) info = "HGNC=TEST;CQ=missense_variant;random_tag" format_keys = "GT:DP" sample_values = genotype + ":50" var.add_info(info) var.add_format(format_keys, sample_values) var.set_gender(gender) var.set_genotype() return var def create_cnv(self, gender, inh, chrom, pos): """ create a default variant """ snp_id = "." ref = "A" alt = "<DUP>" filt = "PASS" # set up a SNV object, since SNV inherits VcfInfo var = CNV(chrom, pos, snp_id, ref, alt, filt) info = "HGNC=TEST;HGNC_ALL=TEST;END=16000000;SVLEN=5000" format_keys = "INHERITANCE:DP" sample_values = inh + ":50" var.add_info(info) var.add_format(format_keys, sample_values) var.set_gender(gender) var.set_genotype() return var def create_variant(self, child_gender, chrom="1", position="15000000"): """ creates a TrioGenotypes variant """ # generate a test variant child_var = self.create_snv(child_gender, "0/1", chrom, position) mom_var = self.create_snv("F", "0/0", chrom, position) dad_var = self.create_snv("M", "0/0", chrom, position) var = TrioGenotypes(child_var) var.add_mother_variant(mom_var) var.add_father_variant(dad_var) return var def create_family(self, child_gender, mom_aff, dad_aff): """ create a default family, with optional gender and parental statuses """ fam = Family("test") fam.add_child("child", "child_vcf", "2", child_gender) fam.add_mother("mother", "mother_vcf", mom_aff, "2") fam.add_father("father", "father_vcf", dad_aff, "1") fam.set_child() return fam def test_check_inheritance_mode_matches_gene_mode(self): """ test that check_inheritance_mode_matches_gene_mode() works correctly """ # check that the default inheritance types have been set up correctly self.assertEqual(self.inh.inheritance_modes, {"Monoallelic", "Biallelic", "Both"}) # make sure that the default var and gene inheritance work self.assertTrue(self.inh.check_inheritance_mode_matches_gene_mode()) # check that no gene inheritance overlap fails self.inh.gene_inheritance = {"Mosaic"} self.inh.inheritance_modes = {"Monoallelic", "Biallelic", "Both"} self.assertFalse(self.inh.check_inheritance_mode_matches_gene_mode()) # check that a single inheritance type still works self.inh.gene_inheritance = {"Monoallelic"} self.assertTrue(self.inh.check_inheritance_mode_matches_gene_mode()) # check that multiple inheritance types for a gene still work self.inh.gene_inheritance = {"Monoallelic", "Biallelic"} self.assertTrue(self.inh.check_inheritance_mode_matches_gene_mode()) # check that extra inheritance modes are included still work self.inh.gene_inheritance = {"Monoallelic", "Biallelic", "Mosaic"} self.assertTrue(self.inh.check_inheritance_mode_matches_gene_mode()) def test_set_trio_genotypes(self): """ test that set_trio_genotypes() works correctly """ # set the genotypes using the default variant var = self.variants[0] self.inh.set_trio_genotypes(var) # the genotypes for the inh object should match the vars genotypes self.assertEqual(self.inh.child, var.child) self.assertEqual(self.inh.mom, var.mother) self.assertEqual(self.inh.dad, var.father) # now remove the parents before re-setting the genotypes del var.mother del var.father self.inh.trio.father = None self.inh.trio.mother = None self.inh.set_trio_genotypes(var) # the child should match the vars genotypes, but the parent's # genotypes should be None self.assertEqual(self.inh.child, var.child) self.assertIsNone(self.inh.mom) self.assertIsNone(self.inh.dad) def test_add_variant_to_appropriate_list(self): """ test that add_variant_to_appropriate_list() works correctly """ var = self.variants[0] inheritance = "Monoallelic" check = "compound_het" # check that compound_het vars are only added to the compound_het list self.inh.compound_hets = [] self.inh.candidates = [] self.inh.add_variant_to_appropriate_list(var, check, inheritance) self.assertEqual(self.inh.candidates, []) self.assertEqual(self.inh.compound_hets, [(var, check, inheritance)]) # check that single_variant vars are only added to the candidates list self.inh.compound_hets = [] self.inh.candidates = [] check = "single_variant" self.inh.add_variant_to_appropriate_list(var, check, inheritance) self.assertEqual(self.inh.candidates, [(var, check, inheritance)]) self.assertEqual(self.inh.compound_hets, []) # check that other vars aren't added either list self.inh.compound_hets = [] self.inh.candidates = [] check = "nothing" self.inh.add_variant_to_appropriate_list(var, check, inheritance) self.assertEqual(self.inh.candidates, []) self.assertEqual(self.inh.compound_hets, []) def test_check_if_any_variant_is_cnv(self): """ test if check_if_any_variant_is_cnv() works correctly """ # generate a test variant chrom = "1" position = "60000" child_var = self.create_cnv("F", "unknown", chrom, position) mom_var = self.create_cnv("F", "unknown", chrom, position) dad_var = self.create_cnv("M", "unknown", chrom, position) cnv_var = TrioGenotypes(child_var) cnv_var.add_mother_variant(mom_var) cnv_var.add_father_variant(dad_var) # check that all variants=SNV returns False self.assertFalse(self.inh.check_if_any_variant_is_cnv()) # add a CNV to the variants, then check that we find a CNV self.inh.variants.append(cnv_var) self.assertTrue(self.inh.check_if_any_variant_is_cnv()) def set_compound_het_var(self, var, geno, compound_type): """ convenience function to set the trio genotypes for a variant """ genos = {"0": "0/0", "1": "0/1", "2": "1/1"} # convert the geno codes to allele codes child = genos[geno[0]] mom = genos[geno[1]] dad = genos[geno[2]] # set the genotype field for each individual var.child.format["GT"] = child var.mother.format["GT"] = mom var.father.format["GT"] = dad # and set th genotype for each individual var.child.set_genotype() var.mother.set_genotype() var.father.set_genotype() # set the trio genotypes for the inheritance object return (var, compound_type, "Biallelic") 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)) def test_check_compound_hets_allosomal(self): """ test that check_compound_hets() works correctly for allosomal vars """ # set some X chrom variants, so we can alter them later var1 = self.create_variant("F", chrom="X", position="15000000") var2 = self.create_variant("F", chrom="X", position="16000000") # set the inheritance type, the compound het type ("hemizygous" # for allosomal variants, and start allosomal inheritance) inh = "Hemizygous" compound = "hemizygous" self.inh = Allosomal([var1, var2], self.trio, inh) variants = ["", ""] # check that de novo containing "110, 100" combos pass 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 "110, 102" combo fails if the father is unaffected variants[0] = self.set_compound_het_var(var1, "110", compound) variants[1] = self.set_compound_het_var(var2, "102", compound) self.assertEqual(self.inh.check_compound_hets(variants), []) # check that "110, 102" combo passes if the father is 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)) # make sure we can't set the father as het on the X chrom with self.assertRaises(ValueError): self.set_compound_het_var(var2, "101", compound)