Beispiel #1
0
 def test_dfe_errors(self):
     m1 = stdpopsim.MutationType()
     m2 = stdpopsim.MutationType()
     for bad_props in [["abc"], 1.0, [1.0], [0.2, 0.4, 0.4], [-0.1, -0.1]]:
         with pytest.raises(ValueError):
             _ = stdpopsim.DFE(
                 id="abc",
                 description="test test",
                 long_description="test test test test",
                 proportions=bad_props,
                 mutation_types=[m1, m2],
             )
     for bad_mut_types in ["abc", {}, [1.0, 2.0], [m1], m1, ["a", "b"]]:
         with pytest.raises(ValueError):
             _ = stdpopsim.DFE(
                 id="abc",
                 description="test test",
                 long_description="test test test test",
                 proportions=[0.6, 0.4],
                 mutation_types=bad_mut_types,
             )
     for bad_sums in [[-0.4, 0.5], [0.6, 0.8], [139487135987, 0.0],
                      [0.2, 0.3]]:
         print(bad_sums)
         with pytest.raises(ValueError):
             _ = stdpopsim.DFE(
                 id="abc",
                 description="test test",
                 long_description="test test test test",
                 proportions=bad_sums,
                 mutation_types=[m1, m2],
             )
Beispiel #2
0
 def test_is_neutral(self):
     for neutral in (True, False):
         for dist in ("f", "e"):
             contig = stdpopsim.Contig.basic_contig(length=100)
             contig.clear_dfes()
             props = [0.3, 0.7]
             if neutral:
                 s = 0
             else:
                 s = 0.1
             mt = [
                 stdpopsim.MutationType(distribution_type=dist,
                                        distribution_args=[s])
                 for _ in props
             ]
             dfes = [
                 stdpopsim.DFE(
                     id=str(j),
                     description="test",
                     long_description="test test",
                     proportions=props,
                     mutation_types=mt,
                 ) for j in range(2)
             ]
             contig.add_dfe(
                 intervals=np.array([[10, 30], [50, 100]]),
                 DFE=dfes[0],
             )
             contig.add_dfe(intervals=np.array([[30, 40]]), DFE=dfes[1])
             # exponential with mean zero doesn't count as neutral!
             assert contig.is_neutral is (neutral and dist == "f")
Beispiel #3
0
 def test_no_msprime_DFE(self):
     # test we cannot simulate a non-neutral DFE with msprime
     m1 = stdpopsim.ext.MutationType(
         dominance_coeff=0.2,
         distribution_type="e",
         distribution_args=[0.1],
     )
     desc = "test test"
     long_desc = "test test 🐢"
     dfe = stdpopsim.DFE(
         id="abc",
         description=desc,
         long_description=long_desc,
         mutation_types=[m1],
     )
     contig = stdpopsim.Contig.basic_contig(
         length=10000,
         mutation_rate=1e-6,
     )
     contig.clear_genomic_mutation_types()
     contig.add_DFE(
         intervals=np.array([[0, contig.length / 2]], dtype="int"),
         DFE=dfe,
     )
     model = stdpopsim.PiecewiseConstantSize(1000)
     samples = model.get_samples(2)
     engine = stdpopsim.get_engine("msprime")
     with pytest.raises(ValueError):
         _ = engine.simulate(
             model,
             contig,
             samples,
         )
Beispiel #4
0
def _KimDFE():
    id = "Gamma_K17"
    description = "Deleterious Gamma DFE"
    long_description = """
    Return neutral and negative MutationType()s representing a human DFE.
    Kim et al. (2017), https://doi.org/10.1534/genetics.116.197145
    """
    citations = [
        stdpopsim.Citation(
            author="Kim et al.",
            year=2017,
            doi="https://doi.org/10.1534/genetics.116.197145",
            reasons="to be defined",  # include the dfe_model reason
        )
    ]
    neutral = stdpopsim.ext.MutationType()
    gamma_shape = 0.186  # shape
    gamma_mean = -0.01314833  # expected value
    h = 0.5  # dominance coefficient
    negative = stdpopsim.ext.MutationType(
        dominance_coeff=h,
        distribution_type="g",  # gamma distribution
        distribution_args=[gamma_mean, gamma_shape],
    )

    return stdpopsim.DFE(
        id=id,
        description=description,
        long_description=long_description,
        mutation_types=[neutral, negative],
        proportions=[0.3, 0.7],
        citations=citations,
    )
