Skip to content

Commit

Permalink
add estimatedLastTick() method to Community
Browse files Browse the repository at this point in the history
  • Loading branch information
bhaller committed Mar 20, 2024
1 parent dfc1b57 commit d908c65
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions QtSLiM/help/SLiMHelpClasses.html
Expand Up @@ -186,6 +186,8 @@
<p class="p6">LogTable supports periodic automatic logging of a new row of data, enabled by supplying a non-<span class="s1">NULL</span> value for <span class="s1">logInterval</span>.<span class="Apple-converted-space">  </span>In this case, a new row will be logged (as if <span class="s1">logRow()</span> were called on the <span class="s1">LogFile</span>) at the end of every <span class="s1">logInterval</span> ticks (just before the tick counter increments, in both WF and nonWF models), starting at the end of the tick in which the <span class="s1">LogFile</span> was created.<span class="Apple-converted-space">  </span>A <span class="s1">logInterval</span> of <span class="s1">1</span> will cause automatic logging at the end of every tick, whereas a <span class="s1">logInterval</span> of <span class="s1">NULL</span> disables automatic logging.<span class="Apple-converted-space">  </span>Automatic logging can always be disabled or reconfigured later with the <span class="s1">LogFile</span> method <span class="s1">setLogInterval()</span>, or logging can be triggered manually by calling <span class="s1">logRow()</span>.</p>
<p class="p6">When compression is enabled, <span class="s1">LogFile</span> flushes new data lazily by default, for performance reasons, buffering data for multiple rows before writing to disk.<span class="Apple-converted-space">  </span>Passing a non-<span class="s1">NULL</span> value for <span class="s1">flushInterval</span> requests a flush every <span class="s1">flushInterval</span> rows (with a value of <span class="s1">1</span> providing unbuffered operation).<span class="Apple-converted-space">  </span>Note that flushing very frequently will likely result in both lower performance and a larger final file size (in one simple test, <span class="s1">48943</span> bytes instead of <span class="s1">4280</span> bytes, or more than a 10× increase in size).<span class="Apple-converted-space">  </span>Alternatively, passing a very large value for <span class="s1">flushInterval</span> will effectively disable automatic flushing, except at the end of the simulation (but be aware that this may use a large amount of memory for large log files).<span class="Apple-converted-space">  </span>In any case, the log file will be created immediately, with its requested initial contents; the initial write is not buffered.<span class="Apple-converted-space">  </span>When compression is not enabled, the <span class="s1">flushInterval</span> setting is ignored.</p>
<p class="p6">The <span class="s1">LogFile</span> documentation discusses how to configure and use <span class="s1">LogFile</span> to write out the data you are interested in from your simulation.</p>
<p class="p5">– (integer$)estimatedLastTick(void)</p>
<p class="p6">Returns SLiM’s current estimate of the last tick in which the model will execute.<span class="Apple-converted-space">  </span>Because script blocks can be added, removed, and rescheduled, and because the simulation may end prematurely (due to a call to <span class="s1">simulationFinished()</span>, for example), this is only an estimate, and may change over time.</p>
<p class="p3">– (void)deregisterScriptBlock(io&lt;SLiMEidosBlock&gt; scriptBlocks)</p>
<p class="p4">All <span class="s1">SLiMEidosBlock</span> objects specified by <span class="s1">scriptBlocks</span> (either with <span class="s1">SLiMEidosBlock</span> objects or with <span class="s1">integer</span> identifiers) will be scheduled for deregistration.<span class="Apple-converted-space">  </span>The deregistered blocks remain valid, and may even still be executed in the current stage of the current tick; the blocks are not actually deregistered and deallocated until sometime after the currently executing script block has completed.<span class="Apple-converted-space">  </span>To immediately prevent a script block from executing, even when it is scheduled to execute in the current stage of the current tick, use the <span class="s1">active</span> property of the script block.</p>
<p class="p5">– (object&lt;GenomicElementType&gt;)genomicElementTypesWithIDs(integer ids)</p>
Expand Down
8 changes: 8 additions & 0 deletions SLiMgui/SLiMHelpClasses.rtf
Expand Up @@ -994,6 +994,14 @@ The
\f4\fs20 to write out the data you are interested in from your simulation.\
\pard\pardeftab720\li720\fi-446\ri720\sb180\sa60\partightenfactor0
\f3\fs18 \cf2 \'96\'a0(integer$)estimatedLastTick(void)\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
\f4\fs20 \cf2 Returns SLiM\'92s current estimate of the last tick in which the model will execute. Because script blocks can be added, removed, and rescheduled, and because the simulation may end prematurely (due to a call to
\f3\fs18 simulationFinished()
\f4\fs20 , for example), this is only an estimate, and may change over time.\
\pard\pardeftab720\li720\fi-446\ri720\sb180\sa60\partightenfactor0
\f3\fs18 \cf0 \'96\'a0(void)deregisterScriptBlock(io<SLiMEidosBlock>\'a0scriptBlocks)\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
Expand Down
1 change: 1 addition & 0 deletions VERSIONS
Expand Up @@ -40,6 +40,7 @@ development head (in the master branch):
require the symbol name passed to defineConstant() / defineGlobal() to be a valid Eidos identifier
fix a bug that would cause failures to write buffered compressed data from writeFile(), only in SLiMgui; these failures were not reported to the user well (only through SLiMgui's stderr)
recipe 14.7 is a ground-up rewrite, to show the utility of using marker mutations to track true local ancestry, including live plotting in SLiMgui
add estimatedLastTick() method to Community; useful for custom plotting where you want to know the span of the model up front, to set an axis range, for example


version 4.1 (Eidos version 3.1):
Expand Down
1 change: 1 addition & 0 deletions core/community.h
Expand Up @@ -358,6 +358,7 @@ class Community : public EidosDictionaryUnretained
virtual EidosValue_SP ExecuteInstanceMethod(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter) override;

EidosValue_SP ExecuteMethod_createLogFile(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter);
EidosValue_SP ExecuteMethod_estimatedLastTick(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter);
EidosValue_SP ExecuteMethod_deregisterScriptBlock(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter);
EidosValue_SP ExecuteMethod_genomicElementTypesWithIDs(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter);
EidosValue_SP ExecuteMethod_interactionTypesWithIDs(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter);
Expand Down
15 changes: 15 additions & 0 deletions core/community_eidos.cpp
Expand Up @@ -547,6 +547,7 @@ EidosValue_SP Community::ExecuteInstanceMethod(EidosGlobalStringID p_method_id,
switch (p_method_id)
{
case gID_createLogFile: return ExecuteMethod_createLogFile(p_method_id, p_arguments, p_interpreter);
case gID_estimatedLastTick: return ExecuteMethod_estimatedLastTick(p_method_id, p_arguments, p_interpreter);
case gID_deregisterScriptBlock: return ExecuteMethod_deregisterScriptBlock(p_method_id, p_arguments, p_interpreter);
case gID_genomicElementTypesWithIDs: return ExecuteMethod_genomicElementTypesWithIDs(p_method_id, p_arguments, p_interpreter);
case gID_interactionTypesWithIDs: return ExecuteMethod_interactionTypesWithIDs(p_method_id, p_arguments, p_interpreter);
Expand Down Expand Up @@ -651,6 +652,19 @@ EidosValue_SP Community::ExecuteMethod_createLogFile(EidosGlobalStringID p_metho
return result_SP;
}

// ********************* - (integer$)estimatedLastTick(void)
//
EidosValue_SP Community::ExecuteMethod_estimatedLastTick(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter)
{
#pragma unused (p_method_id, p_arguments, p_interpreter)
if (!tick_ranges_available_)
EIDOS_TERMINATION << "ERROR (Community::ExecuteMethod_estimatedLastTick): estimatedLastTick() cannot be called until script block tick ranges have been evaluated, after initialize() callbacks have finished executing." << EidosTerminate();

slim_tick_t last_tick = EstimatedLastTick();

return EidosValue_SP(new (gEidosValuePool->AllocateChunk()) EidosValue_Int(last_tick));
}

// ********************* - (void)deregisterScriptBlock(io<SLiMEidosBlock> scriptBlocks)
//
EidosValue_SP Community::ExecuteMethod_deregisterScriptBlock(EidosGlobalStringID p_method_id, const std::vector<EidosValue_SP> &p_arguments, EidosInterpreter &p_interpreter)
Expand Down Expand Up @@ -1366,6 +1380,7 @@ const std::vector<EidosMethodSignature_CSP> *Community_Class::Methods(void) cons
methods = new std::vector<EidosMethodSignature_CSP>(*super::Methods());

methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_createLogFile, kEidosValueMaskObject | kEidosValueMaskSingleton, gSLiM_LogFile_Class))->AddString_S(gEidosStr_filePath)->AddString_ON("initialContents", gStaticEidosValueNULL)->AddLogical_OS("append", gStaticEidosValue_LogicalF)->AddLogical_OS("compress", gStaticEidosValue_LogicalF)->AddString_OS("sep", gStaticEidosValue_StringComma)->AddInt_OSN("logInterval", gStaticEidosValueNULL)->AddInt_OSN("flushInterval", gStaticEidosValueNULL));
methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_estimatedLastTick, kEidosValueMaskInt | kEidosValueMaskSingleton)));
methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_deregisterScriptBlock, kEidosValueMaskVOID))->AddIntObject("scriptBlocks", gSLiM_SLiMEidosBlock_Class));
methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_genomicElementTypesWithIDs, kEidosValueMaskObject, gSLiM_GenomicElementType_Class))->AddInt("ids"));
methods->emplace_back((EidosInstanceMethodSignature *)(new EidosInstanceMethodSignature(gStr_interactionTypesWithIDs, kEidosValueMaskObject, gSLiM_InteractionType_Class))->AddInt("ids"));
Expand Down
1 change: 1 addition & 0 deletions core/slim_globals.cpp
Expand Up @@ -1302,6 +1302,7 @@ const std::string &gStr_drawSelectionCoefficient = EidosRegisteredString("drawSe
const std::string &gStr_setDistribution = EidosRegisteredString("setDistribution", gID_setDistribution);
const std::string &gStr_addSubpop = EidosRegisteredString("addSubpop", gID_addSubpop);
const std::string &gStr_addSubpopSplit = EidosRegisteredString("addSubpopSplit", gID_addSubpopSplit);
const std::string &gStr_estimatedLastTick = EidosRegisteredString("estimatedLastTick", gID_estimatedLastTick);
const std::string &gStr_deregisterScriptBlock = EidosRegisteredString("deregisterScriptBlock", gID_deregisterScriptBlock);
const std::string &gStr_genomicElementTypesWithIDs = EidosRegisteredString("genomicElementTypesWithIDs", gID_genomicElementTypesWithIDs);
const std::string &gStr_interactionTypesWithIDs = EidosRegisteredString("interactionTypesWithIDs", gID_interactionTypesWithIDs);
Expand Down
2 changes: 2 additions & 0 deletions core/slim_globals.h
Expand Up @@ -896,6 +896,7 @@ extern const std::string &gStr_drawSelectionCoefficient;
extern const std::string &gStr_setDistribution;
extern const std::string &gStr_addSubpop;
extern const std::string &gStr_addSubpopSplit;
extern const std::string &gStr_estimatedLastTick;
extern const std::string &gStr_deregisterScriptBlock;
extern const std::string &gStr_genomicElementTypesWithIDs;
extern const std::string &gStr_interactionTypesWithIDs;
Expand Down Expand Up @@ -1311,6 +1312,7 @@ enum _SLiMGlobalStringID : int {
gID_setDistribution,
gID_addSubpop,
gID_addSubpopSplit,
gID_estimatedLastTick,
gID_deregisterScriptBlock,
gID_genomicElementTypesWithIDs,
gID_interactionTypesWithIDs,
Expand Down

0 comments on commit d908c65

Please sign in to comment.