def test_open_ped_single_family(self): """ check that we correctly parse a ped file with a single trio """ # load all the components from the file self.assertEqual( open_ped(self.path), { 'fam_ID': [ Person(family_id="fam_ID", person_id="proband", dad_id="dad", mom_id="mom", sex="F", status="2", path="/path/to/proband_vcf.gz"), Person(family_id="fam_ID", person_id="dad", dad_id="0", mom_id="0", sex="M", status="1", path="/path/to/dad_vcf.gz"), Person(family_id="fam_ID", person_id="mom", dad_id="0", mom_id="0", sex="F", status="1", path="/path/to/mom_vcf.gz") ] })
def setUp(self): """ define a default Person object """ ID = "name" path = "/home/filename.vcf" status = "2" gender = "1" self.person = Person(ID, path, status, gender)
def setUp(self): """ define a default Person object """ family_id = "fam_id" person_id = "name" path = "/home/filename.vcf" status = "2" sex = "1" mom_id = "mom_id" dad_id = "dad_id" self.person = Person(family_id, person_id, dad_id, mom_id, sex, status, path)
def test_open_individual(self): ''' test that open_individual() works correctly ''' # missing individual returns empty list self.assertEqual(open_individual(None), []) vcf = make_vcf_header() vcf.append(make_vcf_line(pos=1, extra='HGNC=TEST;MAX_AF=0.0001')) vcf.append(make_vcf_line(pos=2, extra='HGNC=ATRX;MAX_AF=0.0001')) path = os.path.join(self.temp_dir, "temp.vcf") write_temp_vcf(path, vcf) person = Person('fam_id', 'sample', 'dad', 'mom', 'F', '2', path) var1 = SNV(chrom="1", position=1, id=".", ref="G", alts="T", qual='1000', filter="PASS", info="CQ=missense_variant;HGNC=TEST;MAX_AF=0.0001", format="DP:GT", sample="50:0/1", gender="female", mnv_code=None) var2 = SNV(chrom="1", position=2, id=".", ref="G", alts="T", qual='1000', filter="PASS", info="CQ=missense_variant;HGNC=ATRX;MAX_AF=0.0001", format="DP:GT", sample="50:0/1", gender="female", mnv_code=None) self.assertEqual(open_individual(person), [var2]) # define a set of variants to automatically pass, and check that these # variants pass. child_keys = set([('1', 1), ('1', 2)]) self.assertEqual(open_individual(person, child_variants=child_keys), [var1, var2])
def test_load_variants(self): ''' test that load_variants() works correctly. Mainly checks variables are set correctly. ''' vcf = make_minimal_vcf() path = os.path.join(self.temp_dir, "temp.vcf.gz") write_gzipped_vcf(path, vcf) sum_x_lr2 = {} parents = True fam = Family( 'fam', children=[Person('fam', 'child', '0', '0', 'f', '2', path)]) variants = load_variants(fam, 0.9, ['AFR_AF'], self.known_genes, set(), sum_x_lr2, parents) self.assertEqual(SNV.known_genes, self.known_genes) self.assertEqual(CNV.known_genes, self.known_genes) self.assertEqual(Info.populations, ['AFR_AF']) self.assertEqual(Info.last_base, set()) # and check that the variants = load_variants(fam, 0.9, [], None, set([('1', 100)]), sum_x_lr2, parents) self.assertIsNone(SNV.known_genes, self.known_genes) self.assertIsNone(CNV.known_genes, self.known_genes) self.assertEqual(Info.populations, []) self.assertEqual(Info.last_base, set([('1', 100)]))
def test_debug_option(self): """ test whether we can set up the class with the debug option """ known = {} pops = None sum_x_lr2 = {} vcf = make_minimal_vcf() path = os.path.join(self.temp_dir, "temp.vcf.gz") write_gzipped_vcf(path, vcf) fam = Family( 'fam', children=[Person('fam', 'child', '0', '0', 'f', '2', path)]) # if the debug info isn't available, then the SNV object doesn't use the # debug filter function variants = load_variants(fam, 1.0, pops, known, set(), sum_x_lr2) self.assertNotEqual(SNV.passes_filters, SNV.passes_filters_with_debug) # if the debug info is passed in, check that the debug filter function # got set correctly variants = load_variants(fam, 1.0, pops, known, set(), sum_x_lr2, "1", "10000") self.assertEqual(SNV.passes_filters, SNV.passes_filters_with_debug)
def test_open_individual_with_mnvs(self): ''' test that open_individual works with MNVs ''' vcf = make_vcf_header() vcf.append(make_vcf_line(pos=1, cq='splice_region_variant', extra='HGNC=ATRX;MAX_AF=0.0001')) vcf.append(make_vcf_line(pos=2, cq='missense_variant', extra='HGNC=ATRX;MAX_AF=0.0001')) path = os.path.join(self.temp_dir, "temp.vcf.gz") write_gzipped_vcf(path, vcf) person = Person('fam_id', 'sample', 'dad', 'mom', 'F', '2', path) args = {'chrom': "1", 'position': 1, 'id': ".", 'ref': "G", 'alts': "T", 'filter': "PASS", 'info': "CQ=splice_region_variant;HGNC=ATRX;MAX_AF=0.0001", 'format': "DP:GT", 'sample': "50:0/1", 'gender': "female", 'mnv_code': 'modified_protein_altering_mnv', 'qual': '1000'} var1 = SNV(**args) args['position'] = 2 args['mnv_code'] = None args['info'] = "CQ=missense_variant;HGNC=ATRX;MAX_AF=0.0001" var2 = SNV(**args) # by default only one variant passes self.assertEqual(open_individual(person), [var2]) # if we include MNVs, then the passing variants swap self.assertEqual(open_individual(person, mnvs={('1', 1): 'modified_protein_altering_mnv', ('1', 2): 'modified_synonymous_mnv'}), [var1])
def test_get_parental_var_snv(self): ''' check that get_parental_var() works correctly for SNVs ''' sex = 'F' var = create_snv(sex, '0/1') mom = Person('fam_id', 'mom', '0', '0', 'F', '1', '/PATH') parental = [] # try to get a matching variant for a mother. This will create a default # variant for a missing parental genotype self.assertEqual( get_parental_var(var, parental, mom), SNV(chrom="1", position=150, id=".", ref="A", alts="G", qual='1000', filter="PASS", info=str(var.info), format="GT", sample="0/0", gender="female", mnv_code=None)) # now see if we can pick up a variant where it does exist mother_var = create_snv(sex, '0/0') self.assertEqual(get_parental_var(var, [mother_var], mom), mother_var)
def test_open_ped_multiple_sibs(self): """ check that we correctly parse a ped file with multiple siblings """ # add an extra sibling self.tempfile.write( "fam_ID sib dad mom F 2 /path/to/sib_vcf.gz\n") self.tempfile.flush() # load all the components from the file self.assertEqual( open_ped(self.path), { 'fam_ID': [ Person(family_id="fam_ID", person_id="proband", dad_id="dad", mom_id="mom", sex="F", status="2", path="/path/to/proband_vcf.gz"), Person(family_id="fam_ID", person_id="dad", dad_id="0", mom_id="0", sex="M", status="1", path="/path/to/dad_vcf.gz"), Person(family_id="fam_ID", person_id="mom", dad_id="0", mom_id="0", sex="F", status="1", path="/path/to/mom_vcf.gz"), Person(family_id="fam_ID", person_id="sib", dad_id="mom", mom_id="dad", sex="F", status="2", path="/path/to/sib_vcf.gz") ] })
def test__iter__(self): ''' test that __iter__() works correctly ''' family_id, person_id, mom_id, dad_id = 'fam_ID', 'child', 'dad', 'mom', path, status, sex = 'child.vcf', '2', 'M' child = Person(family_id, person_id, dad_id, mom_id, sex, status, path) self.family.add_child(person_id, dad_id, mom_id, sex, status, path) self.family.set_child() # check the Family iterates by getting a list of the Family object members = list(self.family) self.assertEqual(members, [child, None, None])
def test_get_parental_var_cnv_maternally_inherited(self): ''' test that we can construct a maternally inherited CNV ''' sex = 'F' mom = Person('fam_id', 'mom', '0', '0', 'F', '1', '/PATH') # check that even if a CNV exist in the parent at a matching site, we # still create a new CNV object for the parent var = create_cnv(sex, 'maternal') self.assertEqual(get_parental_var(var, [], mom), CNV(chrom="1", position=150, id=".", ref="A", alts="<DUP>", qual='1000',filter="PASS", info=str(var.info), format='INHERITANCE', sample='uncertain', gender="female", mnv_code=None))
def test_open_individual_male_het_chrx(self): """ test that open_individual() passes over hets in males on chrX """ # the sub-functions are all tested elsewhere, this test merely checks # that valid variants are added to the variants list, and invalid # variants are passed over without being added to the variants list vcf = make_vcf_header() vcf.append(make_vcf_line(chrom='X', pos=1, genotype='0/1', extra='HGNC=TEST;MAX_AF=0.0001')) path = os.path.join(self.temp_dir, "temp.vcf") write_temp_vcf(path, vcf) person = Person('fam_id', 'sample', 'dad', 'mom', 'M', '2', path) self.assertEqual(open_individual(person), [])
def test_get_parental_var_cnv(self): ''' check that get_parental_var() works correctly for CNVs ''' sex = 'F' var = create_cnv(sex, 'deNovo') mom = Person('fam_id', 'mom', '0', '0', 'F', '1', '/PATH') parental_vars = [] self.assertEqual( get_parental_var(var, parental_vars, mom), CNV(chrom="1", position=150, id=".", ref="A", alts="<REF>", qual='1000', filter="PASS", info=str(var.info), format='INHERITANCE', sample='uncertain', gender="female", mnv_code=None)) # check that even if a CNV exist in the parent at a matching site, we # still create a new CNV objectr for the parent mother_var = create_cnv(sex, 'uncertain') self.assertEqual( get_parental_var(var, [mother_var], mom), CNV(chrom="1", position=150, id=".", ref="A", alts="<REF>", qual='1000', filter="PASS", info=str(var.info), format='INHERITANCE', sample='uncertain', gender="female", mnv_code=None))
class TestPerson(unittest.TestCase): """ """ def setUp(self): """ define a default Person object """ ID = "name" path = "/home/filename.vcf" status = "2" gender = "1" self.person = Person(ID, path, status, gender) def test_get_id(self): """ test that get_id() works correctly """ self.person.person_id = "test_id" self.assertEqual(self.person.get_id(), "test_id") def test_get_path(self): """ test that get_path() works correctly """ self.person.vcf_path = "test_path" self.assertEqual(self.person.get_path(), "test_path") def test_get_affected_status(self): """ test that get_affected_status works correctly """ self.person.affected_status = "test_status" self.assertEqual(self.person.get_affected_status(), "test_status") def test_is_affected(self): """ test that is_affected() works correctly """ # check that a status of "1" means unaffected self.person.affected_status = "1" self.assertFalse(self.person.is_affected()) # check that a status of "2" means affected self.person.affected_status = "2" self.assertTrue(self.person.is_affected()) # check that statuses other than "1" or "2" raise an error self.person.affected_status = "3" with self.assertRaises(ValueError): self.assertFalse(self.person.is_affected()) def test_set_analysed(self): """ test that set_analysed() and is_analysed() work correctly """ # check that by default a person is not analysed self.assertFalse(self.person.is_analysed()) # check that set_analysed() changes the flag correctly self.person.set_analysed() self.assertTrue(self.person.is_analysed()) # check that repeating set_analysed() does not affected anything self.person.set_analysed() self.assertTrue(self.person.is_analysed()) def test_get_gender(self): """ test that get_gender() works correctly """ self.person.gender = "M" self.assertEqual(self.person.get_gender(), "M") def test_is_male(self): """ test that is_male() works correctly """ male_codes = ["1", "M", "m", "male"] for code in male_codes: self.person.gender = code self.assertTrue(self.person.is_male()) female_codes = ["2", "f", "F", "female"] for code in female_codes: self.person.gender = code self.assertFalse(self.person.is_male()) def test_is_female(self): """ test that is_female() works correctly """ female_codes = ["2", "f", "F", "female"] for code in female_codes: self.person.gender = code self.assertTrue(self.person.is_female()) male_codes = ["1", "M", "m", "male"] for code in male_codes: self.person.gender = code self.assertFalse(self.person.is_female()) def test_check_gender(self): """ test that check_gender() works correctly """ # check that a male gender doesn't raise an error if we check that it # is male self.person.gender = "M" self.person.check_gender("1") # check that we raise an error if the gender doesn't match the expected # (useful in catching errors with the parents) with self.assertRaises(ValueError): self.person.check_gender("2") # check that a female gender doesn't raise an error if we check that it # is female self.person.gender = "F" self.person.check_gender("2") # check that we raise an error if the gender doesn't match the expected # (useful in catching errors with the parents) with self.assertRaises(ValueError): self.person.check_gender("1") # check that we raise an error for nonstandard gender codes self.person.gender = "NA" with self.assertRaises(ValueError): self.person.check_gender("2")
class TestPerson(unittest.TestCase): """ """ def setUp(self): """ define a default Person object """ family_id = "fam_id" person_id = "name" path = "/home/filename.vcf" status = "2" sex = "1" mom_id = "mom_id" dad_id = "dad_id" self.person = Person(family_id, person_id, dad_id, mom_id, sex, status, path) def test_get_id(self): """ test that get_id() works correctly """ self.person.person_id = "test_id" self.assertEqual(self.person.get_id(), "test_id") def test_get_path(self): """ test that get_path() works correctly """ self.person.vcf_path = "test_path" self.assertEqual(self.person.get_path(), "test_path") def test_get_affected_status(self): """ test that get_affected_status works correctly """ self.person.status = "test_status" self.assertEqual(self.person.get_affected_status(), "test_status") def test_is_affected(self): """ test that is_affected() works correctly """ # check that a status of "1" means unaffected self.person.status = "1" self.assertFalse(self.person.is_affected()) # check that a status of "2" means affected self.person.status = "2" self.assertTrue(self.person.is_affected()) # check that statuses other than "1" or "2" raise an error self.person.status = "3" with self.assertRaises(ValueError): self.assertFalse(self.person.is_affected()) def test_set_analysed(self): """ test that set_analysed() and is_analysed() work correctly """ # check that by default a person is not analysed self.assertFalse(self.person.is_analysed()) # check that set_analysed() changes the flag correctly self.person.set_analysed() self.assertTrue(self.person.is_analysed()) # check that repeating set_analysed() does not affected anything self.person.set_analysed() self.assertTrue(self.person.is_analysed()) def test_get_gender(self): """ test that get_gender() works correctly """ self.person.sex = "M" self.assertEqual(self.person.get_gender(), "M") def test_is_male(self): """ test that is_male() works correctly """ male_codes = ["1", "M", "m", "male"] for code in male_codes: self.person.sex = code self.assertTrue(self.person.is_male()) female_codes = ["2", "f", "F", "female"] for code in female_codes: self.person.sex = code self.assertFalse(self.person.is_male()) def test_is_female(self): """ test that is_female() works correctly """ female_codes = ["2", "f", "F", "female"] for code in female_codes: self.person.sex = code self.assertTrue(self.person.is_female()) male_codes = ["1", "M", "m", "male"] for code in male_codes: self.person.sex = code self.assertFalse(self.person.is_female()) def test_check_gender(self): """ test that check_gender() works correctly """ # check that a male gender doesn't raise an error if we check that it # is male self.person.sex = "M" self.person.check_gender("1") # check that we raise an error if the gender doesn't match the expected # (useful in catching errors with the parents) with self.assertRaises(ValueError): self.person.check_gender("2") # check that a female gender doesn't raise an error if we check that it # is female self.person.sex = "F" self.person.check_gender("2") # check that we raise an error if the gender doesn't match the expected # (useful in catching errors with the parents) with self.assertRaises(ValueError): self.person.check_gender("1") # check that we raise an error for nonstandard gender codes self.person.sex = "NA" with self.assertRaises(ValueError): self.person.check_gender("2")
def test_analyse_trio(self): ''' test that analyse_trio() works correctly ''' # construct the VCFs for the trio members paths = {} for member in ['child', 'mom', 'dad']: vcf = make_vcf_header() geno, pp_dnm = '0/0', '' if member == 'child': geno, pp_dnm = '0/1', ';DENOVO-SNP;PP_DNM=1' vcf.append( make_vcf_line(genotype=geno, extra='HGNC=ARID1B' + pp_dnm)) # write the VCF data to a file handle = tempfile.NamedTemporaryFile(dir=self.temp_dir, delete=False, suffix='.vcf') for x in vcf: handle.write(x.encode('utf8')) handle.flush() paths[member] = handle.name # create a Family object, so we can load the data from the trio's VCFs fam_id = 'fam01' child = Person(fam_id, 'child', 'dad', 'mom', 'female', '2', paths['child']) mom = Person(fam_id, 'mom', '0', '0', 'female', '1', paths['mom']) dad = Person(fam_id, 'dad', '0', '0', 'male', '1', paths['dad']) family = Family(fam_id, [child], mom, dad) self.assertEqual(self.finder.analyse_trio(family), [(TrioGenotypes( chrom="1", pos=1, child=SNV( chrom="1", position=1, id=".", ref="G", alts="T", qual='1000', filter="PASS", info="CQ=missense_variant;DENOVO-SNP;HGNC=ARID1B;PP_DNM=1", format="DP:GT", sample="50:0/1", gender="female", mnv_code=None), mother=SNV(chrom="1", position=1, id=".", ref="G", alts="T", qual='1000', filter="PASS", info="CQ=missense_variant;HGNC=ARID1B", format="DP:GT", sample="50:0/0", gender="female", mnv_code=None), father=SNV(chrom="1", position=1, id=".", ref="G", alts="T", qual='1000', filter="PASS", info="CQ=missense_variant;HGNC=ARID1B", format="DP:GT", sample="50:0/0", gender="male", mnv_code=None)), ['single_variant'], [ 'Monoallelic', 'Mosaic' ], ['ARID1B'])])