Beispiel #5
0
 def test_too_many_dfes(self):
     contig = stdpopsim.Contig.basic_contig(length=100)
     contig.clear_DFEs()
     props = [0.3, 0.7]
     mt = [
         stdpopsim.ext.MutationType(distribution_type="e",
                                    distribution_args=[1]) for _ in props
     ]
     dfes = [
         stdpopsim.DFE(
             id=str(j),
             description="test",
             long_description="test test",
             proportions=props,
             mutation_types=mt,
         ) for j in range(3)
     ]
     contig.add_DFE(intervals=np.array([[10, 30], [50, 100]]),
                    DFE=dfes[0],
                    fill_neutral=False)
     contig.add_DFE(intervals=np.array([[30, 40]]),
                    DFE=dfes[1],
                    fill_neutral=False)
     with pytest.raises(ValueError):
         contig.add_DFE(intervals=np.array([[30, 40]]),
                        DFE=dfes[2],
                        fill_neutral=False)
Beispiel #6
0
 def test_DFE_defaults(self):
     m1 = stdpopsim.ext.MutationType()
     desc = "test test"
     long_desc = "test test 🐢"
     dfe = stdpopsim.DFE(
         id="abc",
         description=desc,
         long_description=long_desc,
         mutation_types=[m1],
         proportions=[],
     )
     assert isinstance(dfe.proportions, list)
     assert len(dfe.proportions) == 1
     assert dfe.proportions[0] == 1
Beispiel #7
0
 def test_add_DFE_errors(self):
     contig = stdpopsim.Contig.basic_contig(length=100)
     props = [0.3, 0.7]
     mt = [stdpopsim.ext.MutationType() for _ in props]
     # bad intervals
     dfe = stdpopsim.DFE(
         id="abc",
         description="test",
         long_description="test test",
         proportions=props,
         mutation_types=mt,
     )
     with pytest.raises(ValueError):
         contig.add_DFE(np.array([10, 20]), dfe)
Beispiel #8
0
 def test_non_neutral_contig(self):
     species = stdpopsim.get_species("HomSap")
     model = species.get_demographic_model("AshkSub_7G19")
     samples = model.get_samples(10)
     contig = stdpopsim.Contig.basic_contig(length=100)
     contig.clear_DFEs()
     props = [1]
     mt = [stdpopsim.ext.MutationType(distribution_type="f", distribution_args=[1])]
     dfes = [
         stdpopsim.DFE(
             id=str(0),
             description="test",
             long_description="test test",
             proportions=props,
             mutation_types=mt,
         )
     ]
     contig.add_DFE(intervals=np.array([[0, 50]]), DFE=dfes[0])
     engine = stdpopsim.get_engine("msprime")
     with pytest.raises(ValueError):
         engine.simulate(model, contig, samples, seed=1)
     # okay now change selection coefficient to neutral
     contig.clear_DFEs()
     props = [1]
     mt = [stdpopsim.ext.MutationType(distribution_type="f", distribution_args=[0])]
     dfes = [
         stdpopsim.DFE(
             id=str(0),
             description="test",
             long_description="test test",
             proportions=props,
             mutation_types=mt,
         )
     ]
     contig.add_DFE(intervals=np.array([[0, 50]]), DFE=dfes[0])
     engine = stdpopsim.get_engine("msprime")
     engine.simulate(model, contig, samples, seed=1)
Beispiel #9
0
 def test_printing_DFE(self, capsys):
     m1 = stdpopsim.ext.MutationType()
     desc = "test test"
     long_desc = "test test 🐢"
     dfe = stdpopsim.DFE(
         id="abc",
         description=desc,
         long_description=long_desc,
         mutation_types=[m1],
     )
     print(dfe)
     captured = capsys.readouterr()
     assert "DFE:\n" in captured.out
     assert "║" in captured.out
     assert "║  id               = abc\n" in captured.out
