Skip to content

Commit 8b8d48e

Browse files
committed
extend mutationEffect() callbacks with multi-trait frills
1 parent b8f35d9 commit 8b8d48e

20 files changed

+366
-197
lines changed

QtSLiM/QtSLiMScriptTextEdit.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ void QtSLiMTextEdit::updateStatusFieldFromSelection(void)
979979
else if (callName == "mutationEffect")
980980
{
981981
static EidosCallSignature_CSP callbackSig = nullptr;
982-
if (!callbackSig) callbackSig = EidosCallSignature_CSP((new EidosFunctionSignature("mutationEffect", nullptr, kEidosValueMaskFloat | kEidosValueMaskSingleton))->AddObject_S("mutationType", gSLiM_MutationType_Class)->AddObject_OS("subpop", gSLiM_Subpopulation_Class, gStaticEidosValueNULLInvisible));
982+
if (!callbackSig) callbackSig = EidosCallSignature_CSP((new EidosFunctionSignature("mutationEffect", nullptr, kEidosValueMaskNULL | kEidosValueMaskFloat | kEidosValueMaskSingleton))->AddObject_S("mutationType", gSLiM_MutationType_Class)->AddObject_OS("subpop", gSLiM_Subpopulation_Class, gStaticEidosValueNULLInvisible)->AddString_OS("trait", gStaticEidosValueNULLInvisible));
983983
signature = callbackSig;
984984
}
985985
else if (callName == "fitnessEffect")
@@ -2129,6 +2129,7 @@ void QtSLiMTextEdit::slimSpecificCompletion(QString completionScriptString, NSRa
21292129
case SLiMEidosBlockType::SLiMEidosMutationEffectCallback:
21302130
(*typeTable)->SetTypeForSymbol(gID_mut, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Mutation_Class});
21312131
(*typeTable)->SetTypeForSymbol(gID_homozygous, EidosTypeSpecifier{kEidosValueMaskLogical, nullptr});
2132+
(*typeTable)->SetTypeForSymbol(gID_trait, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Trait_Class});
21322133
(*typeTable)->SetTypeForSymbol(gID_effect, EidosTypeSpecifier{kEidosValueMaskFloat, nullptr});
21332134
(*typeTable)->SetTypeForSymbol(gID_individual, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Individual_Class});
21342135
(*typeTable)->SetTypeForSymbol(gID_subpop, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Subpopulation_Class});

QtSLiM/help/SLiMHelpClasses.html

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

SLiMgui/SLiMHelpClasses.rtf

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,15 +2721,15 @@ The optional parameter
27212721

27222722
\f4\fs20 \cf2 Returns the sum of the effects of all mutations that are of the type specified by
27232723
\f3\fs18 mutType
2724-
\f4\fs20 , out of all of the mutations in the haplosome, for the trait(s) specified by
2724+
\f4\fs20 , out of all of the mutations in the haplosome, for the trait specified by
27252725
\f3\fs18 trait
2726-
\f4\fs20 . The traits can be specified as
2726+
\f4\fs20 . The trait can be specified as the
27272727
\f3\fs18 integer
2728-
\f4\fs20 indices or
2728+
\f4\fs20 index or
27292729
\f3\fs18 string
2730-
\f4\fs20 names of traits in the species, or directly as
2730+
\f4\fs20 name of a trait in the species, or directly as a
27312731
\f3\fs18 Trait
2732-
\f4\fs20 objects;
2732+
\f4\fs20 object;
27332733
\f3\fs18 NULL
27342734
\f4\fs20 can be used to represent the one defined trait in a single-trait species.\
27352735
Historically, this method was often useful in models that used a particular mutation type to represent QTLs with additive effects; in that context,
@@ -4526,15 +4526,15 @@ More specifically, this method uses the parental pedigree IDs from the pedigree
45264526

