Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

In development.

**Maintenance**:

- The ``SLiMMutationModel`` is renamed ``SLiMv5MutationModel``. The class
``SLiMMutationModel`` retains its previous behavior, but emits a FutureWarning.
This change is made because mutations made by the older SLiM mutation model
can be read as SLiM v6 mutations (but with meaningless values), producing a confusing
situation for downstream users. New code should use either ``SLiMv5MutationModel``
or ``SLiMv6MutationModel``, as appropriate. ({pr}`2546`, {user}`petrelharp`)

## [1.4.4] - 2026-09-01

Bugfix release.
Expand Down
6 changes: 3 additions & 3 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ for discussion and examples of individual features.
TPM
EL2
InfiniteAlleles
SLiMv5MutationModel
SLiMv6MutationModel
SLiMMutationModel
```

### Demography
Expand Down Expand Up @@ -219,11 +219,11 @@ for discussion and examples of individual features.
```

```{eval-rst}
.. autoclass:: msprime.SLiMv6MutationModel()
.. autoclass:: msprime.SLiMv5MutationModel()
```

```{eval-rst}
.. autoclass:: msprime.SLiMMutationModel()
.. autoclass:: msprime.SLiMv6MutationModel()
```

(sec_api_node_flags)=
Expand Down
16 changes: 9 additions & 7 deletions docs/mutations.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ for more information.
{class}`.InfiniteAlleles` (Integers)
: A generic infinite-alleles mutation model

{class}`.SLiMv5MutationModel` (Integers)
: An infinite-alleles model producing SLiM-style mutations for SLiM versions before 6.0

{class}`.SLiMv6MutationModel` (Integers)
: An infinite-alleles model producing SLiM-style mutations for SLiM v6+

{class}`.SLiMMutationModel` (Integers)
: An infinite-alleles model producing SLiM-style mutations for older versions of SLiM

{class}`.MatrixMutationModel` (General finite state model)
: Superclass of mutation models with a finite set of states