Beispiel #10
0
 def test_basic_DFE(self):
     desc = "test test"
     long_desc = "test test 🐢"
     for props in ([0.4, 0.6], [1.0, 0.0], [1.0], [1 / 3, 1 / 3, 1 / 3]):
         mt = [stdpopsim.ext.MutationType() for _ in props]
         dfe = stdpopsim.DFE(
             id="abc",
             description=desc,
             long_description=long_desc,
             proportions=props,
             mutation_types=mt,
         )
         assert dfe.id == "abc"
         assert dfe.description == desc
         assert dfe.long_description == long_desc
         for a, b in zip(props, dfe.proportions):
             assert a == b
         for a, b in zip(mt, dfe.mutation_types):
             assert a == b
Beispiel #11
0
 def test_add_dfe(self):
     for clear in (True, False):
         contig = stdpopsim.Contig.basic_contig(length=100)
         if clear:
             contig.clear_dfes()
         props = [0.3, 0.7]
         mt = [stdpopsim.MutationType() for _ in props]
         dfes = [
             stdpopsim.DFE(
                 id=str(j),
                 description="test",
                 long_description="test test",
                 proportions=props,
                 mutation_types=mt,
             ) for j in range(3)
         ]
         contig.add_dfe(
             intervals=np.array([[10, 30], [50, 100]]),
             DFE=dfes[0],
         )
         contig.add_dfe(intervals=np.array([[30, 40]]), DFE=dfes[1])
         contig.add_dfe(intervals=np.array([[20, 60]]), DFE=dfes[2])
         assert len(contig.dfe_list) == 4 - clear
         assert len(contig.mutation_types()) == 7 - clear
         if clear:
             dfe_ids = []
             true_ints = []
         else:
             true_ints = [np.array([[0, 10]])]
             dfe_ids = ["neutral"]
         dfe_ids += [dfe.id for dfe in dfes]
         true_ints += [
             np.array([[10, 20], [60, 100]]),
             np.empty((0, 2)),
             np.array([[20, 60]]),
         ]
         for d, i in zip(contig.dfe_list, dfe_ids):
             assert d.id == i
         for a1, a2 in zip(contig.interval_list, true_ints):
             assert np.all(a1.shape == a2.shape)
             assert np.all(a1 == a2)
         self.verify_dfe_breakpoints(contig)
Beispiel #12
0
 def test_dfe_breakpoints(self):
     contig = stdpopsim.Contig.basic_contig(length=100)
     contig.clear_dfes()
     mt = stdpopsim.MutationType()
     for j in range(3):
         dfe = stdpopsim.DFE(
             id=str(j),
             description="test",
             long_description="test test",
             mutation_types=[mt],
         )
         contig.add_dfe(
             np.array(
                 [[(j + 1) * 5,
                   (j + 1) * 10], [(j + 1) * 20, (j + 1) * 20 + 1]],
                 dtype="int",
             ),
             dfe,
         )
     self.verify_dfe_breakpoints(contig)
Beispiel #13
0
 def test_is_neutral2(self):
     contig = stdpopsim.Contig.basic_contig(length=100)
     contig.clear_DFEs()
     props = [0.3, 0.7]
     mt = [stdpopsim.ext.MutationType() for _ in props]
     dfes = [
         stdpopsim.DFE(
             id=str(j),
             description="test",
             long_description="test test",
             proportions=props,
             mutation_types=mt,
         ) for j in range(2)
     ]
     contig.add_DFE(intervals=np.array([[10, 30], [50, 100]]),
                    DFE=dfes[0],
                    fill_neutral=False)
     contig.add_DFE(intervals=np.array([[30, 40]]),
                    DFE=dfes[1],
                    fill_neutral=False)
     assert contig.is_neutral