45274527
\f4\fs20 \cf2 Returns the sum of the effects of all mutations that are of the type specified by
45284528
\f3\fs18 mutType
4529-
\f4\fs20 , out of all of the mutations in the haplosomes of the individual, for the trait(s) specified by
4529+
\f4\fs20 , out of all of the mutations in the haplosomes of the individual, for the trait specified by
45304530
\f3\fs18 trait
4531-
\f4\fs20 . The traits can be specified as
4531+
\f4\fs20 . The trait can be specified as the
45324532
\f3\fs18 integer
4533-
\f4\fs20 indices or
4533+
\f4\fs20 index or
45344534
\f3\fs18 string
4535-
\f4\fs20 names of traits in the species, or directly as
4535+
\f4\fs20 name of a trait in the species, or directly as a
45364536
\f3\fs18 Trait
4537-
\f4\fs20 objects;
4537+
\f4\fs20 object;
45384538
\f3\fs18 NULL
45394539
\f4\fs20 can be used to represent the one defined trait in a single-trait species.\
45404540
Historically, this method was often useful in models that used a particular mutation type to represent QTLs with additive effects; in that context,
@@ -7039,8 +7039,7 @@ Also note that dominance coefficients have a quirk: they are stored internally i
70397039
\f4\fs20 and
70407040
\f3\fs18 kind="count"
70417041
\f4\fs20 are allowed, since separate values for each mutation are then not logged.\
7042-
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
7043-
\cf2 The remaining flags control which columns of data should be returned (for
7042+
The remaining flags control which columns of data should be returned (for
70447043
\f3\fs18 kind
70457044
\f4\fs20 options other than
70467045
\f3\fs18 "count"
@@ -11133,7 +11132,7 @@ After this call, the fitness values used for all purposes in SLiM will be the ne
1113311132
\f4\fs20 will be defined as a global variable immediately by this method, and will also be returned by this method.\
1113411133
\pard\pardeftab720\li720\fi-446\ri720\sb180\sa60\partightenfactor0
1113511134

11136-
\f3\fs18 \cf2 \kerning1\expnd0\expndtw0 \'96\'a0(object<SLiMEidosBlock>$)registerMutationEffectCallback(Nis$\'a0id, string$\'a0source, io<MutationType>$\'a0mutType, [Nio<Subpopulation>$\'a0subpop\'a0=\'a0NULL], [Ni$\'a0start\'a0=\'a0NULL], [Ni$\'a0end\'a0=\'a0NULL])\
11135+
\f3\fs18 \cf2 \kerning1\expnd0\expndtw0 \'96\'a0(object<SLiMEidosBlock>$)registerMutationEffectCallback(Nis$\'a0id, string$\'a0source, io<MutationType>$\'a0mutType, [Nio<Subpopulation>$\'a0subpop\'a0=\'a0NULL], [Ni$\'a0start\'a0=\'a0NULL], [Ni$\'a0end\'a0=\'a0NULL], [Niso<Trait>$\'a0trait\'a0=\'a0NULL])\
1113711136
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
1113811137

1113911138
\f4\fs20 \cf2 Register a block of Eidos source code, represented as the
@@ -11152,11 +11151,21 @@ After this call, the fitness values used for all purposes in SLiM will be the ne
1115211151
\f3\fs18 integer
1115311152
\f4\fs20 identifier, or
1115411153
\f3\fs18 NULL
11155-
\f4\fs20 , the default, to indicate all subpopulations), and optional
11154+
\f4\fs20 , the default, to indicate all subpopulations), optional
1115611155
\f3\fs18 start
1115711156
\f4\fs20 and
1115811157
\f3\fs18 end
11159-
\f4\fs20 ticks all limiting its applicability. The script block will be given identifier
11158+
\f4\fs20 ticks, and optional trait identifier
11159+
\f3\fs18 trait
11160+
\f4\fs20 (which may be an
11161+
\f3\fs18 integer
11162+
\f4\fs20 trait index, a
11163+
\f3\fs18 string
11164+
\f4\fs20 trait name, a
11165+
\f3\fs18 Trait
11166+
\f4\fs20 object, or
11167+
\f3\fs18 NULL
11168+
\f4\fs20 if the species has only one defined trait anyway), all limiting its applicability. The script block will be given identifier
1116011169
\f3\fs18 id
1116111170
\f4\fs20 (specified as an
1116211171
\f3\fs18 integer

SLiMgui/SLiMWindowController.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3828,6 +3828,7 @@ - (BOOL)eidosTextView:(EidosTextView *)eidosTextView completionContextWithScript
38283828
case SLiMEidosBlockType::SLiMEidosMutationEffectCallback:
38293829
(*typeTable)->SetTypeForSymbol(gID_mut, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Mutation_Class});
38303830
(*typeTable)->SetTypeForSymbol(gID_homozygous, EidosTypeSpecifier{kEidosValueMaskLogical, nullptr});
3831+
(*typeTable)->SetTypeForSymbol(gID_trait, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Trait_Class});
38313832
(*typeTable)->SetTypeForSymbol(gID_effect, EidosTypeSpecifier{kEidosValueMaskFloat, nullptr});
38323833
(*typeTable)->SetTypeForSymbol(gID_individual, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Individual_Class});
38333834
(*typeTable)->SetTypeForSymbol(gID_subpop, EidosTypeSpecifier{kEidosValueMaskObject, gSLiM_Subpopulation_Class});
@@ -4139,7 +4140,7 @@ - (void)updateStatusFieldFromSelection
41394140
static EidosCallSignature_CSP callbackSig = nullptr;
41404141

41414142
if (!callbackSig)
4142-
callbackSig = EidosCallSignature_CSP((new EidosFunctionSignature("mutationEffect", nullptr, kEidosValueMaskFloat | kEidosValueMaskSingleton))->AddObject_S("mutationType", gSLiM_MutationType_Class)->AddObject_OS("subpop", gSLiM_Subpopulation_Class, gStaticEidosValueNULLInvisible));
4143+
callbackSig = EidosCallSignature_CSP((new EidosFunctionSignature("mutationEffect", nullptr, kEidosValueMaskNULL | kEidosValueMaskFloat | kEidosValueMaskSingleton))->AddObject_S("mutationType", gSLiM_MutationType_Class)->AddObject_OS("subpop", gSLiM_Subpopulation_Class, gStaticEidosValueNULLInvisible)->AddString_OS("trait", gStaticEidosValueNULLInvisible));
41434144

