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

Issue:
no `record_provenance` argument to sim_mutations
The following code has per-bp resolution on the RateMap:
```
L = 1e5
ts = msprime.sim_ancestry(1000, sequence_length=L, recombination_rate=1e-8, population_size=1e4)

rm = msprime.RateMap(
    position=np.linspace(0, L, int(L+1)),
    rate=rng.exponential(size=int(L))*1e-8
)
mts = msprime.sim_mutations(ts, rate=rm)
```
and produces the warning:
```
The provenance information for the resulting tree sequence is 3.08MB. This is nothing to worry about as provenance is a good thing to have, but if you want to save this memory/storage space you can disable provenance recording by setting record_provenance=False
```
However, this isn't possible, as [sim_mutations](https://github.com/tskit-dev/msprime/blob/main/msprime/mutations.py#L1555) doesn't have that option. This might be an issue in practice, for someone wanting to do chromosome-scale per-bp resolution (which should only take ~1hr with human-like parameters, so is not crazy!).


Discussion / hints:

Fix patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index bed4dfa45..b620e4e51 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,7 +15,7 @@ jobs:
           # we can invalidate the cache when we need to. Note that we need
           # to update the key in the ``save_cache`` block below also when
           # doing that.
-          key: msprime-{{ .Branch }}-v4
+          key: msprime-{{ .Branch }}-v5
       - run:
           name: Checkout submodules
           command: |
@@ -32,7 +32,7 @@ jobs:
             # way to set path persistently https://circleci.com/docs/2.0/env-vars/#setting-path
             echo 'export PATH=/home/circleci/.local/bin:$PATH' >> $BASH_ENV
       - save_cache:
-          key: msprime-{{ .Branch }}-v4
+          key: msprime-{{ .Branch }}-v5
           paths:
             - "/home/circleci/.local"
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9be5b2704..c30f35da3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Changelog
 
+## [1.3.2] - 2024-07-08
+
+- Add `record_provenance` argument to `sim_mutations` ({issue}`2272`, {pr}`2273`, {user}`peterlharp`)
+
+
 ## [1.3.1] - 2024-02-09
 
 **Bug fixes**:
diff --git a/msprime/mutations.py b/msprime/mutations.py
index 1db11890f..4a20b69c4 100644
--- a/msprime/mutations.py
+++ b/msprime/mutations.py
@@ -1562,6 +1562,7 @@ def sim_mutations(
     end_time=None,
     discrete_genome=None,
     keep=None,
+    record_provenance=True,
 ):
     """
     Simulates mutations on the specified ancestry and returns the resulting
@@ -1631,6 +1632,8 @@ def sim_mutations(
     :param bool discrete_genome: Whether to generate mutations at only integer positions
         along the genome (Default=True).
     :param bool keep: Whether to keep existing mutations. (default: True)
+    :param bool record_provenance: If True, record all input parameters
+        in the tree sequence :ref:`tskit:sec_provenance`.
     :return: The :class:`tskit.TreeSequence` object resulting from overlaying
         mutations on the input tree sequence.
     :rtype: :class:`tskit.TreeSequence`
@@ -1645,20 +1648,20 @@ def sim_mutations(
     else:
         seed = int(seed)
 
-    parameters = dict(
-        command="sim_mutations",
-        tree_sequence=tree_sequence,
-        rate=rate,
-        model=model,
-        start_time=start_time,
-        end_time=end_time,
-        discrete_genome=discrete_genome,
-        keep=keep,
-        random_seed=seed,
-    )
-    encoded_provenance = provenance.json_encode_provenance(
-        provenance.get_provenance_dict(parameters)
-    )
+    provenance_dict = None
+    if record_provenance:
+        parameters = dict(
+            command="sim_mutations",
+            tree_sequence=tree_sequence,
+            rate=rate,
+            model=model,
+            start_time=start_time,
+            end_time=end_time,
+            discrete_genome=discrete_genome,
+            keep=keep,
+            random_seed=seed,
+        )
+        provenance_dict = provenance.get_provenance_dict(parameters)
 
     if rate is None:
         rate = 0
@@ -1698,5 +1701,6 @@ def sim_mutations(
     )
 
     tables = tskit.TableCollection.fromdict(lwt.asdict())
-    tables.provenances.add_row(encoded_provenance)
+    if provenance_dict is not None:
+        tables.provenances.add_row(provenance.json_encode_provenance(provenance_dict))
     return tables.tree_sequence()


Test patch:
diff --git a/tests/test_mutations.py b/tests/test_mutations.py
index cd708624a..30201f041 100644
--- a/tests/test_mutations.py
+++ b/tests/test_mutations.py
@@ -159,6 +159,14 @@ def test_keep(self):
             assert record["parameters"]["command"] == "sim_mutations"
             assert record["parameters"]["keep"] == keep
 
+    def test_record_provenance(self):
+        ts = msprime.sim_ancestry(10, random_seed=1)
+        assert ts.num_provenances == 1
+        mutated = msprime.sim_mutations(ts, rate=1, record_provenance=True)
+        assert mutated.num_provenances == 2
+        mutated = msprime.sim_mutations(ts, rate=1, record_provenance=False)
+        assert mutated.num_provenances == 1
+
 
 class TestMatrixMutationModel:
     def validate_model(self, model):