Beispiel #14
0
 def test_dfe_is_neutral(self):
     for neutral in (True, False):
         for dist in ("f", "e"):
             props = [0.3, 0.7]
             if neutral:
                 svals = [0.0, 0.0]
             else:
                 svals = [0.0, 0.1]
             mt = [
                 stdpopsim.MutationType(distribution_type=dist,
                                        distribution_args=[s])
                 for s in svals
             ]
             dfe = stdpopsim.DFE(
                 id=0,
                 description="test",
                 long_description="test test",
                 proportions=props,
                 mutation_types=mt,
             )
             assert dfe.is_neutral is (neutral and dist == "f")
Beispiel #15
0
def _HuberDFE():
    id = "Gamma_H17"
    description = "Deleterious Gamma DFE"
    long_description = """
    Return neutral and negative MutationType()s representing a H**o sapiens DFE.
    Huber et al. (2017), https://doi.org/10.1073/pnas.1619508114.
    DFE parameters are based on the Full Model described in Table S2, in which
    All Data (none of the listed filters) were used.
    """  # [this was a different filtering scheme than the Huber et al DroMel DFE ]
    citations = [
        stdpopsim.Citation(
            author="Huber et al.",
            year=2017,
            doi="https://doi.org/10.1073/pnas.1619508114",
            reasons="to be defined",  # include the dfe_model reason
        )
    ]
    neutral = stdpopsim.MutationType()
    gamma_shape = 0.19  # shape
    gamma_mean = -0.014  # expected value
    h = 0.5  # dominance coefficient
    negative = stdpopsim.MutationType(
        dominance_coeff=h,
        distribution_type="g",  # gamma distribution
        distribution_args=[gamma_mean, gamma_shape],
    )

    return stdpopsim.DFE(
        id=id,
        description=description,
        long_description=long_description,
        mutation_types=[neutral, negative],
        proportions=[
            0.3,
            0.7,
        ],  # [0.3 and 0.7 were used in Xin's analysis,
        #  but I couldn't find these values in the Huber paper]
        citations=citations,
    )
Beispiel #16
0
def _HuberDFE():
    id = "Gamma_H17"
    description = "Deleterious Gamma DFE"
    long_description = """
    Return neutral and negative MutationType()s representing a drosophila DFE.
    Huber et al. (2017), https://doi.org/10.1073/pnas.1619508114.
    DFE parameters are based on the Full model described in Table S2, in which
    singletons are excluded and a recent mutation rate estimate is used
    (mu=3x10e-9, Keightley 2014).
    """
    citations = [
        stdpopsim.Citation(
            author="Huber et al.",
            year=2017,
            doi="https://doi.org/10.1073/pnas.1619508114",
            reasons="to be defined",  # include the dfe_model reason
        )
    ]
    neutral = stdpopsim.ext.MutationType()
    gamma_shape = 0.33  # shape
    gamma_mean = -3.96e-04  # expected value
    h = 0.5  # dominance coefficient
    negative = stdpopsim.ext.MutationType(
        dominance_coeff=h,
        distribution_type="g",  # gamma distribution
        distribution_args=[gamma_mean, gamma_shape],
    )

    return stdpopsim.DFE(
        id=id,
        description=description,
        long_description=long_description,
        mutation_types=[neutral, negative],
        proportions=[0.26, 0.74],  # LNS = 2.85 x LS
        citations=citations,
    )