41444145
sig = callbackSig.get();
41454146
}

VERSIONS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ multitrait branch:
140140
- (void)logMutationData(logical$ enable, [logical$ autogeneratedOnly = T], [logical$ meanOnly = F], <flags>)
141141
- (ifo<DataFrame>)loggedData(string$ kind, <flags>)
142142
policy change: mean(integer(0)) or mean(float(0)) now returns NAN rather than NULL, to match R; I just noticed this, and NAN does seem better
143+
add optional [Ns$ trait = NULL] specifier to the mutationEffect() callback syntax, allowing mutationEffect() callbacks to be defined as specific to a particular trait
144+
note that if this new specifier is absent or NULL, the callback will be called separately for each trait; that preserves backward compatibility
145+
add trait pseudo-parameter to mutationEffect() callbacks
146+
add [Niso<Trait>$ trait = NULL] parameter to registerMutationEffectCallback() to allow the trait specifier to be given (defaults to NULL for backward compatibility)
147+
add a new return option for mutationEffect() callbacks: NULL now indicates neutrality for the focal trait, meaning either 1.0 (multiplicative) or 0.0 (additive)
143148

144149

145150
version 5.1 (Eidos version 4.1):

core/haplosome.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,14 +1318,8 @@ EidosValue_SP Haplosome::ExecuteMethod_sumOfMutationsOfType(EidosGlobalStringID
13181318
Species &species = individual_->subpopulation_->species_;
13191319
MutationType *mutation_type_ptr = SLiM_ExtractMutationTypeFromEidosValue_io(mutType_value, 0, &species.community_, &species, "sumOfMutationsOfType()"); // SPECIES CONSISTENCY CHECK
13201320

1321-
// get the trait indices, with bounds-checking
1322-
std::vector<slim_trait_index_t> trait_indices;
1323-
species.GetTraitIndicesFromEidosValue(trait_indices, trait_value, "sumOfMutationsOfType");
1324-
1325-
if (trait_indices.size() != 1)
1326-
EIDOS_TERMINATION << "ERROR (Haplosome::ExecuteMethod_sumOfMutationsOfType): sumOfMutationsOfType() requires exactly one trait to be specified." << EidosTerminate();
1327-
1328-
const slim_trait_index_t trait_index = trait_indices[0];
1321+
// get the trait index, with bounds-checking
1322+
const slim_trait_index_t trait_index = species.GetTraitIndexFromEidosValue(trait_value, "sumOfMutationsOfType");
13291323

13301324
// Sum the selection coefficients of mutations of the given type
13311325
MutationBlock *mutation_block = species.SpeciesMutationBlock();
@@ -2291,7 +2285,7 @@ const std::vector<EidosMethodSignature_CSP> *Haplosome_Class::Methods(void) cons
22912285
methods->emplace_back((EidosClassMethodSignature *)(new EidosClassMethodSignature(gStr_outputHaplosomesToMS, kEidosValueMaskVOID))->AddString_OSN(gEidosStr_filePath, gStaticEidosValueNULL)->AddLogical_OS("append", gStaticEidosValue_LogicalF)->AddLogical_OS("filterMonomorphic", gStaticEidosValue_LogicalF));
22922286
methods->emplace_back((EidosClassMethodSignature *)(new EidosClassMethodSignature(gStr_outputHaplosomesToVCF, kEidosValueMaskVOID))->AddString_OSN(gEidosStr_filePath, gStaticEidosValueNULL)->AddLogical_OS("outputMultiallelics", gStaticEidosValue_LogicalT)->AddLogical_OS("append", gStaticEidosValue_LogicalF)->AddLogical_OS("simplifyNucleotides", gStaticEidosValue_LogicalF)->AddLogical_OS("outputNonnucleotides", gStaticEidosValue_LogicalT)->AddLogical_OS("groupAsIndividuals", gStaticEidosValue_LogicalT));
22932287
methods->emplace_back((EidosClassMethodSignature *)(new EidosClassMethodSignature(gStr_outputHaplosomes, kEidosValueMaskVOID))->AddString_OSN(gEidosStr_filePath, gStaticEidosValueNULL)->AddLogical_OS("append", gStaticEidosValue_LogicalF)->AddLogical_OS("objectTags", gStaticEidosValue_LogicalF));
2294-
methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_sumOfMutationsOfType, kEidosValueMaskFloat | kEidosValueMaskSingleton))->AddIntObject_S("mutType", gSLiM_MutationType_Class)->AddIntStringObject_OSN("trait", gSLiM_Trait_Class, gStaticEidosValueNULL));
2288+
methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_sumOfMutationsOfType, kEidosValueMaskFloat | kEidosValueMaskSingleton))->AddIntObject_S("mutType", gSLiM_MutationType_Class)->AddIntStringObject_OSN(gStr_trait, gSLiM_Trait_Class, gStaticEidosValueNULL));
22952289

22962290
std::sort(methods->begin(), methods->end(), CompareEidosCallSignatures);
22972291
}

0 commit comments

Comments
 (0)