Expand Down Expand Up @@ -488,8 +488,8 @@ Here are the available models; they are documented in more detail below.
- {class}`.TPM`: Two-phase mutation model for microsatellite repeat copy number. DiRienzo et al. ('94)
- {class}`.EL2`: Two-phase mutation model, equal rate, linear bias model for microsatellite repeat copy number. Garza et al. ('95)
- {class}`.InfiniteAlleles`: A generic infinite-alleles mutation model
- {class}`.SLiMv5MutationModel`: An infinite-alleles model of mutation producing SLiM-style mutations for older versions of SLiM
- {class}`.SLiMv6MutationModel`: An infinite-alleles model of mutation producing SLiM-style mutations for SLiM v6+
- {class}`.SLiMMutationModel`: An infinite-alleles model of mutation producing SLiM-style mutations for older versions of SLiM

(sec_mutations_matrix_mutations_models)=

Expand Down Expand Up @@ -878,7 +878,7 @@ ancestral and derived states are modified (for instance, to be VCF-compliant)
then there is no loss of information.

There are in fact two mutation models for SLiM:
{class}`.SLiMv6MutationModel` and {class}`.SLiMMutationModel`,
{class}`.SLiMv5MutationModel` and {class}`.SLiMv6MutationModel`,
because the format that SLiM uses to store mutations changed with version 6.0.
Both store the same thing in derived state; the difference is in metadata.
So, you probably want to use {class}`.SLiMv6MutationModel`;
Expand Down Expand Up @@ -1035,14 +1035,16 @@ don't have the right tool for the job.
#### Previous versions

The technical difference between
{class}`.SLiMv6MutationModel` and {class}`.SLiMMutationModel` is as follows.
{class}`.SLiMv6MutationModel` and {class}`.SLiMv5MutationModel` is as follows.
{class}`.SLiMv6MutationModel` stores the SLiM IDs in binary metadata
as well as in the derived state,
so that the actual metadata about mutations can be looked up from where
SLiM expects it in top-level metadata.
The older version, {class}`.SLiMMutationModel`,
The older version, {class}`.SLiMv5MutationModel`,
stores the metadata about SLiM mutations directly in each tskit mutation's metadata
(and since individual SLiM mutations can appear in more than one tskit mutation,
this leads to some redundancy; thus the change
to how mutation metadata is handled in SLiMv6). For more information, see
{ref}`the pyslim documentation<pyslim:sec_previous_versions>`.
Formerly, {class}`.SLiMv5MutationModel` was named `SLiMMutationModel`;
the older name still works for backwards compatibility, but produces a warning.
2 changes: 1 addition & 1 deletion lib/msprime.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ int matrix_mutation_model_factory(mutation_model_t *self, int model);
int matrix_mutation_model_alloc(mutation_model_t *self, size_t num_alleles,
char **alleles, size_t *allele_length, double *root_distribution,
double *transition_matrix);
int slim_mutation_model_alloc(mutation_model_t *self, int32_t mutation_type_id,
int slim_v5_mutation_model_alloc(mutation_model_t *self, int32_t mutation_type_id,
int64_t next_mutation_id, int32_t slim_generation, size_t block_size);
int slim_v6_mutation_model_alloc(
mutation_model_t *self, int64_t next_mutation_id, size_t block_size);
Expand Down
21 changes: 11 additions & 10 deletions lib/mutgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ slim_both_mutator_free(mutation_model_t *self)
}

/*******************************
* (Older) SLiM mutation model */
* (Older) SLiMv5 mutation model */

/* Typedefs from MutationMetadataRec in slim_sim.h:
* line 125 in v3.4, git hash b2c2b634199f35e53c4e7e513bd26c91c6d99fd9
Expand Down Expand Up @@ -373,7 +373,7 @@ slim_both_mutator_free(mutation_model_t *self)
#define SLIM_MUTATION_METADATA_SIZE 17 // = 4 + 4 + 4 + 4 + 1

static void
copy_slim_mutation_metadata(slim_mutator_t *params, char *dest, double time)
copy_slim_v5_mutation_metadata(slim_mutator_t *params, char *dest, double time)
{
int32_t mutation_type_id = params->mutation_type_id;
float selection_coeff = 0;
Expand All @@ -394,7 +394,7 @@ copy_slim_mutation_metadata(slim_mutator_t *params, char *dest, double time)
}

static void
slim_mutator_print_state(mutation_model_t *self, FILE *out)
slim_v5_mutator_print_state(mutation_model_t *self, FILE *out)
{
slim_mutator_t params = self->params.slim_mutator;
fprintf(out, "SLiM mutation model :: mutation type ID = %d\n",
Expand All @@ -406,7 +406,7 @@ slim_mutator_print_state(mutation_model_t *self, FILE *out)
}

static int MSP_WARN_UNUSED
slim_mutator_check_validity(slim_mutator_t *self)
slim_v5_mutator_check_validity(slim_mutator_t *self)
{
int ret = 0;

Expand All @@ -425,7 +425,7 @@ slim_mutator_check_validity(slim_mutator_t *self)
}

static int
slim_mutator_transition(mutation_model_t *self, gsl_rng *MSP_UNUSED(rng),
slim_v5_mutator_transition(mutation_model_t *self, gsl_rng *MSP_UNUSED(rng),
const char *parent_allele, tsk_size_t parent_allele_length,
const char *parent_metadata, tsk_size_t parent_metadata_length, mutation_t *mutation)
{
Expand All @@ -441,7 +441,8 @@ slim_mutator_transition(mutation_model_t *self, gsl_rng *MSP_UNUSED(rng),
}

// copy the final bit of metadata in (this is different than the v6 model)
copy_slim_mutation_metadata(params, buff + parent_metadata_length, mutation->time);
copy_slim_v5_mutation_metadata(
params, buff + parent_metadata_length, mutation->time);
mutation->metadata = buff;

// finally, set up for the next one
Expand Down Expand Up @@ -655,7 +656,7 @@ matrix_mutation_model_alloc(mutation_model_t *self, size_t num_alleles, char **a
}

int MSP_WARN_UNUSED
slim_mutation_model_alloc(mutation_model_t *self, int32_t mutation_type_id,
slim_v5_mutation_model_alloc(mutation_model_t *self, int32_t mutation_type_id,
int64_t next_mutation_id, int32_t slim_generation, size_t block_size)
{
int ret = 0;
Expand All @@ -664,8 +665,8 @@ slim_mutation_model_alloc(mutation_model_t *self, int32_t mutation_type_id,
memset(self, 0, sizeof(*self));

self->choose_root_state = &slim_both_mutator_choose_root_state;
self->transition = &slim_mutator_transition;
self->print_state = &slim_mutator_print_state;
self->transition = &slim_v5_mutator_transition;
self->print_state = &slim_v5_mutator_print_state;
self->free = &slim_both_mutator_free;
if (block_size == 0) {
/* 8K is a good default, but we need to have the
Expand All @@ -685,7 +686,7 @@ slim_mutation_model_alloc(mutation_model_t *self, int32_t mutation_type_id,
params->next_mutation_id = next_mutation_id;
params->slim_generation = slim_generation;

ret = slim_mutator_check_validity(params);
ret = slim_v5_mutator_check_validity(params);
if (ret != 0) {
goto out;
}
Expand Down
31 changes: 16 additions & 15 deletions lib/tests/test_mutations.c
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ verify_slim_metadata(char *metadata, size_t metadata_length, int32_t slim_time)
}

static void
test_mutgen_slim_mutations(void)
test_mutgen_slim_v5_mutations(void)
{
int ret = 0;
int j, k;
Expand All @@ -930,7 +930,7 @@ test_mutgen_slim_mutations(void)
int32_t slim_generation = 17;

CU_ASSERT_FATAL(rng != NULL);
ret = slim_mutation_model_alloc(
ret = slim_v5_mutation_model_alloc(
&mut_model, mutation_type_id, next_mutation_id, slim_generation, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);

Expand Down Expand Up @@ -1011,7 +1011,7 @@ test_mutgen_slim_mutations(void)
}

static void
test_mutgen_slim_mutation_large_values(void)
test_mutgen_slim_v5_mutation_large_values(void)
{
int ret = 0;
mutgen_t mutgen;
Expand All @@ -1028,7 +1028,7 @@ test_mutgen_slim_mutation_large_values(void)
insert_single_tree(&tables, -1);

/* Trying to generate mutations that overflow raises an error */
ret = slim_mutation_model_alloc(&mut_model, 0, INT64_MAX, 1, 0);
ret = slim_v5_mutation_model_alloc(&mut_model, 0, INT64_MAX, 1, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
ret = mutgen_alloc(&mutgen, rng, &tables, &mut_model, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
Expand All @@ -1043,7 +1043,7 @@ test_mutgen_slim_mutation_large_values(void)
tsk_site_table_clear(&tables.sites);
/* Try out with a large value that doesn't hit the ceiling */
next_mutation_id = INT64_MAX - 100;
ret = slim_mutation_model_alloc(&mut_model, 0, next_mutation_id, 1, 0);
ret = slim_v5_mutation_model_alloc(&mut_model, 0, next_mutation_id, 1, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
ret = mutgen_alloc(&mutgen, rng, &tables, &mut_model, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
Expand Down Expand Up @@ -1533,7 +1533,7 @@ test_matrix_mutation_model_properties(void)
}

static void
test_slim_mutation_model_errors(void)
test_slim_v5_mutation_model_errors(void)
{
int ret;
mutation_model_t model;
Expand All @@ -1542,29 +1542,29 @@ test_slim_mutation_model_errors(void)
int32_t slim_generation = 1;

next_mutation_id--;
ret = slim_mutation_model_alloc(
ret = slim_v5_mutation_model_alloc(
&model, mutation_type_id, next_mutation_id, slim_generation, 0);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_SLIM_PARAMETERS);
mutation_model_free(&model);

mutation_type_id--;
next_mutation_id++;
ret = slim_mutation_model_alloc(
ret = slim_v5_mutation_model_alloc(
&model, mutation_type_id, next_mutation_id, slim_generation, 0);
CU_ASSERT_EQUAL_FATAL(ret, MSP_ERR_BAD_SLIM_PARAMETERS);
mutation_model_free(&model);
}

static void
test_slim_mutation_model_properties(void)
test_slim_v5_mutation_model_properties(void)
{
int ret;
mutation_model_t model;
int32_t mutation_type_id = 1;
int64_t next_mutation_id = 2;
int32_t slim_generation = 3;

ret = slim_mutation_model_alloc(
ret = slim_v5_mutation_model_alloc(
&model, mutation_type_id, next_mutation_id, slim_generation, 0);
CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_EQUAL_FATAL(model.params.slim_mutator.slim_generation, 3);
Expand Down Expand Up @@ -1623,9 +1623,9 @@ main(int argc, char **argv)
test_single_tree_mutgen_many_mutations },
{ "test_jukes_cantor_has_silent_mutations",
test_jukes_cantor_has_silent_mutations },
{ "test_mutgen_slim_mutations", test_mutgen_slim_mutations },
{ "test_mutgen_slim_mutation_large_values",
test_mutgen_slim_mutation_large_values },
{ "test_mutgen_slim_v5_mutations", test_mutgen_slim_v5_mutations },
{ "test_mutgen_slim_v5_mutation_large_values",
test_mutgen_slim_v5_mutation_large_values },
{ "test_mutgen_slim_v6_mutations", test_mutgen_slim_v6_mutations },
{ "test_mutgen_slim_v6_mutations_keeps", test_mutgen_slim_v6_mutations_keeps },
{ "test_mutgen_slim_v6_mutation_large_values",
Expand All @@ -1636,8 +1636,9 @@ main(int argc, char **argv)
{ "test_matrix_mutation_model_errors", test_matrix_mutation_model_errors },
{ "test_matrix_mutation_model_properties",
test_matrix_mutation_model_properties },
{ "test_slim_mutation_model_errors", test_slim_mutation_model_errors },
{ "test_slim_mutation_model_properties", test_slim_mutation_model_properties },
{ "test_slim_v5_mutation_model_errors", test_slim_v5_mutation_model_errors },
{ "test_slim_v5_mutation_model_properties",
test_slim_v5_mutation_model_properties },
{ "test_slim_v6_mutation_model_errors", test_slim_v6_mutation_model_errors },
{ "test_slim_v6_mutation_model_properties",
test_slim_v6_mutation_model_properties },
Expand Down
2 changes: 2 additions & 0 deletions msprime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
NUCLEOTIDES,
PAM,
SLiMMutationModel,
SLiMv5MutationModel,
SLiMv6MutationModel,
sim_mutations,
)
Expand Down Expand Up @@ -152,6 +153,7 @@
"RateMap",
"RecombinationMap",
"SLiMMutationModel",
"SLiMv5MutationModel",
"SLiMv6MutationModel",
"Sample",
"SampleSet",
Expand Down
Loading
Loading