Beispiel #17
0
class TestContig(object):

    example_dfe = stdpopsim.DFE(
        id="abc",
        description="example DFE",
        long_description="test test beep boop beep",
        proportions=[0.3, 0.7],
        mutation_types=[stdpopsim.MutationType() for _ in range(2)],
    )

    def verify_dfe_breakpoints(self, contig):
        breaks, dfe_labels = contig.dfe_breakpoints()
        for j, intervals in enumerate(contig.interval_list):
            for left, right in intervals:
                assert left in breaks
                assert right in breaks
                k = np.searchsorted(breaks, left)
                assert dfe_labels[k] == j

    def test_default_dfe(self):
        contig = stdpopsim.Contig.basic_contig(length=100)
        assert len(contig.dfe_list) == 1
        assert len(contig.interval_list) == 1
        assert contig.dfe_list[0].id == "neutral"
        assert np.all(
            contig.interval_list[0] == np.array([[0, contig.length]]))

    def test_add_dfe_errors(self):
        contig = stdpopsim.Contig.basic_contig(length=100)
        # bad intervals
        with pytest.raises(ValueError):
            contig.add_dfe(np.array([10, 20]), self.example_dfe)
        with pytest.raises(ValueError):
            contig.add_dfe("abc", self.example_dfe)

    def test_dfe_breakpoints(self):
        contig = stdpopsim.Contig.basic_contig(length=100)
        contig.clear_dfes()
        mt = stdpopsim.MutationType()
        for j in range(3):
            dfe = stdpopsim.DFE(
                id=str(j),
                description="test",
                long_description="test test",
                mutation_types=[mt],
            )
            contig.add_dfe(
                np.array(
                    [[(j + 1) * 5,
                      (j + 1) * 10], [(j + 1) * 20, (j + 1) * 20 + 1]],
                    dtype="int",
                ),
                dfe,
            )
        self.verify_dfe_breakpoints(contig)

    def test_add_dfe(self):
        for clear in (True, False):
            contig = stdpopsim.Contig.basic_contig(length=100)
            if clear:
                contig.clear_dfes()
            props = [0.3, 0.7]
            mt = [stdpopsim.MutationType() for _ in props]
            dfes = [
                stdpopsim.DFE(
                    id=str(j),
                    description="test",
                    long_description="test test",
                    proportions=props,
                    mutation_types=mt,
                ) for j in range(3)
            ]
            contig.add_dfe(
                intervals=np.array([[10, 30], [50, 100]]),
                DFE=dfes[0],
            )
            contig.add_dfe(intervals=np.array([[30, 40]]), DFE=dfes[1])
            contig.add_dfe(intervals=np.array([[20, 60]]), DFE=dfes[2])
            assert len(contig.dfe_list) == 4 - clear
            assert len(contig.mutation_types()) == 7 - clear
            if clear:
                dfe_ids = []
                true_ints = []
            else:
                true_ints = [np.array([[0, 10]])]
                dfe_ids = ["neutral"]
            dfe_ids += [dfe.id for dfe in dfes]
            true_ints += [
                np.array([[10, 20], [60, 100]]),
                np.empty((0, 2)),
                np.array([[20, 60]]),
            ]
            for d, i in zip(contig.dfe_list, dfe_ids):
                assert d.id == i
            for a1, a2 in zip(contig.interval_list, true_ints):
                assert np.all(a1.shape == a2.shape)
                assert np.all(a1 == a2)
            self.verify_dfe_breakpoints(contig)

    @pytest.mark.skip(reason="TODO allow more flexible inputs")
    def test_add_dfe_interval_formats(self):
        L = 50818
        for intervals in (
            [[0, L]],
            [[0, int(0.2 * L)]],
            ([0, int(0.2 * L)], [int(0.6 * L), L]),
        ):
            contig = stdpopsim.Contig.basic_contig(length=L)
            contig.add_dfe(intervals=intervals, DFE=self.example_dfe)
            np.testing.assert_array_equal(intervals, contig.interval_list[1])

    def test_is_neutral(self):
        for neutral in (True, False):
            for dist in ("f", "e"):
                contig = stdpopsim.Contig.basic_contig(length=100)
                contig.clear_dfes()
                props = [0.3, 0.7]
                if neutral:
                    s = 0
                else:
                    s = 0.1
                mt = [
                    stdpopsim.MutationType(distribution_type=dist,
                                           distribution_args=[s])
                    for _ in props
                ]
                dfes = [
                    stdpopsim.DFE(
                        id=str(j),
                        description="test",
                        long_description="test test",
                        proportions=props,
                        mutation_types=mt,
                    ) for j in range(2)
                ]
                contig.add_dfe(
                    intervals=np.array([[10, 30], [50, 100]]),
                    DFE=dfes[0],
                )
                contig.add_dfe(intervals=np.array([[30, 40]]), DFE=dfes[1])
                # exponential with mean zero doesn't count as neutral!
                assert contig.is_neutral is (neutral and dist == "f")