Example #1
0
    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")
                ]
            })
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
 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])
Example #5
0
    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)]))
Example #6
0
    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)
Example #7
0
 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])
Example #8
0
    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)
Example #9
0
    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 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)
Example #11
0
    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])
Example #12
0
 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))
Example #13
0
 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), [])
Example #14
0
    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))
Example #15
0
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'])])