Repository: tskit-dev/msprime (language: python)

Issue:
recording migrants with sweep model
I was trying to record `msprime.NodeType.MIGRANT` in the `SweepGenicModel`. In theory, this should allow us to record lineages that recombine away from the selected background (= changing labels in the structured coalescent).

```python
Ne = 10_000
model = msprime.SweepGenicSelection(position=10, start_frequency=0.1, end_frequency=0.9, s=0.01, dt=1/(40 * Ne))
msprime.sim_ancestry(
    samples=4,
    model=model, 
    recombination_rate=1e-8, 
    sequence_length=1000, 
    coalescing_segments_only=False, 
    additional_nodes=msprime.NodeType.MIGRANT,
    population_size=Ne
)
```
This returns the following error:
`msprime._msprime.LibraryError: The simulation model supplied resulted in a parent node having a time value <= to its child. This can occur as a result of multiple bottlenecks happening at the same time, multiple census events at the same time or numerical imprecision with very smallpopulation sizes.`

This is due to how the sweep is set up: [`msp_sweep_initialise`](https://github.com/tskit-dev/msprime/blob/054c032880676b359edecd4e4a84f42c1f961dd3/lib/msprime.c#L4906). The move individuals function is applied here to the sampled lineages. We shouldn't be registering an additional node here. The same error will happen when the sweep is finalised I think.


Discussion / hints:
In the long run, recording events this way may cause some issues.  Arguably, one goal is for msprime to replace, e.g., discoal, in terms of functionality.  If that happens, then the notion of a "migration" will get overloaded: between fitness classes and between "real" demes.
Yes, agreed. We need a new `msprime.NodeType`, or a way of recording fitness classes in a flexible way. In the mean time I will make sure we throw an error when trying to record MIGRANTS for the `SweepGenicModel`.

Fix patch:
diff --git a/msprime/ancestry.py b/msprime/ancestry.py
index b44dd2995..e62b66a4f 100644
--- a/msprime/ancestry.py
+++ b/msprime/ancestry.py
@@ -866,18 +866,22 @@ def _parse_sim_ancestry(
                     " additional_nodes."
                 )
 
-        if is_dtwf:
-            if additional_nodes.value & NodeType.MIGRANT.value:
+        if additional_nodes.value & NodeType.MIGRANT.value:
+            if is_dtwf:
                 raise ValueError(
                     "Recording MIGRANT nodes is currently not supported in"
                     " DTWF simulation."
                 )
-        if is_pedigree:
-            if additional_nodes.value & NodeType.MIGRANT.value:
+            if is_pedigree:
                 raise ValueError(
                     "Recording MIGRANT nodes is not supported in "
                     "FixedPedigree simulation."
                 )
+            if any(isinstance(model, SweepGenicSelection) for model in models):
+                raise ValueError(
+                    "Recording MIGRANT nodes is not supported in "
+                    "SweepGenicSelection simulation."
+                )
 
     record_migrations = core._parse_flag(record_migrations, default=False)
 


Test patch:
diff --git a/tests/test_models.py b/tests/test_models.py
index cf5b0933c..56bf673b1 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -962,3 +962,30 @@ def test_lots_of_sweeps(self):
             random_seed=2,
         )
         assert all(tree.num_roots == 1 for tree in ts.trees())
+
+    def test_sweep_migration_event(self):
+        models = [
+            msprime.StandardCoalescent(duration=0.01),
+            msprime.SweepGenicSelection(
+                position=5,
+                start_frequency=0.69,
+                end_frequency=0.7,
+                s=0.1,
+                dt=1e-6,
+            ),
+        ]
+        with pytest.raises(
+            ValueError,
+            match="Recording MIGRANT nodes is not supported in "
+            "SweepGenicSelection simulation.",
+        ):
+            msprime.sim_ancestry(
+                3,
+                population_size=1000,
+                sequence_length=10,
+                recombination_rate=0.2,
+                model=models,
+                random_seed=2,
+                coalescing_segments_only=False,
+                additional_nodes=msprime.NodeType.MIGRANT,
+            )