5.2  Class Chromosome

5.2.1  Chromosome properties

colorSubstitution <–> (string$)

The color used to display substitutions in SLiMgui when both mutations and substitutions are being displayed in the chromosome view.  Outside of SLiMgui, this property still exists, but is not used by SLiM.  Colors may be specified by name, or with hexadecimal RGB values of the form "#RRGGBB".  If colorSubstitution is the empty string, "", SLiMgui will defer to the color scheme of each MutationType, just as it does when only substitutions are being displayed.  The default, "3333FF", causes all substitutions to be shown as dark blue when displayed in conjunction with mutations, to prevent the view from becoming too noisy.  Note that when substitutions are displayed without mutations also being displayed, this value is ignored by SLiMgui and the substitutions use the color scheme of each MutationType.

geneConversionEnabled => (logical$)

When gene conversion has been enabled by calling initializeGeneConversion(), switching to the DSB recombination model, this property is T; otherwise, when using the crossover breakpoints model, it is F.

geneConversionGCBias => (float$)

The gene conversion bias coefficient, which expresses a bias in the resolution of heteroduplex mismatches in complex gene conversion tracts.  When gene conversion has not been enabled by calling initializeGeneConversion(), this property will be unavailable.

geneConversionNonCrossoverFraction => (float$)

The fraction of double-stranded breaks that result in non-crossover events.  When gene conversion has not been enabled by calling initializeGeneConversion(), this property will be unavailable.

geneConversionMeanLength => (float$)

The mean length of a gene conversion tract (in base positions).  When gene conversion has not been enabled by calling initializeGeneConversion(), this property will be unavailable.

geneConversionSimpleConversionFraction => (float$)

The fraction of gene conversion tracts that are “simple” (i.e., not involving resolution of heteroduplex mismatches); the remainder will be “complex”.  When gene conversion has not been enabled by calling initializeGeneConversion(), this property will be unavailable.

genomicElements => (object<GenomicElement>)

All of the GenomicElement objects that comprise the chromosome.

hotspotEndPositions => (integer)

The end positions for hotspot map regions along the chromosome.  Each hotspot map region is assumed to start at the position following the end of the previous hotspot map region; in other words, the regions are assumed to be contiguous.  When using sex-specific hotspot maps, this property will unavailable; see hotspotEndPositionsF and hotspotEndPositionsM.

hotspotEndPositionsF => (integer)

The end positions for hotspot map regions for females, when using sex-specific hotspot maps; unavailable otherwise.  See hotspotEndPositions for further explanation.

hotspotEndPositionsM => (integer)

The end positions for hotspot map regions for males, when using sex-specific hotspot maps; unavailable otherwise.  See hotspotEndPositions for further explanation.

hotspotMultipliers => (float)

The hotspot multiplier for each of the hotspot map regions specified by hotspotEndPositions.  When using sex-specific hotspot maps, this property will be unavailable; see hotspotMultipliersF and hotspotMultipliersM.

hotspotMultipliersF => (float)

The hotspot multiplier for each of the hotspot map regions specified by hotspotEndPositionsF, when using sex-specific hotspot maps; unavailable otherwise.

hotspotMultipliersM => (float)

The hotspot multiplier for each of the hotspot map regions specified by hotspotEndPositionsM, when using sex-specific hotspot maps; unavailable otherwise.

lastPosition => (integer$)

The last valid position in the chromosome; its length, essentially.  Note that the chromosome length is determined by the maximum of the end of the last genomic element, the end of the last recombination region, and the end of the last mutation map region (or hotspot map region).

mutationEndPositions => (integer)

The end positions for mutation rate regions along the chromosome.  Each mutation rate region is assumed to start at the position following the end of the previous mutation rate region; in other words, the regions are assumed to be contiguous.  When using sex-specific mutation rate maps, this property will unavailable; see mutationEndPositionsF and mutationEndPositionsM.

This property is unavailable in nucleotide-based models.

mutationEndPositionsF => (integer)

The end positions for mutation rate regions for females, when using sex-specific mutation rate maps; unavailable otherwise.  See mutationEndPositions for further explanation.

This property is unavailable in nucleotide-based models.

mutationEndPositionsM => (integer)

The end positions for mutation rate regions for males, when using sex-specific mutation rate maps; unavailable otherwise.  See mutationEndPositions for further explanation.

This property is unavailable in nucleotide-based models.

mutationRates => (float)

The mutation rate for each of the mutation rate regions specified by mutationEndPositions.  When using sex-specific mutation rate maps, this property will be unavailable; see mutationRatesF and mutationRatesM.

This property is unavailable in nucleotide-based models.

mutationRatesF => (float)

The mutation rate for each of the mutation rate regions specified by mutationEndPositionsF, when using sex-specific mutation rate maps; unavailable otherwise.

This property is unavailable in nucleotide-based models.

mutationRatesM => (float)

The mutation rate for each of the mutation rate regions specified by mutationEndPositionsM, when using sex-specific mutation rate maps; unavailable otherwise.

This property is unavailable in nucleotide-based models.

overallMutationRate => (float$)

The overall mutation rate across the whole chromosome determining the overall number of mutation events that will occur anywhere in the chromosome, as calculated from the individual mutation ranges and rates as well as the coverage of the chromosome by genomic elements (since mutations are only generated within genomic elements, regardless of the mutation rate map).  When using sex-specific mutation rate maps, this property will unavailable; see overallMutationRateF and overallMutationRateM.

This property is unavailable in nucleotide-based models.

overallMutationRateF => (float$)

The overall mutation rate for females, when using sex-specific mutation rate maps; unavailable otherwise.  See overallMutationRate for further explanation.

This property is unavailable in nucleotide-based models.

overallMutationRateM => (float$)

The overall mutation rate for males, when using sex-specific mutation rate maps; unavailable otherwise.  See overallMutationRate for further explanation.

This property is unavailable in nucleotide-based models.

overallRecombinationRate => (float$)

The overall recombination rate across the whole chromosome determining the overall number of recombination events that will occur anywhere in the chromosome, as calculated from the individual recombination ranges and rates.  When using sex-specific recombination maps, this property will unavailable; see overallRecombinationRateF and overallRecombinationRateM.

overallRecombinationRateF => (float$)

The overall recombination rate for females, when using sex-specific recombination maps; unavailable otherwise.  See overallRecombinationRate for further explanation.

overallRecombinationRateM => (float$)

The overall recombination rate for males, when using sex-specific recombination maps; unavailable otherwise.  See overallRecombinationRate for further explanation.

recombinationEndPositions => (integer)

The end positions for recombination regions along the chromosome.  Each recombination region is assumed to start at the position following the end of the previous recombination region; in other words, the regions are assumed to be contiguous.  When using sex-specific recombination maps, this property will unavailable; see recombinationEndPositionsF and recombinationEndPositionsM.

recombinationEndPositionsF => (integer)

The end positions for recombination regions for females, when using sex-specific recombination maps; unavailable otherwise.  See recombinationEndPositions for further explanation.

recombinationEndPositionsM => (integer)

The end positions for recombination regions for males, when using sex-specific recombination maps; unavailable otherwise.  See recombinationEndPositions for further explanation.

recombinationRates => (float)

The recombination rate for each of the recombination regions specified by recombinationEndPositions.  When using sex-specific recombination maps, this property will unavailable; see recombinationRatesF and recombinationRatesM.

recombinationRatesF => (float)

The recombination rate for each of the recombination regions specified by recombinationEndPositionsF, when using sex-specific recombination maps; unavailable otherwise.

recombinationRatesM => (float)

The recombination rate for each of the recombination regions specified by recombinationEndPositionsM, when using sex-specific recombination maps; unavailable otherwise.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.

5.2.2  Chromosome methods

– (is)ancestralNucleotides([Ni$ start = NULL], [Ni$ end = NULL], [string$ format = "string"])

Returns the ancestral nucleotide sequence originally supplied to initializeAncestralNucleotides(), including any sequence changes due to nucleotide mutations that have fixed and substituted.  This nucleotide sequence is the reference sequence for positions in a genome that do not contain a nucleotide-based mutation.  The range of the returned sequence may be constrained by a start position given in start and/or an end position given in end; nucleotides will be returned from start to end, inclusive.  The default value of NULL for start and end represent the first and last base positions of the chromosome, respectively.

The format of the returned sequence is controlled by the format parameter.  A format of "string" will return the sequence as a singleton string (e.g., "TATA").  A format of "char" will return a string vector with one element per nucleotide (e.g., "T", "A", "T", "A").  A format of "integer" will return an integer vector with values A=0, C=1, G=2, T=3 (e.g., 3, 0, 3, 0).  If the sequence returned is likely to be long, the "string" format will be the most memory-efficient, and may also be the fastest (but may be harder to work with).

For purposes related to interpreting the nucleotide sequence as a coding sequence, a format of "codon" is also supported.  This format will return an integer vector with values from 0 to 63, based upon successive nucleotide triplets in the sequence (which, for this format, must have a length that is a multiple of three).  The codon value for a given nucleotide triplet XYZ is 16X + 4Y + Z, where X, Y, and Z have the usual values A=0, C=1, G=2, T=3.  For example, the triplet AAA has a codon value of 0, AAC is 1, AAG is 2, AAT is 3, ACA is 4, and on upward to TTT which is 63.  If the nucleotide sequence AACACATTT is requested in codon format, the codon vector 1 4 63 will therefore be returned.  These codon values can be useful in themselves; they can also be passed to codonToAminoAcid() to translate them into the corresponding amino acid sequence if desired.

– (integer)drawBreakpoints([No<Individual>$ parent = NULL], [Ni$ n = NULL])

Draw recombination breakpoints, using the chromosome’s recombination rate map, the current gene conversion parameters, and (in some cases – see below) any active and applicable recombination() callbacks.  The number of breakpoints to generate, n, may be supplied; if it is NULL (the default), the number of breakpoints will be drawn based upon the overall recombination rate and the chromosome length (following the standard procedure in SLiM).  Note that if the double-stranded breaks model has been chosen, the number of breakpoints generated will probably not be equal to the number requested, because most breakpoints will entail gene conversion tracts, which entail additional crossover breakpoints.

It is generally recommended that the parent individual be supplied to this method, but parent is NULL by default.  The individual supplied in parent is used for two purposes.  First, in sexual models that define separate recombination rate maps for males versus females, the sex of parent will be used to determine which map is used; in this case, a non-NULL value must be supplied for parent, since the choice of recombination rate map must be determined.  Second, in models that define recombination() callbacks, parent is used to determine the various pseudo-parameters that are passed to recombination() callbacks (individual, genome1, genome2, subpop), and the subpopulation to which parent belongs is used to select which recombination() callbacks are applicable; given the necessity of this information, recombination() callbacks will not be called as a side effect of this method if parent is NULL.  Apart from these two uses, parent is not used, and the caller does not guarantee that the generated breakpoints will actually be used to recombine the genomes of parent in particular.

– (integer$)setAncestralNucleotides(is sequence)

This method, which may be called only in nucleotide-based models, replaces the ancestral nucleotide sequence for the model.  The sequence parameter is interpreted exactly as it is in the initializeAncestralSequence() function; see that documentation for details.  The length of the ancestral sequence is returned.

It is unusual to replace the ancestral sequence in a running simulation, since the nucleotide states of segregating and fixed mutations will depend upon the original ancestral sequence.  It can be useful when loading a new population state with readFromMS() or readFromVCF(), such as when resetting the simulation state to an earlier state in a conditional simulation; however, that is more commonly done using readFromPopulationFile() with a SLiM or .trees file.

– (void)setGeneConversion(numeric$ nonCrossoverFraction, numeric$ meanLength, numeric$ simpleConversionFraction, [numeric$ bias = 0])

This method switches the recombination model to the “double-stranded break (DSB)” model (if it is not already set to that), and configures the details of the gene conversion tracts that will therefore be modeled.  The meanings and effects of the parameters exactly mirror the initializeGeneConversion() function.

– (void)setHotspotMap(numeric multipliers, [Ni ends = NULL], [string$ sex = "*"])

In nucleotide-based models, set the mutation rate multiplier along the chromosome.  There are two ways to call this method.  If the optional ends parameter is NULL (the default), then multipliers must be a singleton value that specifies a single multiplier to be used along the entire chromosome.  If, on the other hand, ends is supplied, then multipliers and ends must be the same length, and the values in ends must be specified in ascending order.  In that case, multipliers and ends taken together specify the multipliers to be used along successive contiguous stretches of the chromosome, from beginning to end; the last position specified in ends should extend to the end of the chromosome (as previously determined, during simulation initialization).  See the initializeHotspotMap() function for further discussion of precisely how these multipliers and positions are interpreted.

If the optional sex parameter is "*" (the default), then the supplied hotspot map will be used for both sexes (which is the only option for hermaphroditic simulations).  In sexual simulations sex may be "M" or "F" instead, in which case the supplied hotspot map is used only for that sex.  Note that whether sex-specific hotspot maps will be used is set by the way that the simulation is initially configured with initializeHotspot(), and cannot be changed with this method; so if the simulation was set up to use sex-specific hotspot maps then sex must be "M" or "F" here, whereas if it was set up not to, then sex must be "*" or unsupplied here.  If a simulation needs sex-specific hotspot maps only some of the time, the male and female maps can simply be set to be identical the rest of the time.

The hotspot map is normally constant in simulations, so be sure you know what you are doing.

– (void)setMutationRate(numeric rates, [Ni ends = NULL], [string$ sex = "*"])

Set the mutation rate per base position per generation along the chromosome.  There are two ways to call this method.  If the optional ends parameter is NULL (the default), then rates must be a singleton value that specifies a single mutation rate to be used along the entire chromosome.  If, on the other hand, ends is supplied, then rates and ends must be the same length, and the values in ends must be specified in ascending order.  In that case, rates and ends taken together specify the mutation rates to be used along successive contiguous stretches of the chromosome, from beginning to end; the last position specified in ends should extend to the end of the chromosome (as previously determined, during simulation initialization).  See the initializeMutationRate() function for further discussion of precisely how these rates and positions are interpreted.

If the optional sex parameter is "*" (the default), then the supplied mutation rate map will be used for both sexes (which is the only option for hermaphroditic simulations).  In sexual simulations sex may be "M" or "F" instead, in which case the supplied mutation rate map is used only for that sex.  Note that whether sex-specific mutation rate maps will be used is set by the way that the simulation is initially configured with initializeMutationRate(), and cannot be changed with this method; so if the simulation was set up to use sex-specific mutation rate maps then sex must be "M" or "F" here, whereas if it was set up not to, then sex must be "*" or unsupplied here.  If a simulation needs sex-specific mutation rate maps only some of the time, the male and female maps can simply be set to be identical the rest of the time.

The mutation rate intervals are normally a constant in simulations, so be sure you know what you are doing.

In nucleotide-based models, setMutationRate() may not be called.  If variation in the mutation rate along the chromosome is desired, setHotspotMap() should be used.

– (void)setRecombinationRate(numeric rates, [Ni ends = NULL], [string$ sex = "*"])

Set the recombination rate per base position per generation along the chromosome.  All rates must be in the interval [0.0, 0.5].  There are two ways to call this method.  If the optional ends parameter is NULL (the default), then rates must be a singleton value that specifies a single recombination rate to be used along the entire chromosome.  If, on the other hand, ends is supplied, then rates and ends must be the same length, and the values in ends must be specified in ascending order.  In that case, rates and ends taken together specify the recombination rates to be used along successive contiguous stretches of the chromosome, from beginning to end; the last position specified in ends should extend to the end of the chromosome (as previously determined, during simulation initialization).  See the initializeRecombinationRate() function for further discussion of precisely how these rates and positions are interpreted.

If the optional sex parameter is "*" (the default), then the supplied recombination rate map will be used for both sexes (which is the only option for hermaphroditic simulations).  In sexual simulations sex may be "M" or "F" instead, in which case the supplied recombination map is used only for that sex.  Note that whether sex-specific recombination maps will be used is set by the way that the simulation is initially configured with initializeRecombinationRate(), and cannot be changed with this method; so if the simulation was set up to use sex-specific recombination maps then sex must be "M" or "F" here, whereas if it was set up not to, then sex must be "*" or unsupplied here.  If a simulation needs sex-specific recombination maps only some of the time, the male and female maps can simply be set to be identical the rest of the time.

The recombination intervals are normally a constant in simulations, so be sure you know what you are doing.

5.3  Class Genome

5.3.1  Genome properties

genomePedigreeID => (integer$)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), genomePedigreeID is a unique non-negative identifier for each genome in a simulation, never re-used throughout the duration of the simulation run.  Furthermore, the genomePedigreeID of a given genome will be equal to either (2*pedigreeID) or (2*pedigreeID + 1) of the individual that the genome belongs to (the former for the first genome of the individual, the latter for the second genome of the individual); this invariant relationship is guaranteed.  If pedigree tracking is not enabled, this property is unavailable.

genomeType => (string$)

The type of chromosome represented by this genome; one of "A", "X", or "Y".

individual => (object<Individual>$)

The Individual object to which this genome belongs.

isNullGenome => (logical$)

T if the genome is a “null” genome, F if it is an ordinary genome object.  When a sex chromosome (X or Y) is simulated, the other sex chromosome also exists in the simulation, but it is a “null” genome that does not carry any mutations.  Instead, it is a placeholder, present to allow SLiM’s code to operate in much the same way as it does when an autosome is simulated.  Null genomes should not be accessed or manipulated.

mutations => (object<Mutation>)

All of the Mutation objects present in this genome.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.

Note that the Genome objects used by SLiM are new with every generation, so the tag value of each new offspring generated in each generation will be initially undefined.  If you set a tag value for an offspring genome inside a modifyChild() callback, that tag value will be preserved as the offspring individual becomes a parent (across the generation boundary, in other words).  If you take advantage of this, however, you should be careful to set up initial values for the tag values of all offspring, otherwise undefined initial values might happen to match the values that you are trying to use to tag particular individuals.  A rule of thumb in programming: undefined values should always be assumed to take on the most inconvenient value possible.

5.3.2  Genome methods

+ (void)addMutations(object<Mutation> mutations)

Add the existing mutations in mutations to the genome, if they are not already present (if they are already present, they will be ignored), and if the addition is not prevented by the mutation stacking policy (see the mutationStackPolicy property of MutationType).

Calling this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

Note that in nonWF models that use tree-sequence recording, mutations cannot be added to an individual after the generation in which the individual is created (i.e., when the age of the individual is greater than 0), to prevent the possibility of inconsistencies in the recorded tree sequence.

+ (object<Mutation>)addNewDrawnMutation(io<MutationType> mutationType, integer position, [Ni originGeneration = NULL], [Nio<Subpopulation> originSubpop = NULL], [Nis nucleotide = NULL])

Add new mutations to the target genome(s) with the specified mutationType (specified by the MutationType object or by integer identifier), position, originGeneration (which may be NULL, the default, to specify the current generation; otherwise, beginning in SLiM 3.5, it must be equal to the current generation anyway, as other uses of this property have been deprecated), and originSubpop (specified by the Subpopulation object or by integer identifier, or by NULL, the default, to specify the subpopulation to which the first target genome belongs).  If originSubpop is supplied as an integer, it is intentionally not checked for validity; you may use arbitrary values of originSubpop to “tag” the mutations that you create.  The selection coefficients of the mutations are drawn from their mutation types; addNewMutation() may be used instead if you wish to specify selection coefficients.

In non-nucleotide-based models, mutationType will always be a non-nucleotide-based mutation type, and so nucleotide must be NULL (the default).  In a nucleotide-based model, mutationType might still be non-nucleotide-based (in which case nucleotide must still be NULL), or mutationType might be nucleotide-based, in which case a non-NULL value must be supplied for nucleotide, specifying the nucleotide(s) to be associated with the new mutation(s).  Nucleotides may be specified with string values ("A", "C", "G", or "T"), or with integer values (A=0, C=1, G=2, T=3).  If a nucleotide mutation already exists at the mutating position, it is replaced automatically in accordance with the stacking policy for nucleotide-based mutation types.  No check is performed that a new mutation’s nucleotide differs from the ancestral sequence, or that its selection coefficient is consistent with other mutations that may already exist at the given position with the same nucleotide; model consistency is the responsibility of the model.

Beginning in SLiM 2.5 this method is vectorized, so all of these parameters may be singletons (in which case that single value is used for all mutations created by the call) or non-singleton vectors (in which case one element is used for each corresponding mutation created).  Non-singleton parameters must match in length, since their elements need to be matched up one-to-one.

The new mutations created by this method are returned, even if their actual addition is prevented by the mutation stacking policy (see the mutationStackPolicy property of MutationType).  However, the order of the mutations in the returned vector is not guaranteed to be the same as the order in which the values are specified in parameter vectors, unless the position parameter is specified in ascending order.  In other words, pre-sorting the parameters to this method into ascending order by position, using order() and subsetting, will guarantee that the order of the returned vector of mutations corresponds to the order of elements in the parameters to this method; otherwise, no such guarantee exists.

Beginning in SLiM 2.1, this is a class method, not an instance method.  This means that it does not get multiplexed out to all of the elements of the receiver (which would add a different new mutation to each element); instead, it is performed as a single operation, adding the same new mutation objects to all of the elements of the receiver.  Before SLiM 2.1, to add the same mutations to multiple genomes, it was necessary to call addNewDrawnMutation() on one of the genomes, and then add the returned Mutation object to all of the other genomes using addMutations().  That is not necessary in SLiM 2.1 and later, because of this change (although doing it the old way does no harm and produces identical behavior).  Pre-2.1 code that actually relied upon the old multiplexing behavior will no longer work correctly (but this is expected to be an extremely rare pattern of usage).

Calling this will normally affect the fitness values calculated at the end of the current generation (but not sooner); if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

Note that in nonWF models that use tree-sequence recording, mutations cannot be added to an individual after the generation in which the individual is created (i.e., when the age of the individual is greater than 0), to prevent the possibility of inconsistencies in the recorded tree sequence.

+ (object<Mutation>)addNewMutation(io<MutationType> mutationType, numeric selectionCoeff, integer position, [Ni originGeneration = NULL], [Nio<Subpopulation> originSubpop = NULL], [Nis nucleotide = NULL])

Add new mutations to the target genome(s) with the specified mutationType (specified by the MutationType object or by integer identifier), selectionCoeff, position, originGeneration (which may be NULL, the default, to specify the current generation; otherwise, beginning in SLiM 3.5, it must be equal to the current generation anyway, as other uses of this property have been deprecated), and originSubpop (specified by the Subpopulation object or by integer identifier, or by NULL, the default, to specify the subpopulation to which the first target genome belongs).  If originSubpop is supplied as an integer, it is intentionally not checked for validity; you may use arbitrary values of originSubpop to “tag” the mutations that you create.  The addNewDrawnMutation() method may be used instead if you wish selection coefficients to be drawn from the mutation types of the mutations.

In non-nucleotide-based models, mutationType will always be a non-nucleotide-based mutation type, and so nucleotide must be NULL (the default).  In a nucleotide-based model, mutationType might still be non-nucleotide-based (in which case nucleotide must still be NULL), or mutationType might be nucleotide-based, in which case a non-NULL value must be supplied for nucleotide, specifying the nucleotide(s) to be associated with the new mutation(s).  Nucleotides may be specified with string values ("A", "C", "G", or "T"), or with integer values (A=0, C=1, G=2, T=3).  If a nucleotide mutation already exists at the mutating position, it is replaced automatically in accordance with the stacking policy for nucleotide-based mutation types.  No check is performed that a new mutation’s nucleotide differs from the ancestral sequence, or that its selection coefficient is consistent with other mutations that may already exist at the given position with the same nucleotide; model consistency is the responsibility of the model.

The new mutations created by this method are returned, even if their actual addition is prevented by the mutation stacking policy (see the mutationStackPolicy property of MutationType).  However, the order of the mutations in the returned vector is not guaranteed to be the same as the order in which the values are specified in parameter vectors, unless the position parameter is specified in ascending order.  In other words, pre-sorting the parameters to this method into ascending order by position, using order() and subsetting, will guarantee that the order of the returned vector of mutations corresponds to the order of elements in the parameters to this method; otherwise, no such guarantee exists.

Beginning in SLiM 2.1, this is a class method, not an instance method.  This means that it does not get multiplexed out to all of the elements of the receiver (which would add a different new mutation to each element); instead, it is performed as a single operation, adding the same new mutation object to all of the elements of the receiver.  Before SLiM 2.1, to add the same mutation to multiple genomes, it was necessary to call addNewMutation() on one of the genomes, and then add the returned Mutation object to all of the other genomes using addMutations().  That is not necessary in SLiM 2.1 and later, because of this change (although doing it the old way does no harm and produces identical behavior).  Pre-2.1 code that actually relied upon the old multiplexing behavior will no longer work correctly (but this is expected to be an extremely rare pattern of usage).

Calling this will normally affect the fitness values calculated at the end of the current generation (but not sooner); if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

Note that in nonWF models that use tree-sequence recording, mutations cannot be added to an individual after the generation in which the individual is created (i.e., when the age of the individual is greater than 0), to prevent the possibility of inconsistencies in the recorded tree sequence.

 (Nlo<Mutation>$)containsMarkerMutation(io<MutationType>$ mutType, integer$ position, [logical$ returnMutation = F])

Returns T if the genome contains a mutation of type mutType at position, F otherwise (if returnMutation has its default value of F; see below).  This method is, as its name suggests, intended for checking for “marker mutations”: mutations of a special mutation type that are not literally mutations in the usual sense, but instead are added in to particular genomes to mark them as possessing some property.  Marker mutations are not typically added by SLiM’s mutation-generating machinery; instead they are added explicitly with addNewMutation() or addNewDrawnMutation() at a known, constant position in the genome.  This method provides a check for whether a marker mutation of a given type exists in a particular genome; because the position to check is known in advance, that check can be done much faster than the equivalent check with containsMutations() or countOfMutationsOfType(), using a binary search of the genome.

If returnMutation is T (an option added in SLiM 3), this method returns the actual mutation found, rather than just T or F.  More specifically, the first mutation found of mutType at position will be returned; if more than one such mutation exists in the target genome, which one is returned is not defined.  If returnMutation is T and no mutation of mutType is found at position, NULL will be returned.

– (logical)containsMutations(object<Mutation> mutations)

Returns a logical vector indicating whether each of the mutations in mutations is present in the genome; each element in the returned vector indicates whether the corresponding mutation is present (T) or absent (F).  This method is provided for speed; it is much faster than the corresponding Eidos code.

 (integer$)countOfMutationsOfType(io<MutationType>$ mutType)

Returns the number of mutations that are of the type specified by mutType, out of all of the mutations in the genome.  If you need a vector of the matching Mutation objects, rather than just a count, use -mutationsOfType().  This method is provided for speed; it is much faster than the corresponding Eidos code.

+ (integer)mutationCountsInGenomes([No<Mutation> mutations = NULL])

Return an integer vector with the frequency counts of all of the Mutation objects passed in mutations, within the target Genome vector.  If the optional mutations argument is NULL (the default), frequency counts will be returned for all of the active Mutation objects in the simulation – the same Mutation objects, and in the same order, as would be returned by the mutations property of sim, in other words.

See the +mutationFrequenciesInGenomes() method to obtain float frequencies instead of integer counts.  See also the SLiMSim methods mutationCounts() and mutationFrequencies(), which may be more efficient for getting counts/frequencies for whole subpopulations or for the whole simulation.

+ (float)mutationFrequenciesInGenomes([No<Mutation> mutations = NULL])

Return a float vector with the frequencies of all of the Mutation objects passed in mutations, within the target Genome vector.  If the optional mutations argument is NULL (the default), frequencies will be returned for all of the active Mutation objects in the simulation – the same Mutation objects, and in the same order, as would be returned by the mutations property of sim, in other words.

See the +mutationCountsInGenomes() method to obtain integer counts instead of float frequencies.  See also the SLiMSim methods mutationCounts() and mutationFrequencies(), which may be more efficient for getting counts/frequencies for whole subpopulations or for the whole simulation.

 (object<Mutation>)mutationsOfType(io<MutationType>$ mutType)

Returns an object vector of all the mutations that are of the type specified by mutType, out of all of the mutations in the genome.  If you just need a count of the matching Mutation objects, rather than a vector of the matches, use -countOfMutationsOfType(); if you need just the positions of matching Mutation objects, use -positionsOfMutationsOfType(); and if you are aiming for a sum of the selection coefficients of matching Mutation objects, use -sumOfMutationsOfType().  This method is provided for speed; it is much faster than the corresponding Eidos code.

– (is)nucleotides([Ni$ start = NULL], [Ni$ end = NULL], [string$ format = "string"])

Returns the nucleotide sequence for the genome.  This is the current ancestral sequence, as would be returned by the Chromosome method ancestralNucleotides(), with the nucleotides for any nucleotide-based mutations in the genome overlaid.  The range of the returned sequence may be constrained by a start position given in start and/or an end position given in end; nucleotides will be returned from start to end, inclusive.  The default value of NULL for start and end represent the first and last base positions of the chromosome, respectively.

The format of the returned sequence is controlled by the format parameter.  A format of "string" will return the sequence as a singleton string (e.g., "TATA").  A format of "char" will return a string vector with one element per nucleotide (e.g., "T", "A", "T", "A").  A format of "integer" will return an integer vector with values A=0, C=1, G=2, T=3 (e.g., 3, 0, 3, 0).  A format of "codon" will return an integer vector with values from 0 to 63, based upon successive nucleotide triplets in the sequence (which, for this format, must have a length that is a multiple of three); see the ancestralNucleotides() documentation for details.  If the sequence returned is likely to be long, the "string" format will be the most memory-efficient, and may also be the fastest (but may be harder to work with).

Several helper functions are provided for working with sequences, such as nucleotideCounts() to get the counts of A/C/G/T nucleotides in a sequence, nucleotideFrequencies() to get the same information as frequencies, and codonsToAminoAcids() to convert a codon sequence (such as provided by the codon format described above) to an amino acid sequence.

+ (void)output([Ns$ filePath = NULL], [logical$ append = F])

Output the target genomes in SLiM’s native format.  This low-level output method may be used to output any sample of Genome objects (the Eidos function sample() may be useful for constructing custom samples, as may the SLiM class Individual).  For output of a sample from a single Subpopulation, the outputSample() of Subpopulation may be more straightforward to use.  If the optional parameter filePath is NULL (the default), output is directed to SLiM’s standard output.  Otherwise, the output is sent to the file specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.

See outputMS() and outputVCF() for other output formats.  Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

+ (void)outputMS([Ns$ filePath = NULL], [logical$ append = F], [logical$ filterMonomorphic = F])

Output the target genomes in MS format.  This low-level output method may be used to output any sample of Genome objects (the Eidos function sample() may be useful for constructing custom samples, as may the SLiM class Individual).  For output of a sample from a single Subpopulation, the outputMSSample() of Subpopulation may be more straightforward to use.  If the optional parameter filePath is NULL (the default), output is directed to SLiM’s standard output.  Otherwise, the output is sent to the file specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.  Positions in the output will span the interval [0,1].

If filterMonomorphic is F (the default), all mutations that are present in the sample will be included in the output.  This means that some mutations may be included that are actually monomorphic within the sample (i.e., that exist in every sampled genome, and are thus apparently fixed).  These may be filtered out with filterMonomorphic = T if desired; note that this option means that some mutations that do exist in the sampled genomes might not be included in the output, simply because they exist in every sampled genome.

See output() and outputVCF() for other output formats.  Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

+ (void)outputVCF([Ns$ filePath = NULL], [logical$ outputMultiallelics = T], [logical$ append = F], [logical$ simplifyNucleotides = F], [logical$ outputNonnucleotides = T])

Output the target genomes in VCF format.  The target genomes are treated as pairs comprising individuals for purposes of structuring the VCF output, so an even number of genomes is required.  This low-level output method may be used to output any sample of Genome objects (the Eidos function sample() may be useful for constructing custom samples, as may the SLiM class Individual).  For output of a sample from a single Subpopulation, the outputVCFSample() of Subpopulation may be more straightforward to use.  If the optional parameter filePath is NULL (the default), output is directed to SLiM’s standard output.  Otherwise, the output is sent to the file specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.

The parameters outputMultiallelics, simplifyNucleotides, and outputNonnucleotides affect the format of the output produced; see the reference documentation for further discussion.

See outputMS() and output() for other output formats.  Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (integer)positionsOfMutationsOfType(io<MutationType>$ mutType)

Returns the positions of mutations that are of the type specified by mutType, out of all of the mutations in the genome.  If you need a vector of the matching Mutation objects, rather than just positions, use -mutationsOfType().  This method is provided for speed; it is much faster than the corresponding Eidos code.

+ (object<Mutation>)readFromMS(string$ filePath, io<MutationType>$ mutationType)

Read new mutations from the MS format file at filePath and add them to the target genomes.  The number of target genomes must match the number of genomes represented in the MS file.  To read into all of the genomes in a given subpopulation pN, simply call pN.genomes.readFromMS(), assuming the subpopulation’s size matches that of the MS file.  A vector containing all of the mutations created by readFromMS() is returned.

Each mutation is created at the position specified in the file, using the mutation type given by mutationType.  Positions are expected to be in [0,1], and are scaled to the length of the chromosome by multiplying by the last valid base position of the chromosome (i.e., one less than the chromosome length).  Selection coefficients are drawn from the mutation type.  The population of origin for each mutation is set to -1, and the generation of origin is set to the current generation.  In a nucleotide-based model, if mutationType is nucleotide-based, a random nucleotide different from the ancestral nucleotide at the position will be chosen with equal probability.

The target genomes correspond, in order, to the call lines in the MS file.  In sex-based models that simulate the X or Y chromosome, null genomes in the target vector will be skipped, and will not be used to correspond to any call line; however, care should be taken in this case that the lines in the MS file correspond to the target genomes in the manner desired.

+ (object<Mutation>)readFromVCF(string$ filePath, [Nio<MutationType>$ mutationType = NULL])

Read new mutations from the VCF format file at filePath and add them to the target genomes.  The number of target genomes must match the number of genomes represented in the VCF file (i.e., two times the number of samples, if each sample is diploid).  To read into all of the genomes in a given subpopulation pN, simply call pN.genomes.readFromVCF(), assuming the subpopulation’s size matches that of the VCF file taking ploidy into account.  A vector containing all of the mutations created by readFromVCF() is returned.

SLiM’s VCF parsing is quite primitive.  The header is parsed only inasmuch as SLiM looks to see whether SLiM-specific VCF fields are defined or not; the rest of the header information is ignored.  Call lines are assumed to follow the format:

#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT i0...iN

The CHROM, ID, QUAL, FILTER, and FORMAT fields are ignored, and information in the genotype fields beyond the GT genotype subfield are also ignored.  SLiM’s own VCF annotations are honored; in particular, mutations will be created using the given values of MID, S, PO, GO, and MT if those subfields are present, and DOM, if it is present, must match the dominance coefficient of the mutation type.  The parameter mutationType (a MutationType object or id) will be used for any mutations that have no supplied mutation type id in the MT subfield; if mutationType would be used but is NULL an error will result.  Mutation IDs supplied in MID will be used if no mutation IDs have been used in the simulation so far; if any have been used, it is difficult for SLiM to guarantee that there are no conflicts, so a warning will be emitted and the MID values will be ignored.  If selection coefficients are not supplied with the S subfield, they will be drawn from the mutation type used for the mutation.  If a population of origin is not supplied with the PO subfield, -1 will be used.  If a generation of origin is not supplied with the GO subfield, the current generation will be used.

REF and ALT must always be comprised of simple nucleotides (A/C/G/T) rather than values representing indels or other complex states.  Beyond this, the handling of the REF and ALT fields depends upon several factors.  First of all, these fields are ignored in non-nucleotide-based models, although they are still checked for conformance.  In nucleotide-based models, when a header definition for SLiM’s NONNUC tag is present (as when nucleotide-based output is generated by SLiM): Second, if a NONNUC field is present in the INFO field the call line is taken to represent a non-nucleotide-based mutation, and REF and ALT are again ignored.  In this case the mutation type used must be non-nucleotide-based.  Third, if NONNUC is not present the call line is taken to represent a nucleotide-based mutation.  In this case, the mutation type used must be nucleotide-based.  Also, in this case, the specified reference nucleotide must match the existing ancestral nucleotide at the given position.  In nucleotide-based models, when a header definition for SLiM’s NONNUC tag is not present (as when loading a non-SLiM-generated VCF file): The mutation type will govern the way nucleotides are handled.  If the mutation type used for a mutation is nucleotide-based, the nucleotide provided in the VCF file for that allele will be used.  If the mutation type is non-nucleotide-based, the nucleotide provided will be ignored.

If multiple alleles using the same nucleotide at the same position are specified in the VCF file, a separate mutation will be created for each, mirroring SLiM’s behavior with independent mutational lineages when writing VCF.  The MULTIALLELIC flag is ignored by readFromVCF(); call lines for mutations at the same base position in the same genome will result in stacked mutations whether or not MULTIALLELIC is present.

The target genomes correspond, in order, to the haploid or diploid calls provided for i0iN (the sample IDs) in the VCF file.  In sex-based models that simulate the X or Y chromosome, null genomes in the target vector will be skipped, and will not be used to correspond to any of i0iN; however, care should be taken in this case that the genomes in the VCF file correspond to the target genomes in the manner desired.

+ (void)removeMutations([No<Mutation> mutations = NULL], [logical$ substitute = F])

Remove the mutations in mutations from the target genome(s), if they are present (if they are not present, they will be ignored).  If NULL is passed for mutations (which is the default), then all mutations will be removed from the target genomes; in this case, substitute must be F (a specific vector of mutations to be substituted is required).  Note that the Mutation objects removed remain valid, and will still be in the simulation’s mutation registry (i.e. will be returned by SLiMSim’s mutations property), until the next generation.

Changing this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

The optional parameter substitute was added in SLiM 2.2, with a default of F for backward compatibility.  If substitute is T, Substitution objects will be created for all of the removed mutations so that they are recorded in the simulation as having fixed, just as if they had reached fixation and been removed by SLiM’s own internal machinery.  This will occur regardless of whether the mutations have in fact fixed, regardless of the convertToSubstitution property of the relevant mutation types, and regardless of whether all copies of the mutations have even been removed from the simulation (making it possible to create Substitution objects for mutations that are still segregating).  It is up to the caller to perform whatever checks are necessary to preserve the integrity of the simulation’s records.  Typically substitute will only be set to T in the context of calls like sim.subpopulations.genomes.removeMutations(muts, T), such that the substituted mutations are guaranteed to be entirely removed from circulation.  As mentioned above, substitute may not be T if mutations is NULL.

 (float$)sumOfMutationsOfType(io<MutationType>$ mutType)

Returns the sum of the selection coefficients of all mutations that are of the type specified by mutType, out of all of the mutations in the genome.  This is often useful in models that use a particular mutation type to represent QTLs with additive effects; in that context, sumOfMutationsOfType() will provide the sum of the additive effects of the QTLs for the given mutation type.  This method is provided for speed; it is much faster than the corresponding Eidos code.  Note that this method also exists on Individual, for cases in which the sum across both genomes of an individual is desired.

5.4  Class GenomicElement

5.4.1  GenomicElement properties

endPosition => (integer$)

The last position in the chromosome contained by this genomic element.

genomicElementType => (object<GenomicElementType>$)

The GenomicElementType object that defines the behavior of this genomic element.

startPosition => (integer$)

The first position in the chromosome contained by this genomic element.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.

5.4.2  GenomicElement methods

– (void)setGenomicElementType(io<GenomicElementType>$ genomicElementType)

Set the genomic element type used for a genomic element.  The genomicElementType parameter should supply the new genomic element type for the element, either as a GenomicElementType object or as an integer identifier.  The genomic element type for a genomic element is normally a constant in simulations, so be sure you know what you are doing.

5.5  Class GenomicElementType

5.5.1  GenomicElementType properties

color <–> (string$)

The color used to display genomic elements of this type in SLiMgui.  Outside of SLiMgui, this property still exists, but is not used by SLiM.  Colors may be specified by name, or with hexadecimal RGB values of the form "#RRGGBB".  If color is the empty string, "", SLiMgui’s default color scheme is used; this is the default for new GenomicElementType objects.

id => (integer$)

The identifier for this genomic element type; for genomic element type g3, for example, this is 3.

mutationFractions => (float)

For each MutationType represented in this genomic element type, this property has the corresponding fraction of all mutations that will be drawn from that MutationType.

mutationMatrix => (float)

The nucleotide mutation matrix used for this genomic element type, set up by initializeGenomicElementType() and setMutationMatrix().  This property is only defined in nucleotide-based models; it is unavailable otherwise.

mutationTypes => (object<MutationType>)

The MutationType instances used by this genomic element type.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to genomic element types.

5.5.2  GenomicElementType methods

– (void)setMutationFractions(io<MutationType> mutationTypes, numeric proportions)

Set the mutation type fractions contributing to a genomic element type.  The mutationTypes vector should supply the mutation types used by the genomic element (either as MutationType objects or as integer identifiers), and the proportions vector should be of equal length, specifying the relative proportion of mutations that will be drawn from each corresponding type.  This is normally a constant in simulations, so be sure you know what you are doing.

– (void)setMutationMatrix(float mutationMatrix)

Sets a new nucleotide mutation matrix for the genomic element type.  This replaces the mutation matrix originally set by initializeGenomicElementType().  This method may only be called in nucleotide-based models.

5.6  Class Individual

5.6.1  Individual properties

age <–> (integer$)

The age of the individual, measured in generation “ticks”.  A newly generated offspring individual will have an age of 0 in the same generation in which is was created.  The age of every individual is incremented by one at the same point that the generation counter is incremented.  The age of individuals may be changed; usually this only makes sense when setting up the initial state of a model, however.

color <–> (string$)

The color used to display the individual in SLiMgui.  Outside of SLiMgui, this property still exists, but is not used by SLiM.  Colors may be specified by name, or with hexadecimal RGB values of the form "#RRGGBB".  If color is the empty string, "", SLiMgui’s default (fitness-based) color scheme is used; this is the default for new Individual objects.

fitnessScaling <–> (float$)

A float scaling factor applied to the individual’s fitness (i.e., the fitness value computed for the individual will be multiplied by this value).  This provides a simple, fast way to modify the fitness of an individual; conceptually it is similar to returning a fitness effect for the individual from a fitness(NULL) callback, but without the complexity and performance overhead of implementing such a callback.  To scale the fitness of all individuals in a subpopulation by the same factor, see the fitnessScaling property of Subpopulation.

The value of fitnessScaling is reset to 1.0 every generation, so that any scaling factor set lasts for only a single generation.  This reset occurs immediately after fitness values are calculated, in both WF and nonWF models.

genomes => (object<Genome>)

The pair of Genome objects associated with this individual.  If only one of the two genomes is desired, the genome1 or genome2 property may be used.

genomesNonNull => (object<Genome>)

The pair of Genome objects associated with this individual, as with the genomes property, if both are not null genomes.  If one or both are null genomes, the null genomes are excluded from the returned vector.  This is a convenience shorthand, sometimes useful in models that involve null genomes.

genome1 => (object<Genome>$)

The first Genome object associated with this individual.  This property is particularly useful when you want the first genome from each of a vector of individuals, as often arises in haploid models.

genome2 => (object<Genome>$)

The second Genome object associated with this individual.  This property is particularly useful when you want the second genome from each of a vector of individuals, as often arises in haploid models.

index => (integer$)

The index of the individual in the individuals vector of its Subpopulation.

migrant => (logical$)

Set to T if the individual migrated during the current generation, F otherwise.

In WF models, this flag is set at the point when a new child is generated if it is a migrant (i.e., if its source subpopulation is not the same as its subpopulation), and remains valid, with the same value, for the rest of the individual’s lifetime.

In nonWF models, this flag is F for all new individuals, is set to F in all individuals at the end of the reproduction generation cycle stage, and is set to T on all individuals moved to a new subpopulation by takeMigrants(); the T value set by takeMigrants() will remain until it is reset at the end of the next reproduction generation cycle stage.

pedigreeID => (integer$)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), pedigreeID is a unique non-negative identifier for each individual in a simulation, never re-used throughout the duration of the simulation run.  If pedigree tracking is not enabled, this property is unavailable.

pedigreeParentIDs => (integer)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), pedigreeParentIDs contains the values of pedigreeID that were possessed by the parents of an individual; it is thus a vector of two values.  If pedigree tracking is not enabled, this property is unavailable.  Parental values may be -1 if insufficient generations have elapsed for that information to be available (because the simulation just started, or because a subpopulation is new).

pedigreeGrandparentIDs => (integer)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), pedigreeGrandparentIDs contains the values of pedigreeID that were possessed by the grandparents of an individual; it is thus a vector of four values.  If pedigree tracking is not enabled, this property is unavailable.  Grandparental values may be -1 if insufficient generations have elapsed for that information to be available (because the simulation just started, or because a subpopulation is new).

reproductiveOutput => (integer$)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), reproductiveOutput contains the number of offspring for which this individual has been a parent.  If pedigree tracking is not enabled, this property is unavailable.  If an individual is a parent by cloning or selfing, or as both parents for a biparental mating, this value is incremented by two.  Involvement of an individual as a parent for an addRecombinant() call does not change this property’s value, since the reproductive contribution in that case is unclear; one must conduct separate bookkeeping for that case if necessary.

This property is only useful in nonWF models, since in WF models the parental generation dies immediately after reproduction, giving no opportunity to query this property.  For WF models (and nonWF models, too), see the Subpopulation property lifetimeReproductiveOutput.

sex => (string$)

The sex of the individual.  This will be "H" if sex is not enabled in the simulation (i.e., for hermaphrodites), otherwise "F" or "M" as appropriate.

spatialPosition => (float)

The spatial position of the individual.  The length of the spatialPosition property (the number of coordinates in the spatial position of an individual) depends upon the spatial dimensionality declared with initializeSLiMOptions().  If the spatial dimensionality is zero (as it is by default), it is an error to access this property.  The elements of this property are identical to the values of the x, y, and z properties (if those properties are encompassed by the spatial dimensionality of the simulation).  In other words, if the declared dimensionality is "xy", the individual.spatialPosition property is equivalent to c(individual.x, individual.y); individual.z is not used since it is not encompassed by the simulation’s dimensionality.

subpopulation => (object<Subpopulation>$)

The Subpopulation object to which the individual belongs.

tag <–> (integer$)

A user-defined integer value (as opposed to tagF, which is of type float).  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to individuals.

Note that the Individual objects used by SLiM are (conceptually) new with every generation, so the tag value of each new offspring generated in each generation will be initially undefined.  If you set a tag value for an offspring individual inside a modifyChild() callback, that tag value will be preserved as the offspring individual becomes a parent (across the generation boundary, in other words).  If you take advantage of this, however, you should be careful to set up initial values for the tag values of all offspring, otherwise undefined initial values might happen to match the values that you are trying to use to tag particular individuals.  A rule of thumb in programming: undefined values should always be assumed to take on the most inconvenient value possible.

tagF <–> (float$)

A user-defined float value (as opposed to tag, which is of type integer).  The value of tagF is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tagF is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to individuals.

Note that at present, although many classes in SLiM have an integer-type tag property, only Individual has a float-type tagF property, because attaching model state to individuals seems to be particularly common and useful.  If a tagF property would be helpful on another class, it would be easy to add.

See the description of the tag property above for additional comments.

uniqueMutations => (object<Mutation>)

All of the Mutation objects present in this individual.  Mutations present in both genomes will occur only once in this property, and the mutations will be given in sorted order by position, so this property is similar to sortBy(unique(individual.genomes.mutations), "position").  It is not identical to that call, only because if multiple mutations exist at the exact same position, they may be sorted differently by this method than they would be by sortBy().  This method is provided primarily for speed; it executes much faster than the Eidos equivalent above.  Indeed, it is faster than just individual.genomes.mutations, and gives uniquing and sorting on top of that, so it is advantageous unless duplicate entries for homozygous mutations are actually needed.

x <–> (float$)

A user-defined float value.  The value of x is initially undefined (i.e., has an effectively random value that could be different every time you run your model); if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code, typically in a modifyChild() callback.  The value of x is not used by SLiM unless the optional “continuous space” facility is enabled with the dimensionality parameter to initializeSLiMOptions(), in which case x will be understood to represent the x coordinate of the individual in space.  If continuous space is not enabled, you may use x as an additional tag value of type float.

y <–> (float$)

A user-defined float value.  The value of y is initially undefined (i.e., has an effectively random value that could be different every time you run your model); if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code, typically in a modifyChild() callback.  The value of y is not used by SLiM unless the optional “continuous space” facility is enabled with the dimensionality parameter to initializeSLiMOptions(), in which case y will be understood to represent the y coordinate of the individual in space (if the dimensionality is "xy" or "xyz").  If continuous space is not enabled, or the dimensionality is not "xy" or "xyz", you may use y as an additional tag value of type float.

z <–> (float$)

A user-defined float value.  The value of z is initially undefined (i.e., has an effectively random value that could be different every time you run your model); if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code, typically in a modifyChild() callback.  The value of z is not used by SLiM unless the optional “continuous space” facility is enabled with the dimensionality parameter to initializeSLiMOptions(), in which case z will be understood to represent the z coordinate of the individual in space (if the dimensionality is "xyz").  If continuous space is not enabled, or the dimensionality is not "xyz", you may use z as an additional tag value of type float.

5.6.2  Individual methods

– (logical)containsMutations(object<Mutation> mutations)

Returns a logical vector indicating whether each of the mutations in mutations is present in the individual (in either of its genomes); each element in the returned vector indicates whether the corresponding mutation is present (T) or absent (F).  This method is provided for speed; it is much faster than the corresponding Eidos code.

 (integer$)countOfMutationsOfType(io<MutationType>$ mutType)

Returns the number of mutations that are of the type specified by mutType, out of all of the mutations in the individual (in both of its genomes; a mutation that is present in both genomes counts twice).  If you need a vector of the matching Mutation objects, rather than just a count, use the Genome method -mutationsOfType().  This method is provided for speed; it is much faster than the corresponding Eidos code.

 (float)relatedness(object<Individual> individuals)

Returns a vector containing the degrees of relatedness between the receiver and each of the individuals in individuals.  The relatedness between A and B is always 1.0 if A and B are actually the same individual; this facility works even if SLiM’s optional pedigree tracking is not enabled (in which case all other relatedness values will be 0.0).  Otherwise, if pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), this method will use the pedigree information to construct a relatedness estimate.  More specifically, if information about the grandparental generation is available, then each grandparent shared by A and B contributes 0.125 towards the total relatedness, for a maximum value of 0.5 with four shared grandparents.  If grandparental information is unavailable, then if parental information is available it is used, with each parent shared by A and B contributing 0.25, again for a maximum of 0.5.  If even parental information is unavailable, then the relatedness is assumed to be 0.0.  Again, however, if A and B are the same individual, the relatedness will be 1.0 in all cases.

Note that this relatedness is simply pedigree-based relatedness.  This does not necessarily correspond to genetic relatedness, because of the effects of factors like assortment and recombination.

+ (void)setSpatialPosition(float position)

Sets the spatial position of the individual (as accessed through the spatialPosition property).  The length of position (the number of coordinates in the spatial position of an individual) depends upon the spatial dimensionality declared with initializeSLiMOptions().  If the spatial dimensionality is zero (as it is by default), it is an error to call this method.  The elements of position are set into the values of the x, y, and z properties (if those properties are encompassed by the spatial dimensionality of the simulation).  In other words, if the declared dimensionality is "xy", calling individual.setSpatialPosition(c(1.0, 0.5)) property is equivalent to individual.x = 1.0; individual.y = 0.5; individual.z is not set (even if a third value is supplied in position) since it is not encompassed by the simulation’s dimensionality in this example.

Note that this is an Eidos class method, somewhat unusually, which allows it to work in a special way when called on a vector of individuals.  When the target vector of individuals is non-singleton, this method can do one of two things.  If position contains just a single point (i.e., is equal in length to the spatial dimensionality of the model), the spatial position of all of the target individuals will be set to the given point.  Alternatively, if position contains one point per target individual (i.e., is equal in length to the number of individuals multiplied by the spatial dimensionality of the model), the spatial position of each target individual will be set to the corresponding point from position (where the point data is concatenated, not interleaved, just as it would be returned by accessing the spatialPosition property on the vector of target individuals).  Calling this method with a position vector of any other length is an error.

 (float$)sumOfMutationsOfType(io<MutationType>$ mutType)

Returns the sum of the selection coefficients of all mutations that are of the type specified by mutType, out of all of the mutations in the genomes of the individual.  This is often useful in models that use a particular mutation type to represent QTLs with additive effects; in that context, sumOfMutationsOfType() will provide the sum of the additive effects of the QTLs for the given mutation type.  This method is provided for speed; it is much faster than the corresponding Eidos code.  Note that this method also exists on Genome, for cases in which the sum for just one genome is desired.

 (object<Mutation>)uniqueMutationsOfType(io<MutationType>$ mutType)

Returns an object vector of all the mutations that are of the type specified by mutType, out of all of the mutations in the individual.  Mutations present in both genomes will occur only once in the result of this method, and the mutations will be given in sorted order by position, so this method is similar to sortBy(unique(individual.genomes.mutationsOfType(mutType)), "position").  It is not identical to that call, only because if multiple mutations exist at the exact same position, they may be sorted differently by this method than they would be by sortBy().  If you just need a count of the matching Mutation objects, rather than a vector of the matches, use -countOfMutationsOfType().  This method is provided for speed; it is much faster than the corresponding Eidos code.  Indeed, it is faster than just individual.genomes.mutationsOfType(mutType), and gives uniquing and sorting on top of that, so it is advantageous unless duplicate entries for homozygous mutations are actually needed.

17.7  Class InteractionType

17.7.1  InteractionType properties

id => (integer$)

The identifier for this interaction type; for interaction type i3, for example, this is 3.

maxDistance <–> (float$)

The maximum distance over which this interaction will be evaluated.  For inter-individual distances greater than maxDistance, the interaction strength will be zero.

reciprocal => (logical$)

The reciprocality of the interaction, as specified in initializeInteractionType().  This will be T for reciprocal interactions (those for which the interaction strength of B upon A is equal to the interaction strength of A upon B), and F otherwise.

sexSegregation => (string$)

The sex-segregation of the interaction, as specified in initializeInteractionType().  For non-sexual simulations, this will be "**".  For sexual simulations, this string value indicates the sex of individuals feeling the interaction, and the sex of individuals exerting the interaction; see initializeInteractionType() for details.

spatiality => (string$)

The spatial dimensions used by the interaction, as specified in initializeInteractionType().  This will be "" (the empty string) for non-spatial interactions, or "x", "y", "z", "xy", "xz", "yz", or "xyz", for interactions using those spatial dimensions respectively.  The specified dimensions are used to calculate the distances between individuals for this interaction.  The value of this property is always the same as the value given to initializeInteractionType().

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to interaction types.

17.7.2  InteractionType methods

– (float)distance(object<Individual> individuals1, [No<Individual> individuals2 = NULL])

Returns a vector containing distances between individuals in individuals1 and individuals2.  At least one of individuals1 or individuals2 must be singleton, so that the distances evaluated are either from one individual to many, or from many to one (which are equivalent, in fact); evaluating distances for many to many individuals cannot be done in a single call.  (There is one exception: if both individuals1 and individuals2 are zero-length or NULL, a zero-length float vector will be returned.)  If individuals2 is NULL (the default), then individuals1 must be singleton, and a vector of the distances from that individual to all individuals in its subpopulation (including itself) is returned; this case may be handled differently internally, for greater speed, so supplying NULL is preferable to supplying the vector of all individuals in the subpopulation explicitly even though that should produce identical results.  If the InteractionType is non-spatial, this method may not be called.

Importantly, distances are calculated according to the spatiality of the InteractionType (as declared in initializeInteractionType()), not the dimensionality of the model as a whole (as declared in initializeSLiMOptions()).  The distances returned are therefore the distances that would be used to calculate interaction strengths.  However, distance() will return finite distances for all pairs of individuals, even if the individuals are non-interacting; the distance() between an individual and itself will thus be 0.  See interactionDistance() for an alternative distance definition.

– (float)distanceToPoint(object<Individual> individuals1, float point)

Returns a vector containing distances between individuals in individuals1 and the point given by the spatial coordinates in point.  The point vector is interpreted as providing coordinates precisely as specified by the spatiality of the interaction type; if the interaction type’s spatiality is "xz", for example, then point[0] is assumed to be an x value, and point[1] is assumed to be a z value.  Be careful; this means that in general it is not safe to pass an individual’s spatialPosition property for point, for example (although it is safe if the spatiality of the interaction matches the dimensionality of the simulation).  A coordinate for a periodic spatial dimension must be within the spatial bounds for that dimension, since coordinates outside of periodic bounds are meaningless (pointPeriodic() may be used to ensure this); coordinates for non-periodic spatial dimensions are not restricted.

Importantly, distances are calculated according to the spatiality of the InteractionType (as declared in initializeInteractionType()) not the dimensionality of the model as a whole (as declared in initializeSLiMOptions()).  The distances are therefore interaction distances: the distances that are used to calculate interaction strengths.  If the InteractionType is non-spatial, this method may not be called.  The vector point must be exactly as long as the spatiality of the InteractionType.

– (object<Individual>)drawByStrength(object<Individual>$ individual, [integer$ count = 1])

Returns up to count individuals drawn from the subpopulation of individual.  The probability of drawing particular individuals is proportional to the strength of interaction they exert upon individual.  This method may be used with either spatial or non-spatial interactions, but will be more efficient with spatial interactions that set a short maximum interaction distance.  Draws are done with replacement, so the same individual may be drawn more than once; sometimes using unique() on the result of this call is therefore desirable.  If more than one draw will be needed, it is much more efficient to use a single call to drawByStrength(), rather than drawing individuals one at a time.  Note that if no individuals exert a non-zero interaction upon individual, the vector returned will be zero-length; it is important to consider this possibility.

If the needed interaction strengths have already been calculated, those cached values are simply used.  Otherwise, calling this method triggers evaluation of the needed interactions, including calls to any applicable interaction() callbacks.

– (void)evaluate([Nio<Subpopulation> subpops = NULL], [logical$ immediate = F])

Triggers evaluation of the interaction for the subpopulations specified by subpops (or for all subpopulations, if subpops is NULL).  The subpopulations may be supplied either as integer IDs, or as Subpopulation objects.  By default, the effects of this may be limited, however, since the underlying implementation may choose to postpone some computations lazily.  At a minimum, is it guaranteed that this method will discard all previously cached data for the subpopulation(s), and will cache the current spatial positions of all individuals (so that individuals may then move without disturbing the state of the interaction at the moment of evaluation).  Notably, interaction() callbacks may not be called in response to this method; instead, their evaluation may be deferred until required to satisfy queries (at which point the generation counter may have advanced by one, so be careful with the generation ranges used in defining such callbacks).

If T is passed for immediate, the interaction will immediately and synchronously evaluate all interactions between all individuals in the subpopulation(s), calling any applicable interaction() callbacks as necessary – if the interaction is spatial (see below).  However, depending upon what queries are later executed, this may represent considerable wasted computation.  Immediate evaluation usually generates only a slight performance improvement even if the interactions between all pairs of individuals are eventually accessed; the main reason to choose immediate evaluation, then, is that deferred calculation of interactions would lead to incorrect results due to changes in model state.  For non-spatial interactions, distances and interaction strengths are never cached since such caching would require O(N2) memory and time, which is deemed unacceptable in general; for non-spatial interactions, the immediate parameter is therefore ignored.

You must explicitly call evaluate() at an appropriate time in the life cycle before the interaction is used, but after any relevant changes have been made to the population.  SLiM will invalidate any existing interactions after any portion of the generation cycle in which new individuals have been born or existing individuals have died.  In a WF model, these events occur just before late() events execute (see the WF generation cycle diagram), so late() events are often the appropriate place to put evaluate() calls, but early() events can work too if the interaction is not needed until that point in the generation cycle anyway. In nonWF models, on the other hand, new offspring are produced just before early() events and then individuals die just before late() events (see the nonWF generation cycle diagram), so interactions will be invalidated twice during each generation cycle.  This means that in a nonWF model, an interaction that influences reproduction should usually be evaluated in a first() event, while an interaction that influences fitness or mortality should usually be evaluated in an early() event (and an interaction that affects both may need to be evaluated at both times).

If an interaction is never evaluated for a given subpopulation, it is guaranteed that there will be essentially no memory or computational overhead associated with the interaction for that subpopulation.  Furthermore, attempting to query an interaction for an individual in a subpopulation that has not been evaluated is guaranteed to raise an error.

– (integer)interactingNeighborCount(object<Individual> individuals)

Returns the number of interacting individuals for each individual in individuals, within the maximum interaction distance according to the distance metric of the InteractionType.  More specifically, this method counts the number of individuals which can exert an interaction upon each focal individual; it does not count individuals which only feel an interaction from a focal individual.  This method is similar to nearestInteractingNeighbors() (when passed a large count so as to guarantee that all interacting individuals are returned), but this method returns only a count of the interacting individuals, not a vector containing the individuals.  This method may also be called in a vectorized fashion, with a non-singleton vector of individuals, unlike nearestInteractingNeighbors().

Note that this method uses interaction eligibility as a criterion; it will not count neighbors that cannot exert an interaction upon a focal individual (due to sex-segregation, e.g.).  (It also does not count a focal individual as a neighbor of itself.)

– (float)interactionDistance(object<Individual>$ receiver, [No<Individual> exerters = NULL])

Returns a vector containing interaction-dependent distances between receiver and individuals in exerters that exert an interaction strength upon receiver.  If exerters is NULL (the default), then a vector of the interaction-dependent distances from receiver to all individuals in its subpopulation (including receiver itself) is returned; this case may be handled much more efficiently than if a vector of all individuals in the subpopulation is explicitly provided.  If the InteractionType is non-spatial, this method may not be called.

Importantly, distances are calculated according to the spatiality of the InteractionType (as declared in initializeInteractionType()), not the dimensionality of the model as a whole (as declared in initializeSLiMOptions()).  The distances returned are therefore the distances that would be used to calculate interaction strengths.  In addition, interactionDistance() will return INF as the distance between receiver and any individual which does not exert an interaction upon receiver; the interactionDistance() between an individual and itself will thus be INF, and likewise for pairs excluded from interacting by the sex segregation or max distance of the interaction type.  See distance() for an alternative distance definition.

– (object<Individual>)nearestInteractingNeighbors(object<Individual>$ individual, [integer$ count = 1])

Returns up to count interacting individuals that are spatially closest to individual, according to the distance metric of the InteractionType.  More specifically, this method returns only individuals which can exert an interaction upon the focal individual; it does not include individuals that only feel an interaction from the focal individual.  To obtain all of the interacting individuals within the maximum interaction distance of individual, simply pass a value for count that is greater than or equal to the size of individual’s subpopulation.  Note that if fewer than count interacting individuals are within the maximum interaction distance, the vector returned may be shorter than count, or even zero-length; it is important to check for this possibility even when requesting a single neighbor.  If only the number of interacting individuals is needed, use interactingNeighborCount() instead.

Note that this method uses interaction eligibility as a criterion; it will not return neighbors that cannot exert an interaction upon the focal individual (due to sex-segregation, e.g.).  (It will also never return the focal individual as a neighbor of itself.)  To find all neighbors of the focal individual, whether they can interact with it or not, use nearestNeighbors().

– (object<Individual>)nearestNeighbors(object<Individual>$ individual, [integer$ count = 1])

Returns up to count individuals that are spatially closest to individual, according to the distance metric of the InteractionType.  To obtain all of the individuals within the maximum interaction distance of individual, simply pass a value for count that is greater than or equal to the size of individual’s subpopulation.  Note that if fewer than count individuals are within the maximum interaction distance, the vector returned may be shorter than count, or even zero-length; it is important to check for this possibility even when requesting a single neighbor.

Note that this method does not use interaction eligibility as a criterion; it will return neighbors that could not interact with the focal individual due to sex-segregation.  (It will never return the focal individual as a neighbor of itself, however.)  To find only neighbors that are eligible to exert an interaction upon the focal individual, use nearestInteractingNeighbors().

– (object<Individual>)nearestNeighborsOfPoint(io<Subpopulation>$ subpop, float point, [integer$ count = 1])

Returns up to count individuals in subpop that are spatially closest to point, according to the distance metric of the InteractionType.  The subpopulation may be supplied either as an integer ID, or as a Subpopulation object.  To obtain all of the individuals within the maximum interaction distance of point, simply pass a value for count that is greater than or equal to the size of subpop.  Note that if fewer than count individuals are within the maximum interaction distance, the vector returned may be shorter than count, or even zero-length; it is important to check for this possibility even when requesting a single neighbor.

– (void)setInteractionFunction(string$ functionType, ...)

Set the function used to translate spatial distances into interaction strengths for an interaction type.  The functionType may be "f", in which case the ellipsis ... should supply a numeric$ fixed interaction strength; "l", in which case the ellipsis should supply a numeric$ maximum strength for a linear function; "e", in which case the ellipsis should supply a numeric$ maximum strength and a numeric$ lambda (shape) parameter for a negative exponential function; ; "n", in which case the ellipsis should supply a numeric$ maximum strength and a numeric$ sigma (standard deviation) parameter for a Gaussian function; or "c", in which case the ellipsis should supply a numeric$ maximum strength and a numeric$ scale parameter for a Cauchy distribution function.  Non-spatial interactions must use function type "f", since no distance values are available in that case.

The interaction function for an interaction type is normally a constant in simulations; in any case, it cannot be changed when an interaction has already been evaluated for a given generation of individuals.

– (float)strength(object<Individual>$ receiver, [No<Individual> exerters = NULL])

Returns a vector containing the interaction strengths exerted upon receiver by the individuals in exerters.  If exerters is NULL (the default), then a vector of the interaction strengths exerted by all individuals in the subpopulation of receiver (including receiver itself) is returned; this case may be handled much more efficiently than if a vector of all individuals in the subpopulation is explicitly provided.

If the strengths of interactions exerted by a single individual upon multiple individuals is needed instead (the inverse of what this method provides), multiple calls to this method will be necessary, one per pairwise interaction queried; the interaction engine is not optimized for the inverse case, and so it will likely be quite slow to compute.  If the interaction is reciprocal and sex-symmetric, the opposite query should provide identical results in a single efficient call (because then the interactions exerted are equal to the interactions received); otherwise, the best approach might be to define a second interaction type representing the inverse interaction that you wish to be able to query efficiently.

If the needed interaction strengths have already been calculated, those cached values are simply returned.  Otherwise, calling this method triggers evaluation of the needed interactions, including calls to any applicable interaction() callbacks.

– (float)totalOfNeighborStrengths(object<Individual> individuals)

Returns a vector of the total interaction strength felt by each individual in individuals, which does not need to be a singleton; indeed, it can be a vector of all of the individuals in a given subpopulation.  However, all of the individuals in individuals must be in the same subpopulation.

For one individual, this is essentially the same as calling nearestNeighbors() with a large count so as to obtain the complete vector of all neighbors, calling strength() for each of those interactions to get each interaction strength, and adding those interaction strengths together with sum().  This method is much faster than that implementation, however, since all of that work is done as a single operation.  Also, totalOfNeighborStrengths() can total up interactions for more than one focal individual in a single call.

Similarly, for one individual this is essentially the same as calling strength() to get the interaction strengths between the focal individual and all other individuals, and then calling sum().  Again, this method should be much faster, since this algorithm looks only at neighbors, whereas calling strength() directly assesses interaction strengths with all other individuals.  This will make a particularly large difference when the subpopulation size is large and the maximum distance of the InteractionType is small.

If the needed interaction strengths have already been calculated, those cached values are simply used.  Otherwise, calling this method triggers evaluation of the needed interactions, including calls to any applicable interaction() callbacks.

– (void)unevaluate(void)

Discards all evaluation of this interaction, for all subpopulations.  The state of the InteractionType is reset to a state prior to evaluation.  This can be useful if the model state has changed in such a way that the evaluation already conducted is no longer valid.  For example, if the maximum distance or the interaction function of the InteractionType need to be changed with immediate effect, or if the data used by an interaction() callback has changed in such a way that previously calculated interaction strengths are no longer correct, unevaluate() allows the interaction to begin again from scratch.

In WF models, all interactions are automatically reset to an unevaluated state at the moment when the new offspring generation becomes the parental generation (at step 4 in the generation cycle).

In nonWF models, all interactions are automatically reset to an unevaluated state twice per generation: immediately after reproduction() callbacks have completed (after step 1 in the generation cycle), and immediately before viability/survival selection (before step 4 in the generation cycle).

Given this automatic invalidation, most simulations have no reason to call unevaluate().

24.8  Class LogFile

24.8.1  LogFile properties

filePath => (string$)

The path of the log file being written to.  This may be changed with setFilePath().

logInterval => (integer$)

The interval for automatic logging; a new row of data will be logged every logInterval generations.  This may be changed with setLogInterval().  If automatic logging has been disabled, this property will be 0.

precision <–> (integer$)

The precision of float output.  To be exact, precision specifies the preferred number of significant digits that will be output for float values.  The default is 6; values in [1,22] are legal, but 17 is probably the largest value that makes sense given the limits of double-precision floating point.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.

24.8.2  LogFile methods

– (void)addCustomColumn(string$ columnName, string$ source, [* context = NULL])

Adds a new data column with its name provided by columnName.  The value for the column, when a given row is generated, will be produced by the code supplied in source, which is expected to return either NULL (which will write out NA), or a singleton value of any non-object type.

The context parameter will be set up as a pseudo-parameter, named context, when source is called, allowing the same source code to be used to generate values for multiple data columns; you might, for example, provide the particular Subpopulation object here that you wish source to use for its calculations.  This is optional; if the default value of NULL is used, then context will be NULL when source is called.

See addMeanSDColumns() for a useful variant.

– (void)addGeneration(void)

Adds a new data column that provides the generation number, named generation.

– (void)addGenerationStage(void)

Adds a new data column that provides the generation cycle stage, named gen_stage.  The stage is provided as a string, and will typically be "early", "late", or "end" (the latter used for the point in time at which end-of-generation automatic logging occurs).  Other possible values are discussed in the documentation for the generationStage property of SLiMSim, which this column reflects.

– (void)addKeysAndValuesFrom(object$ source)

This Dictionary method has an override in LogFile to make it illegal to call, since LogFile manages its Dictionary entries.

– (void)addMeanSDColumns(string$ columnName, string$ source, [* context = NULL])

Adds two new data columns with names of columnName_mean and columnName_sd.  When a given row is generated, the code supplied in source is expected to return either a zero-length vector of any type including NULL (which will write out NA to both columns), or a non-zero-length vector of integer or float values.  In the latter case, the result vector will be summarized in the two columns by its mean and standard deviation respectively.  If the result vector has exactly one value, the standard deviation will be written as NA.  The context parameter is set up as a pseudo-parameter when source is called, as described in addCustomColumn().

– (void)addPopulationSexRatio(void)

Adds a new data column that provides the population sex ratio M:(M+F), named sex_ratio.  If the model is hermaphroditic, NA will be written.

– (void)addPopulationSize(void)

Adds a new data column that provides the total population size, named num_individuals.

– (void)addSubpopulationSexRatio(io<Subpopulation>$ subpop)

Adds a new data column that provides the sex ratio M:(M+F) of the subpopulation subpop, named pX_sex_ratio.  If the subpopulation exists but has a size of zero, NA will be written.

– (void)addSubpopulationSize(io<Subpopulation>$ subpop)

Adds a new data column that provides the size of the subpopulation subpop, named pX_num_individuals.  If the subpopulation exists but has a size of zero, 0 will be written.

– (void)clearKeysAndValues(void)

This Dictionary method has an override in LogFile to make it illegal to call, since LogFile manages its Dictionary entries.

– (void)flush(void)

Flushes all buffered data to the output file, synchronously.  This will make the contents of the file on disk be up-to-date with the running simulation.  Flushing frequently may entail a small performance penalty.  More importantly, if .gz compression has been requested with compress=T the size of the resulting file will be larger – potentially much larger – if flush() is called frequently.  Note that automatic periodic flushing can be requested with the flushInterval parameter to createLogFile().

– (void)logRow(void)

This logs a new row of data, by evaluating all of the generators added to the LogFile with add...() calls.  Note that the new row may be buffered, and thus may not be written out to disk immediately; see flush().  This method may be used instead of, or in conjunction with, automatic logging.

You can get the LogFile instance, in order to call logRow() on it, from sim.logFiles, or you can remember it in a global constant with defineConstant().

– (void)setLogInterval([Ni$ logInterval = NULL])

Sets the automatic logging interval.  A logInterval of NULL stops automatic logging immediately.  Other values request that a new row should be logged (as if logRow() were called) at the end of every logInterval generations (just before the generation count increment, in both WF and nonWF models), starting at the end of the generation in which setLogInterval() was called.

– (void)setFilePath(string$ filePath, [Ns initialContents = NULL], [logical$ append = F], [Nl$ compress = NULL], [Ns$ sep = NULL])

Redirects the LogFile to write new rows to a new filePath.  Any rows that have been buffered but not flushed will be written to the previous file first, as if flush() had been called.  With this call, new initialContents may be supplied, which will either replace any existing file or will be appended to it, depending upon the value of append.  New values may be supplied for compress and sep; the meaning of these parameters is identical to their meaning in createLogFile(), except that a value of NULL for these means “do not change this setting from its previous value”.  In effect, then, this method lets you start a completely new log file at a new path, without having to create and configure a new LogFile object.  The new file will be created (or appended) synchronously, with the specified initial contents.

– (void)setValue(string$ key, * value)

This Dictionary method has an override in LogFile to make it illegal to call, since LogFile manages its Dictionary entries.

5.8  Class Mutation

5.8.1  Mutation properties

id => (integer$)

The identifier for this mutation.  Each mutation created during a run receives an immutable identifier that will be unique across the duration of the run.  These identifiers are not re-used during a run, except that if a population file is loaded from disk, the loaded mutations will receive their original identifier values as saved in the population file.

isFixed => (logical$)

T if the mutation has fixed (in the SLiM sense of having been converted to a Substitution object), F otherwise.  Since fixed/substituted mutations are removed from the simulation, you will only see this flag be T if you have held onto a mutation beyond its usual lifetime.

isSegregating => (logical$)

T if the mutation is segregating (in the SLiM sense of not having been either lost or converted to a Substitution object), F otherwise.  Since both lost and fixed/substituted mutations are removed from the simulation, you will only see this flag be F if you have held onto a mutation beyond its usual lifetime.  Note that if isSegregating is F, isFixed will let you determine whether the mutation is no longer segregating because it was lost, or because it fixed.

mutationType => (object<MutationType>$)

The MutationType from which this mutation was drawn.

nucleotide <–> (string$)

A string representing the nucleotide associated with this mutation; this will be "A", "C", "G", or "T".  If the mutation is not nucleotide-based, this property is unavailable.

nucleotideValue <–> (integer$)

An integer representing the nucleotide associated with this mutation; this will be 0 (A), 1 (C), 2 (G), or 3 (T).  If the mutation is not nucleotide-based, this property is unavailable.

originGeneration => (integer$)

The generation in which this mutation arose.

position => (integer$)

The position in the chromosome of this mutation.

selectionCoeff => (float$)

The selection coefficient of the mutation, drawn from the distribution of fitness effects of its MutationType.  If a mutation has a selectionCoeff of s, the multiplicative fitness effect of the mutation in a homozygote is 1+s; in a heterozygote it is 1+hs, where h is the dominance coefficient kept by the mutation type.

Note that this property has a quirk: it is stored internally in SLiM using a single-precision float, not the double-precision float type normally used by Eidos.  This means that if you set a mutation mut’s selection coefficient to some number x, mut.selectionCoeff==x may be F due to floating-point rounding error.  Comparisons of floating-point numbers for exact equality is often a bad idea, but this is one case where it may fail unexpectedly.  Instead, it is recommended to use the id or tag properties to identify particular mutations.

subpopID <–> (integer$)

The identifier of the subpopulation in which this mutation arose.  This property can be used to track the ancestry of mutations through their subpopulation of origin.

If you don’t care which subpopulation a mutation originated in, the subpopID may be used as an arbitrary integer “tag” value for any purpose you wish; SLiM does not do anything with the value of subpopID except propagate it to Substitution objects and report it in output.  (It must still be >= 0, however, since SLiM object identifiers are limited to nonnegative integers).

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.

5.8.2  Mutation methods

– (void)setMutationType(io<MutationType>$ mutType)

Set the mutation type of the mutation to mutType (which may be specified as either an integer identifier or a MutationType object).  This implicitly changes the dominance coefficient of the mutation to that of the new mutation type, since the dominance coefficient is a property of the mutation type.  On the other hand, the selection coefficient of the mutation is not changed, since it is a property of the mutation object itself; it can be changed explicitly using the setSelectionCoeff() method if so desired.

The mutation type of a mutation is normally a constant in simulations, so be sure you know what you are doing.  Changing this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

In nucleotide-based models, a restriction applies: nucleotide-based mutations may not be changed to a non-nucleotide-based mutation type, and non-nucleotide-based mutations may not be changed to a nucleotide-based mutation type.

– (void)setSelectionCoeff(float$ selectionCoeff)

Set the selection coefficient of the mutation to selectionCoeff.  The selection coefficient will be changed for all individuals that possess the mutation, since they all share a single Mutation object (note that the dominance coefficient will remain unchanged, as it is determined by the mutation type).

This is normally a constant in simulations, so be sure you know what you are doing; often setting up a fitness() callback is preferable, in order to modify the selection coefficient in a more limited and controlled fashion.  Changing this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

5.9  Class MutationType

5.9.1  MutationType properties

color <–> (string$)

The color used to display mutations of this type in SLiMgui.  Outside of SLiMgui, this property still exists, but is not used by SLiM.  Colors may be specified by name, or with hexadecimal RGB values of the form "#RRGGBB".  If color is the empty string, "", SLiMgui’s default (selection-coefficient–based) color scheme is used; this is the default for new MutationType objects.

colorSubstitution <–> (string$)

The color used to display substitutions of this type in SLiMgui (see the discussion for the colorSubstitution property of the Chromosome class for details).  Outside of SLiMgui, this property still exists, but is not used by SLiM.  Colors may be specified by name, or with hexadecimal RGB values of the form "#RRGGBB".  If colorSubstitution is the empty string, "", SLiMgui’s default (selection-coefficient–based) color scheme is used; this is the default for new MutationType objects.

convertToSubstitution <–> (logical$)

This property governs whether mutations of this mutation type will be converted to Substitution objects when they reach fixation.

In WF models this property is T by default, since conversion to Substitution objects provides large speed benefits; it should be set to F only if necessary, and only on the mutation types for which it is necessary.  This might be needed, for example, if you are using a fitness() callback to implement an epistatic relationship between mutations; a mutation epistatically influencing the fitness of other mutations through a fitness() callback would need to continue having that influence even after reaching fixation, but if the simulation were to replace the fixed mutation with a Substitution object the mutation would no longer be considered in fitness calculations (unless the callback explicitly consulted the list of Substitution objects kept by the simulation).  Other script-defined behaviors in fitness(), interaction(), mateChoice(), modifyChild(), and recombination() callbacks might also necessitate the disabling of substitution for a given mutation type; this is an important consideration to keep in mind.

In contrast, for nonWF models this property is F by default, because even mutations with no epistatis or other indirect fitness effects will continue to influence the survival probabilities of individuals.  For nonWF models, only neutral mutation types with no epistasis or other side effects can safely be converted to substitutions upon fixation.  When such a pure-neutral mutation type is defined in a nonWF model, this property should be set to T to tell SLiM that substitution is allowed; this may have very large positive effects on performance, so it is important to remember when modeling background neutral mutations.

SLiM consults this flag at the end of each generation when deciding whether to substitute each fixed mutation.  If this flag is T, all eligible fixed mutations will be converted at the end of the current generation, even if they were previously left unconverted because of the previous value of the flag.  Setting this flag to F will prevent future substitutions, but will not cause any existing Substitution objects to be converted back into Mutation objects.

distributionParams => (fs)

The parameters that configure the chosen distribution of fitness effects.  This will be of type string for DFE type "s", and type float for all other DFE types.

distributionType => (string$)

The type of distribution of fitness effects; one of "f", "g", "e", "n", "w", or "s":

"f" – A fixed fitness effect.  This DFE type has a single parameter, the selection coefficient s to be used by all mutations of the mutation type.

"g" – A gamma-distributed fitness effect.  This DFE type is specified by two parameters, a shape parameter and a mean value.  The gamma distribution from which mutations are drawn is given by the probability density function P(s | α,β= [Γ(α)βα]−1exp(−s/β), where α is the shape parameter, and the specified mean for the distribution is equal to αβ.  Note that this parameterization is the same as for the Eidos function rgamma().  A gamma distribution is often used to model deleterious mutations at functional sites.

"e" – An exponentially-distributed fitness effect.  This DFE type is specified by a single parameter, the mean of the distribution.  The exponential distribution from which mutations are drawn is given by the probability density function P(s | β) = β−1exp(−s/β), where β is the specified mean for the distribution.  This parameterization is the same as for the Eidos function rexp().  An exponential distribution is often used to model beneficial mutations.

"n" – A normally-distributed fitness effect.  This DFE type is specified by two parameters, a mean and a standard deviation.  The normal distribution from which mutations are drawn is given by the probability density function P(s | μ,σ) = (2πσ2)−1/2exp(−(sμ)2/2σ2), where μ is the mean and σ is the standard deviation.  This parameterization is the same as for the Eidos function rnorm().  A normal distribution is often used to model mutations that can be either beneficial or deleterious, since both tails of the distribution are unbounded.

"w" – A Weibull-distributed fitness effect.  This DFE type is specified by a scale parameter and a shape parameter.  The Weibull distribution from which mutations are drawn is given by the probability density function P(s | λ,k) = (k/λk)sk−1exp(−(s/λ)k), where λ is the scale parameter and k is the shape parameter.  This parameterization is the same as for the Eidos function rweibull().  A Weibull distribution is often used to model mutations following extreme-value theory.

"s" – A script-based fitness effect.  This DFE type is specified by a script parameter of type string, specifying an Eidos script to be executed to produce each new selection coefficient.  For example, the script "return rbinom(1);" could be used to generate selection coefficients drawn from a binomial distribution, using the Eidos function rbinom(), even though that mutational distribution is not supported by SLiM directly.  The script must return a singleton float or integer.

Note that these distributions can in principle produce selection coefficients smaller than -1.0. In that case, the mutations will be evaluated as “lethal” by SLiM, and the relative fitness of the individual will be set to 0.0.

dominanceCoeff <–> (float$)

The dominance coefficient used for mutations of this type when heterozygous.  Changing this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

Note that the dominance coefficient is not bounded.  A dominance coefficient greater than 1.0 may be used to achieve an overdominance effect.  By making the selection coefficient very small and the dominance coefficient very large, an overdominance scenario in which both homozygotes have the same fitness may be approximated, to a nearly arbitrary degree of precision.

Note that this property has a quirk: it is stored internally in SLiM using a single-precision float, not the double-precision float type normally used by Eidos.  This means that if you set a mutation type muttype’s dominance coefficient to some number x, muttype.dominanceCoeff==x may be F due to floating-point rounding error.  Comparisons of floating-point numbers for exact equality is often a bad idea, but this is one case where it may fail unexpectedly.  Instead, it is recommended to use the id or tag properties to identify particular mutation types.

haploidDominanceCoeff <–> (float$)

The dominance coefficient used for mutations of this type when they occur opposite a null genome (as in sex-chromosome models and models involving haploids).  This defaults to 1.0, and is used only in models where null genomes are present; the dominanceCoeff property is the dominance coefficient used in most circumstances.  Changing this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

As with the dominanceCoeff property, this is stored internally using a single-precision float; see the documentation for dominanceCoeff for discussion.

id => (integer$)

The identifier for this mutation type; for mutation type m3, for example, this is 3.

mutationStackGroup <–> (integer$)

The group into which this mutation type belongs for purposes of mutation stacking policy.  This is equal to the mutation type’s id by default.  See mutationStackPolicy, below, for discussion.

In nucleotide-based models, the stacking group for nucleotide-based mutation types is always -1, and cannot be changed.  Non-nucleotide-based mutation types may also be set to share the -1 stacking group, if they should participate in the same stacking policy as nucleotide-based mutations, but that would be quite unusual.

mutationStackPolicy <–> (string$)

This property and the mutationStackGroup property together govern whether mutations of this mutation type’s stacking group can “stack” – can occupy the same position in a single individual.  A set of mutation types with the same value for mutationStackGroup is called a “stacking group”, and all mutation types in a given stacking group must have the same mutationStackPolicy value, which defines the stacking behavior of all mutations of the mutation types in the stacking group.  In other words, one stacking group might allow its mutations to stack, while another stacking group might not, but the policy within each stacking group must be unambiguous.

This property is "s" by default, indicating that mutations in this stacking group should be allowed to stack without restriction.  If the policy is set to "f", the first mutation of stacking group at a given site is retained; further mutations of this stacking group at the same site are discarded with no effect.  This can be useful for modeling one-way changes; once a gene is disabled by a premature stop codon, for example, you might wish to assume, for simplicity, that further mutations cannot alter that fact.  If the policy is set to "l", the last mutation of this stacking group at a given site is retained; earlier mutation of this stacking group at the same site are discarded.  This can be useful for modeling an “infinite-alleles” scenario in which every new mutation at a site generates a completely new allele, rather than retaining the previous mutations at the site.

The mutation stacking policy applies only within the given mutation type’s stacking group; mutations of different stacking groups are always allowed to stack in SLiM.  The policy applies to all mutations added to the model after the policy is set, whether those mutations are introduced by calls such as addMutation(), addNewMutation(), or addNewDrawnMutation(), or are added by SLiM’s own mutation-generation machinery.  However, no attempt is made to enforce the policy for mutations already existing at the time the policy is set; typically, therefore, the policy is set in an initialize() callback so that it applies throughout the simulation.  The policy is also not enforced upon the mutations loaded from a file with readFromPopulationFile(); such mutations were governed by whatever stacking policy was in effect when the population file was generated.

In nucleotide-based models, the stacking policy for nucleotide-based mutation types is always "l", and cannot be changed.  This ensures that new nucleotide mutations always replace the previous nucleotide at a site, and that more than one nucleotide mutation is never present at the same position in a single genome.

nucleotideBased => (logical$)

If the mutation type was created with initializeMutationType(), it is not nucleotide-based, and this property is F.  If it was created with initializeMutationTypeNuc(), it is nucleotide-based, and this property is T.  See those methods for further discussion.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to mutation types.

5.9.2  MutationType methods

– (float)drawSelectionCoefficient([integer$ n = 1])

Draws and returns a vector of n selection coefficients using the currently defined distribution of fitness effects (DFE) for the target mutation type.  If the DFE is type "s", this method will result in synchronous execution of the DFE’s script.

– (void)setDistribution(string$ distributionType, ...)

Set the distribution of fitness effects for a mutation type.  The distributionType may be "f", in which case the ellipsis ... should supply a numeric$ fixed selection coefficient; "e", in which case the ellipsis should supply a numeric$ mean selection coefficient for the exponential distribution; "g", in which case the ellipsis should supply a numeric$ mean selection coefficient and a numeric$ alpha shape parameter for a gamma distribution; "n", in which case the ellipsis should supply a numeric$ mean selection coefficient and a numeric$ sigma (standard deviation) parameter for a normal distribution; "w", in which case the ellipsis should supply a numeric$ λ scale parameter and a numeric$ k shape parameter for a Weibull distribution; or "s", in which case the ellipsis should supply a string$ Eidos script parameter.  The DFE for a mutation type is normally a constant in simulations, so be sure you know what you are doing.

5.10  Class SLiMEidosBlock

5.10.1  SLiMEidosBlock properties

active <–> (integer$)

If this evaluates to logical F (i.e., is equal to 0), the script block is inactive and will not be called.  The value of active for all registered script blocks is reset to -1 at the beginning of each generation, prior to script events being called, thus activating all blocks.  Any integer value other than -1 may be used instead of -1 to represent that a block is active; for example, active may be used as a counter to make a block execute a fixed number of times in each generation.  This value is not cached by SLiM; if it is changed, the new value takes effect immediately.  For example, a callback might be activated and inactivated repeatedly during a single generation.

end => (integer$)

The last generation in which the script block is active.

id => (integer$)

The identifier for this script block; for script s3, for example, this is 3.  A script block for which no id was given will have an id of -1.

source => (string$)

The source code string of the script block.

start => (integer$)

The first generation in which the script block is active.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.

type => (string$)

The type of the script block; this will be "early" or "late" for the two types of Eidos events, or "initialize", "fitness", "mateChoice", "modifyChild", or "recombination" for the respective types of Eidos callbacks.

5.10.2  SLiMEidosBlock methods


5.11  Class SLiMgui

5.11.1  SLiMgui properties

pid => (integer$)

The Un*x process identifier (commonly called the “pid”) of the running SLiMgui application.  This can be useful for scripts that wish to use system calls to influence the SLiMgui application.

5.11.2  SLiMgui methods

– (void)openDocument(string$ filePath)

Open the document at filePath in SLiMgui, if possible.  Supported document types include SLiM model files (typically with a .slim path extension), text files (typically with a .txt path extension, and opened as untitled model files), and PNG, JPG/JPEG, BMP, and GIF image file formats (typically .png / .jpg / .jpeg / .bmp / .gif, respectively).  (Note that in SLiMguiLegacy, PDF files (.pdf) are supported but these other image file formats are not.)  This method can be particularly useful for opening images created by the simulation itself, often by sublaunching a plotting process in R or another environment.

– (void)pauseExecution(void)

Pauses a model that is playing in SLiMgui.  This is essentially equivalent to clicking the “Play” button to stop the execution of the model.  Execution can be resumed by the user, by clicking the “Play” button again; unlike calling stop() or simulationFinished(), the simulation is not terminated.  This method can be useful for debugging or exploratory purposes, to pause the model at a point of interest.  Execution is paused at the end of the currently executing generation, not mid-generation.

If the model is being profiled, or is executing forward to a generation number entered in the generation field, pauseExecution() will do nothing; by design, pauseExecution() only pauses execution when SLiMgui is doing a simple “Play” of the model.

5.12  Class SLiMSim

5.12.1  SLiMSim properties

chromosome => (object<Chromosome>$)

The Chromosome object used by the simulation.

chromosomeType => (string$)

The type of chromosome being simulated; this will be one of "A", "X", or "Y".

dimensionality => (string$)

The spatial dimensionality of the simulation, as specified in initializeSLiMOptions().  This will be "" (the empty string) for non-spatial simulations (the default), or "x", "xy", or "xyz", for simulations using those spatial dimensions respectively.

dominanceCoeffX <–> (float$)

This property has been deprecated and removed.  In SLiM 3.7 and later, use the haploidDominanceCoeff property of MutationType instead.

The dominance coefficient value used to modify the selection coefficients of mutations present on the single X chromosome of an XY male (see the SLiM documentation for details).  Used only when simulating an X chromosome; setting a value for this property in other circumstances is an error.  Changing this will normally affect the fitness values calculated at the end of the current generation; if you want current fitness values to be affected, you can call SLiMSim’s method recalculateFitness() – but see the documentation of that method for caveats.

generation <–> (integer$)

The current generation number.

generationStage => (string$)

The current generation stage, as a string.  The values of this property essentially mirror the generation stages of WF and nonWF models (see chapters 22 and 23).  Common values include "first" (during execution of first() events), "early" (during execution of early() events), "reproduction" (during offspring generation), "fitness" (during fitness evaluation), "survival" (while applying selection and mortality in nonWF models), and "late" (during execution of late() events).

Other possible values include "begin" (during internal setup before each generation), ”tally" (while tallying mutation reference counts and removing fixed mutations), "swap" (while swapping the offspring generation into the parental generation in WF models), "end" (during internal bookkeeping after each generation), and "console" (during the in-between-generations state in which commands in SLiMgui’s Eidos console are executed).  It would probably be a good idea not to use this latter set of values; they are probably not user-visible during ordinary model execution anyway.

During execution of initialize() callbacks, no SLiMSim object yet exists and so this property cannot be accessed.  To detect this state, use exists("sim"); if that is F, sim does not exist, and therefore your code is executing during initialize() callbacks (or outside of SLiM entirely, in some other Eidos-based context).

genomicElementTypes => (object<GenomicElementType>)

The GenomicElementType objects being used in the simulation.

inSLiMgui => (logical$)

This property has been deprecated, and may be removed in a future release of SLiM.  In SLiM 3.2.1 and later, use exists("slimgui") instead.

If T, the simulation is presently running inside SLiMgui; if F, it is running at the command line.  In general simulations should not care where they are running, but in special circumstances such as opening plot windows it may be necessary to know the runtime environment.

interactionTypes => (object<InteractionType>)

The InteractionType objects being used in the simulation.

logFiles => (object<LogFile>)

The LogFile objects being used in the simulation.

modelType => (string$)

The type of model being simulated, as specified in initializeSLiMModelType().  This will be "WF" for WF models (Wright-Fisher models, the default), or "nonWF" for nonWF models (non-Wright-Fisher models).

mutationTypes => (object<MutationType>)

The MutationType objects being used in the simulation.

mutations => (object<Mutation>)

The Mutation objects that are currently active in the simulation.

nucleotideBased => (logical$)

If T, the model is nucleotide-based; if F, it is not.  See the discussion of the nucleotideBased parameter to initializeSLiMOptions() for discussion.

periodicity => (string$)

The spatial periodicity of the simulation, as specified in initializeSLiMOptions().  This will be "" (the empty string) for non-spatial simulations and simulations with no periodic spatial dimensions (the default).  Otherwise, it will be a string representing the subset of spatial dimensions that have been declared to be periodic, as specified to initializeSLiMOptions().

scriptBlocks => (object<SLiMEidosBlock>)

All registered SLiMEidosBlock objects in the simulation.

sexEnabled => (logical$)

If T, sex is enabled in the simulation; if F, individuals are hermaphroditic.

subpopulations => (object<Subpopulation>)

The Subpopulation instances currently defined in the simulation.

substitutions => (object<Substitution>)

A vector of Substitution objects, representing all mutations that have been fixed.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to the simulation.

verbosity <–> (integer$)

The verbosity level, for SLiM’s logging of information about the simulation.  This is 1 by default, but can be changed at the command line with the -l[ong] option.  It is provided here so that scripts can consult it to govern the level of verbosity of their own output, or set the verbosity level for particular sections of their code.  A verbosity level of 0 suppresses most of SLiM’s optional output; 2 adds some extra output beyond SLiM’s standard output.  See sections 19.3 and 20.4 for more information.

5.12.2  SLiMSim methods

– (object<Subpopulation>$)addSubpop(is$ subpopID, integer$ size, [float$ sexRatio = 0.5], [logical$ haploid = F])

Add a new subpopulation with id subpopID and size individuals (see the SLiM manual for further details).  The subpopID parameter may be either an integer giving the ID of the new subpopulation, or a string giving the name of the new subpopulation (such as "p5" to specify an ID of 5).  Only if sex is enabled in the simulation, the initial sex ratio may optionally be specified as sexRatio (as the male fraction, M:M+F); if it is not specified, a default of 0.5 is used.  The new subpopulation will be defined as a global variable immediately by this method, and will also be returned by this method.  Subpopulations added by this method will initially consist of individuals with empty genomes. In order to model subpopulations that split from an already existing subpopulation, use addSubpopSplit().

Only in nonWF models, the haploid parameter may be T; in this case, the second genome of each new individual will be a null genome, rather than an empty genome.  For even greater control in nonWF models, you can call addSubpop() with an initial size of 0 and then stock the population with new individuals created however you wish in the next generation’s reproduction() callback.

– (object<Subpopulation>$)addSubpopSplit(is$ subpopID, integer$ size, io<Subpopulation>$ sourceSubpop, [float$ sexRatio = 0.5])

Split off a new subpopulation with id subpopID and size individuals derived from subpopulation sourceSubpop (see the SLiM manual for further details).  The subpopID parameter may be either an integer giving the ID of the new subpopulation, or a string giving the name of the new subpopulation (such as "p5" to specify an ID of 5).  The sourceSubpop parameter may specify the source subpopulation either as a Subpopulation object or by integer identifier.  Only if sex is enabled in the simulation, the initial sex ratio may optionally be specified as sexRatio (as the male fraction, M:M+F); if it is not specified, a default of 0.5 is used.  The new subpopulation will be defined as a global variable immediately by this method, and will also be returned by this method.

– (integer$)countOfMutationsOfType(io<MutationType>$ mutType)

Returns the number of mutations that are of the type specified by mutType, out of all of the mutations that are currently active in the simulation.  If you need a vector of the matching Mutation objects, rather than just a count, use -mutationsOfType().  This method is often used to determine whether an introduced mutation is still active (as opposed to being either lost or fixed).  This method is provided for speed; it is much faster than the corresponding Eidos code.

– (object<LogFile>$)createLogFile(string$ filePath, [Ns initialContents = NULL], [logical$ append = F], [logical$ compress = F], [string$ sep = ","], [Ni$ logInterval = NULL], [Ni$ flushInterval = NULL])

Creates and returns a new LogFile object that logs data from the simulation (see the documentation for the LogFile class for details).  Logged data will be written to the file at filePath, overwriting any existing file at that path by default, or appending to it instead if append is T (successive rows of the log table will always be appended to the previously written content, of course).  Before the header line for the log is written out, any string elements in initialContents will be written first, separated by newlines, allowing for a user-defined file header.  If compress is T, the contents will be compressed with zlib as they are written, and the standard .gz extension for gzip-compressed files will be appended to the filename in filePath if it is not already present.

The sep parameter specifies the separator between data values within a row.  The default of "," will generate a “comma-separated value” (CSV) file, while passing sep="\t" will use a tab separator instead to generate a “tab-separated value” (TSV) file.  Other values for sep may also be used, but are less standard.

LogTable supports periodic automatic logging of a new row of data, enabled by supplying a non-NULL value for logInterval.  In this case, a new row will be logged (as if logRow() were called on the LogFile) at the end of every logInterval generations (just before the generation counter increments, in both WF and nonWF models), starting at the end of the generation in which the LogFile was created.  A logInterval of 1 will cause automatic logging at the end of every generation, whereas a logInterval of NULL disables automatic logging.  Automatic logging can always be disabled or reconfigured later with the LogFile method setLogInterval(), or logging can be triggered manually by calling logRow().

When compression is enabled, LogFile flushes new data lazily by default, for performance reasons, buffering data for multiple rows before writing to disk.  Passing a non-NULL value for flushInterval requests a flush every flushInterval rows (with a value of 1 providing unbuffered operation).  Note that flushing very frequently will likely result in both lower performance and a larger final file size (in one simple test, 48943 bytes instead of 4280 bytes, or more than a 10× increase in size).  Alternatively, passing a very large value for flushInterval 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).  In any case, the log file will be created immediately, with its requested initial contents; the initial write is not buffered.  When compression is not enabled, the flushInterval setting is ignored.

The LogFile documentation discusses how to configure and use LogFile to write out the data you are interested in from your simulation.

– (void)deregisterScriptBlock(io<SLiMEidosBlock> scriptBlocks)

All SLiMEidosBlock objects specified by scriptBlocks (either with SLiMEidosBlock objects or with integer identifiers) will be scheduled for deregistration.  The deregistered blocks remain valid, and may even still be executed in the current stage of the current generation; the blocks are not actually deregistered and deallocated until sometime after the currently executing script block has completed.  To immediately prevent a script block from executing, even when it is scheduled to execute in the current stage of the current generation, use the active property of the script block.

– (object<Individual>)individualsWithPedigreeIDs(integer pedigreeIDs, [Nio<Subpopulation> subpops = NULL])

Looks up individuals by pedigree ID, optionally within specific subpopulations.  Pedigree tracking must be turned on with initializeSLiMOptions(keepPedigrees=T) to use this method, otherwise an error will result.  This method is vectorized; more than one pedigree id may be passed in pedigreeID, in which case the returned vector will contain all of the individuals for which a match was found (in the same order in which they were supplied).  If a given id is not found, the returned vector will contain no entry for that id (so the length of the returned vector may not match the length of pedigreeIDs).  If none of the given ids were found, the returned vector will be object<Individual>(0), an empty object vector of class Individual.  If you have more than one pedigree ID to look up, calling this method just once, in vectorized fashion, may be much faster than calling it once for each ID, due to internal optimizations.

To find individuals within all subpopulations, pass the default of NULL for subpops.  If you are interested only in matches within a specific subpopulation, pass that subpopulation for subpops; that will make the search faster.  Similarly, if you know that a particular subpopulation is the most likely to contain matches, you should supply that subpopulation first in the subpops vector so that it will be searched first; the supplied subpopulations are searched in order.  Subpopulations may be supplied either as integer IDs, or as Subpopulation objects.

– (integer)mutationCounts(Nio<Subpopulation> subpops, [No<Mutation> mutations = NULL])

Return an integer vector with the frequency counts of all of the Mutation objects passed in mutations, within the Subpopulation objects in subpops.  The subpops argument is required, but you may pass NULL to get population-wide frequency counts.  Subpopulations may be supplied either as integer IDs, or as Subpopulation objects.  If the optional mutations argument is NULL (the default), frequency counts will be returned for all of the active Mutation objects in the simulation – the same Mutation objects, and in the same order, as would be returned by the mutations property of sim, in other words.

See the -mutationFrequencies() method to obtain float frequencies instead of integer counts.  See also the Genome methods mutationCountsInGenomes() and mutationFrequenciesInGenomes().

– (float)mutationFrequencies(Nio<Subpopulation> subpops, [No<Mutation> mutations = NULL])

Return a float vector with the frequencies of all of the Mutation objects passed in mutations, within the Subpopulation objects in subpops.  The subpops argument is required, but you may pass NULL to get population-wide frequencies.  Subpopulations may be supplied either as integer IDs, or as Subpopulation objects.  If the optional mutations argument is NULL (the default), frequencies will be returned for all of the active Mutation objects in the simulation – the same Mutation objects, and in the same order, as would be returned by the mutations property of sim, in other words.

See the -mutationCounts() method to obtain integer counts instead of float frequencies.  See also the Genome methods mutationCountsInGenomes() and mutationFrequenciesInGenomes().

 (object<Mutation>)mutationsOfType(io<MutationType>$ mutType)

Returns an object vector of all the mutations that are of the type specified by mutType, out of all of the mutations that are currently active in the simulation.  If you just need a count of the matching Mutation objects, rather than a vector of the matches, use -countOfMutationsOfType().  This method is often used to look up an introduced mutation at a later point in the simulation, since there is no way to keep persistent references to objects in SLiM.  This method is provided for speed; it is much faster than the corresponding Eidos code.

– (void)outputFixedMutations([Ns$ filePath = NULL], [logical$ append = F])

Output all fixed mutations – all Substitution objects, in other words – in a SLiM native format.  If the optional parameter filePath is NULL (the default), output will be sent to Eidos’s output stream.  Otherwise, output will be sent to the filesystem path specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.  Mutations which have fixed but have not been turned into Substitution objects – typically because convertToSubstitution has been set to F for their mutation type – are not output; they are still considered to be segregating mutations by SLiM.

In SLiM 3.3 and later, the output format includes the nucleotides associated with any nucleotide-based mutations.

Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (void)outputFull([Ns$ filePath = NULL], [logical$ binary = F], [logical$ append = F], [logical$ spatialPositions = T], [logical$ ages = T], [logical$ ancestralNucleotides = T], [logical$ pedigreeIDs = F])

Output the state of the entire population.  If the optional parameter filePath is NULL (the default), output will be sent to Eidos’s output stream.  Otherwise, output will be sent to the filesystem path specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.  When writing to a file, a logical flag, binary, may be supplied as well.  If binary is T, the population state will be written as a binary file instead of a text file (binary data cannot be written to the standard output stream).  The binary file is usually smaller, and in any case will be read much faster than the corresponding text file would be read.  Binary files are not guaranteed to be portable between platforms; in other words, a binary file written on one machine may not be readable on a different machine (but in practice it usually will be, unless the platforms being used are fairly unusual).  If binary is F (the default), a text file will be written.

Beginning with SLiM 2.3, the spatialPositions parameter may be used to control the output of the spatial positions of individuals in simulations for which continuous space has been enabled using the dimensionality option of initializeSLiMOptions().  If spatialPositions is F, the output will not contain spatial positions, and will be identical to the output generated by SLiM 2.1 and later.  If spatialPositions is T, spatial position information will be output if it is available.  If the simulation does not have continuous space enabled, the spatialPositions parameter will be ignored.  Positional information may be output for all output destinations – the Eidos output stream, a text file, or a binary file.

Beginning with SLiM 3.0, the ages parameter may be used to control the output of the ages of individuals in nonWF simulations.  If ages is F, the output will not contain ages, preserving backward compatibility with the output format of SLiM 2.1 and later.  If ages is T, ages will be output for nonWF models.  In WF simulations, the ages parameter will be ignored.

Beginning with SLiM 3.3, the ancestralNucleotides parameter may be used to control the output of the ancestral nucleotide sequence in nucleotide-based models.  If ancestralNucleotides is F, the output will not contain ancestral nucleotide information, and so the ancestral sequence will not be restored correctly if the saved file is loaded with readPopulationFile().  This option is provided because the ancestral sequence may be quite large, for models with a long chromosome (e.g., 1 GB if the chromosome is 109 bases long, when saved in text format, or 0.25 GB when saved in binary format).  If the model is not nucleotide-based (as enabled with the nucleotideBased parameter to initializeSLiMOptions()), the ancestralNucleotides parameter will be ignored.  Note that in nucleotide-based models the output format will always include the nucleotides associated with any nucleotide-based mutations; the ancestralNucleotides flag governs only the ancestral sequence.

Beginning with SLiM 3.5, the pedigreeIDs parameter may be used to request that pedigree IDs be written out (and read in by readFromPopulationFile(), subsequently).  This option is turned off (F) by default, to preserve backward compatibility; if it is turned on (T), different file version values will be used, and backward compatibility with previous versions of SLiM will be lost.  This option may only be used if SLiM’s optional pedigree tracking has been enabled with initializeSLiMOptions(keepPedigrees=T).

Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (void)outputMutations(object<Mutation> mutations, [Ns$ filePath = NULL], [logical$ append = F])

Output all of the given mutations.  This can be used to output all mutations of a given mutation type, for example.  If the optional parameter filePath is NULL (the default), output will be sent to Eidos’s output stream.  Otherwise, output will be sent to the filesystem path specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.

In SLiM 3.3 and later, the output format includes the nucleotides associated with any nucleotide-based mutations.

Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (void)outputUsage(void)

Output the current memory usage of the simulation to Eidos’s output stream.  The specifics of what is printed, and in what format, should not be relied upon as they may change from version to version of SLiM.  This method is primarily useful for understanding where the memory usage of a simulation predominantly resides, for debugging or optimization.  Note that it does not capture all memory usage by the process; rather, it summarizes the memory usage by SLiM and Eidos in directly allocated objects and buffers.  To get the total memory usage of the running process (either current or peak), use the Eidos function usage().

– (integer$)readFromPopulationFile(string$ filePath)

Read from a population initialization file, whether in text or binary format as previously specified to outputFull(), and return the generation counter value represented by the file’s contents (i.e., the generation at which the file was generated).  Although this is most commonly used to set up initial populations (often in an Eidos event set to run in generation 1, immediately after simulation initialization), it may be called in any Eidos event; the current state of all populations will be wiped and replaced by the state in the file at filePath.  All Eidos variables that are of type object and have element type Subpopulation, Genome, Mutation, Individual, or Substitution will be removed as a side effect of this method, since all such variables would refer to objects that no longer exist in the SLiM simulation; if you want to preserve any of that state, you should output it or save it to a file prior to this call.  New symbols will be defined to refer to the new Subpopulation objects loaded from the file.

If the file being read was written by a version of SLiM prior to 2.3, then for backward compatibility fitness values will be calculated immediately for any new subpopulations created by this call, which will trigger the calling of any activated and applicable fitness() callbacks.  When reading files written by SLiM 2.3 or later, fitness values are not calculated as a side effect of this call (because the simulation will often need to evaluate interactions or modify other state prior to doing so).

In SLiM 2.3 and later when using the WF model, calling readFromPopulationFile() from any context other than a late() event causes a warning; calling from a late() event is almost always correct in WF models, so that fitness values can be automatically recalculated by SLiM at the usual time in the generation cycle without the need to force their recalculation (see comments on recalculateFitness()).

In SLiM 3.0 when using the nonWF model, calling readFromPopulationFile() from any context other than an early() event causes a warning; calling from an early() event is almost always correct in nonWF models, so that fitness values can be automatically recalculated by SLiM at the usual time in the generation cycle without the need to force their recalculation (see comments on recalculateFitness()).

As of SLiM 2.1, this method changes the generation counter to the generation read from the file.  If you do not want the generation counter to be changed, you can change it back after reading, by setting sim.generation to whatever value you wish.  Note that restoring a saved past state and running forward again will not yield the same simulation results, because the random number generator’s state will not be the same; to ensure reproducibility from a given time point, setSeed() can be used to establish a new seed value.  Any changes made to the simulation’s structure (mutation types, genomic element types, etc.) will not be wiped and re-established by readFromPopulationFile(); this method loads only the population’s state, not the simulation configuration, so care should be taken to ensure that the simulation structure meshes coherently with the loaded data.

As of SLiM 2.3, this method will read and restore the spatial positions of individuals if that information is present in the output file and the simulation has enabled continuous space (see outputFull() for details).  If spatial positions are present in the output file but the simulation has not enabled continuous space (or the number of spatial dimensions does not match), an error will result.  If the simulation has enabled continuous space but spatial positions are not present in the output file, the spatial positions of the individuals read will be undefined, but an error is not raised.

As of SLiM 3.0, this method will read and restore the ages of individuals if that information is present in the output file and the simulation is based upon the nonWF model.  If ages are present but the simulation uses a WF model, an error will result; the WF model does not use age information.  If ages are not present but the simulation uses a nonWF model, an error will also result; the nonWF model requires age information.

As of SLiM 3.3, this method will restore the nucleotides of nucleotide-based mutations, and will restore the ancestral nucleotide sequence, if that information is present in the output file.  Loading an output file that contains nucleotide information in a non-nucleotide-based model, and vice versa, will produce an error.

As of SLiM 3.5, this method will read and restore the pedigree IDs of individuals and genomes if that information is present in the output file (as requested with outputFull(pedigreeIDs=T)) and if SLiM’s optional pedigree tracking has been enabled with initializeSLiMOptions(keepPedigrees=T).

This method can also be used to read tree-sequence (.trees) files saved by treeSeqOutput() or generated by the Python pyslim package.  When loading a tree sequence, a crosscheck of the loaded data will be performed to ensure that the tree sequence was well-formed and was loaded correctly.  When running a Release build of SLiM, however, this crosscheck will only occur the first time that readFromPopulationFile() is called to load a tree sequence; subsequent calls will not perform this crosscheck, for greater speed when running models that load saved population state many times (such as models that are conditional on fixation).  If you suspect that a tree sequence file might be corrupted or read incorrectly, running a Debug build of SLiM enables crosschecks after every load.

– (void)recalculateFitness([Ni$ generation = NULL])

Force an immediate recalculation of fitness values for all individuals in all subpopulations.  Normally fitness values are calculated at the end of each generation, and those values are cached and used throughout the following generation.  If simulation parameters are changed in script in a way that affects fitness calculations, and if you wish those changes to take effect immediately rather than taking effect at the end of the current generation, you may call recalculateFitness() to force an immediate recalculation and recache.

The optional parameter generation provides the generation for which fitness() callbacks should be selected; if it is NULL (the default), the simulation’s current generation value, sim.generation, is used.  If you call recalculateFitness() in an early() event in a WF model, you may wish this to be sim.generation - 1 in order to utilize the fitness() callbacks for the previous generation, as if the changes that you have made to fitness-influencing parameters were already in effect at the end of the previous generation when the new generation was first created and evaluated (usually it is simpler to just make such changes in a late() event instead, however, in which case calling recalculateFitness() is probably not necessary at all since fitness values will be recalculated immediately afterwards).  Regardless of the value supplied for generation here, sim.generation inside fitness() callbacks will report the true generation number, so if your callbacks consult that parameter in order to create generation-specific fitness effects you will need to handle the discrepancy somehow.  (Similar considerations apply for nonWF models that call recalculateFitness() in a late() event, which is also not advisable in general.)

After this call, the fitness values used for all purposes in SLiM will be the newly calculated values.  Calling this method will trigger the calling of any enabled and applicable fitness() callbacks, so this is quite a heavyweight operation; you should think carefully about what side effects might result (which is why fitness recalculation does not just occur automatically after changes that might affect fitness values).

– (object<SLiMEidosBlock>$)registerEarlyEvent(Nis$ id, string$ source, [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos early() event in the current simulation, with optional start and end generations limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered event is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerFirstEvent(Nis$ id, string$ source, [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos first() event in the current simulation, with optional start and end generations limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered event is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation (see section 25.9 for details).  The new SLiMEidosBlock will be defined as a global variable immediately by this method (see section 24.11), and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerFitnessCallback(Nis$ id, string$ source, Nio<MutationType>$ mutType, [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos fitness() callback in the current simulation, with a required mutation type mutType (which may be an integer mutation type identifier, or NULL to indicate a global fitness() callback), optional subpopulation subpop (which may also be an integer identifier, or NULL, the default, to indicate all subpopulations), and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerInteractionCallback(Nis$ id, string$ source, io<InteractionType>$ intType, [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos interaction() callback in the current simulation, with a required interaction type intType (which may be an integer identifier), optional subpopulation subpop (which may also be an integer identifier, or NULL, the default, to indicate all subpopulations), and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it will be eligible to execute the next time an InteractionType is evaluated.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerLateEvent(Nis$ id, string$ source, [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos late() event in the current simulation, with optional start and end generations limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered event is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerMateChoiceCallback(Nis$ id, string$ source, [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos mateChoice() callback in the current simulation, with optional subpopulation subpop (which may be an integer identifier, or NULL, the default, to indicate all subpopulations) and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerModifyChildCallback(Nis$ id, string$ source, [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos modifyChild() callback in the current simulation, with optional subpopulation subpop (which may be an integer identifier, or NULL, the default, to indicate all subpopulations) and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerMutationCallback(Nis$ id, string$ source, [Nio<MutationType>$ mutType = NULL], [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos mutation() callback in the current simulation, with an optional mutation type mutType (which may be an integer mutation type identifier, or NULL, the default, to indicate all mutation types), optional subpopulation subpop (which may also be an integer identifier, or NULL, the default, to indicate all subpopulations), and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerRecombinationCallback(Nis$ id, string$ source, [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos recombination() callback in the current simulation, with optional subpopulation subpop (which may be an integer identifier, or NULL, the default, to indicate all subpopulations) and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerReproductionCallback(Nis$ id, string$ source, [Nio<Subpopulation>$ subpop = NULL], [Ns$ sex = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos reproduction() callback in the current simulation, with optional subpopulation subpop (which may be an integer identifier, or NULL, the default, to indicate all subpopulations), optional sex-specificity sex (which may be "M" or "F" in sexual simulations to make the callback specific to males or females respectively, or NULL for no sex-specificity), and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>$)registerSurvivalCallback(Nis$ id, string$ source, [Nio<Subpopulation>$ subpop = NULL], [Ni$ start = NULL], [Ni$ end = NULL])

Register a block of Eidos source code, represented as the string singleton source, as an Eidos survival() callback in the current simulation, with optional subpopulation subpop (which may be an integer identifier, or NULL, the default, to indicate all subpopulations) and optional start and end generations all limiting its applicability.  The script block will be given identifier id (specified as an integer, or as a string symbolic name such as "s5"); this may be NULL if there is no need to be able to refer to the block later.  The registered callback is added to the end of the list of registered SLiMEidosBlock objects, and is active immediately; it may be eligible to execute in the current generation.  The new SLiMEidosBlock will be defined as a global variable immediately by this method, and will also be returned by this method.

– (object<SLiMEidosBlock>)rescheduleScriptBlock(io<SLiMEidosBlock>$ block, [Ni$ start = NULL], [Ni$ end = NULL], [Ni generations = NULL])

Reschedule the target script block given by block to execute in a specified set of generations.  The block parameter may be either an integer representing the ID of the desired script block, or a SLiMScriptBlock specified directly.

The first way to specify the generation set is with start and end parameter values; block will then execute from start to end, inclusive.  In this case, block is returned.

The second way to specify the generation set is using the generations parameter; this is more flexible but more complicated.  Since script blocks execute across a contiguous span of generations defined by their start and end properties, this may result in the duplication of block; one script block will be used for each contiguous span of generations in generations.  The block object itself will be rescheduled to cover the first such span, whereas duplicates of block will be created to cover subsequent contiguous spans.  A vector containing all of the script blocks scheduled by this method, including block, will be returned; this vector is guaranteed to be sorted by the (ascending) scheduled execution order of the blocks.  Any duplicates of block created will be given values for the active, source, tag, and type properties equal to the current values for block, but will be given an id of -1 since script block identifiers must be unique; if it is necessary to find the duplicated blocks again later, their tag property should be used.  The vector supplied for generations does not need to be in sorted order, but it must not contain any duplicates.

Because this method can create a large number of duplicate script blocks, it can sometimes be better to handle script block scheduling in other ways.  If an early() event needs to execute every tenth generation over the whole duration of a long model run, for example, it would not be advisable to use a call like sim.rescheduleScriptBlock(s1, generations=seq(10, 100000, 10)) for that purpose, since that would result in thousands of duplicate script blocks.  Instead, it would be preferable to add a test such as if (sim.generation % 10 != 0) return; at the beginning of the event.  It is legal to reschedule a script block while the block is executing; a call like sim.rescheduleScriptBlock(self, sim.generation + 10, sim.generation + 10); made inside a given block would therefore also cause the block to execute every tenth generation, although this sort of self-rescheduling code is probably harder to read, maintain, and debug.

Whichever way of specifying the generation set is used, block may continue to be executed during the current life cycle stage even after it has been rescheduled, unless it is made inactive using its active property, and similarly, the block may not execute during the current life cycle stage if it was not already scheduled to do so.  Rescheduling script blocks during the generation and life cycle stage in which they are executing, or in which they are intended to execute, should be avoided.  Also, script blocks which are open-ended (i.e., with no specified end generation), are not used in determining whether the end of the simulation has been reached (because then the simulation would run forever); if you reschedule a block to be open-ended, and to start after the end of the last closed-ended block, the rescheduled block will therefore not run at all (just as such a block would not run at all in other circumstances, too).

Note that new script blocks can also be created and scheduled using the register...() methods of SLiMSim; by using the same source as a template script block, the template can be duplicated and scheduled for different generations.  In fact, rescheduleScriptBlock() does essentially that internally.

– (void)simulationFinished(void)

Declare the current simulation finished.  Normally SLiM ends a simulation when, at the end of a generation, there are no script events or callbacks registered for any future generation (excluding scripts with no declared end generation).  If you wish to end a simulation before this condition is met, a call to simulationFinished() will cause the current simulation to end at the end of the current generation.  For example, a simulation might self-terminate if a test for a dynamic equilibrium condition is satisfied.  Note that the current generation will finish executing; if you want the simulation to stop immediately, you can use the Eidos method stop(), which raises an error condition.

– (object<Mutation>)subsetMutations([No<Mutation>$ exclude = NULL], [Nio<MutationType>$ mutType = NULL], [Ni$ position = NULL], [Nis$ nucleotide = NULL], [Ni$ tag = NULL], [Ni$ id = NULL])

Returns a vector of mutations subset from the list of all active mutations in the simulation (as would be provided by the mutations property).  The parameters specify constraints upon the subset of mutations that will be returned.  Parameter exclude, if non-NULL, may specify a specific mutation that should not be included (typically the focal mutation in some operation).  Parameter mutType, if non-NULL, may specify a mutation type for the mutations to be returned (as either a MutationType object or an integer identifier).  Parameter position, if non-NULL, may specify a base position for the mutations to be returned.  Parameter nucleotide, if non-NULL, may specify a nucleotide for the mutations to be returned (either as a string, "A" / "C" / "G" / "T", or as an integer, 0 / 1 / 2 / 3 respectively).  Parameter tag, if non-NULL, may specify a tag value for the mutations to be returned.  Parameter id, if non-NULL, may specify a required value for the id property of the mutations to be returned.

This method is shorthand for getting the mutations property of the subpopulation, and then using operator [] to select only mutations with the desired properties; besides being much simpler than the equivalent Eidos code, it is also much faster.  Note that if you only need to select on mutation type, the mutationsOfType() method will be even faster.

– (logical$)treeSeqCoalesced(void)

Returns the coalescence state for the recorded tree sequence at the last simplification.  The returned value is a logical singleton flag, T to indicate that full coalescence was observed at the last tree-sequence simplification (meaning that there is a single ancestral individual that roots all ancestry trees at all sites along the chromosome – although not necessarily the same ancestor at all sites), or F if full coalescence was not observed.  For simple models, reaching coalescence may indicate that the model has reached an equilibrium state, but this may not be true in models that modify the dynamics of the model during execution by changing migration rates, introducing new mutations programmatically, dictating non-random mating, etc., so be careful not to attach more meaning to coalescence than it is due; some models may require burn-in beyond coalescence to reach equilibrium, or may not have an equilibrium state at all.  Also note that some actions by a model, such as adding a new subpopulation, may cause the coalescence state to revert from T back to F (at the next simplification), so a return value of T may not necessarily mean that the model is coalesced at the present moment – only that it was coalesced at the last simplification.

This method may only be called if tree sequence recording has been turned on with initializeTreeSeq(); in addition, checkCoalescence=T must have been supplied to initializeTreeSeq(), so that the necessary work is done during each tree-sequence simplification.  Since this method does not perform coalescence checking itself, but instead simply returns the coalescence state observed at the last simplification, it may be desirable to call treeSeqSimplify() immediately before treeSeqCoalesced() to obtain up-to-date information.  However, the speed penalty of doing this in every generation would be large, and most models do not need this level of precision; usually it is sufficient to know that the model has coalesced, without knowing whether that happened in the current generation or in a recent preceding generation.

– (void)treeSeqOutput(string$ path, [logical$ simplify = T], [logical$ includeModel = T], [No$ metadata = NULL])

Outputs the current tree sequence recording tables to the path specified by path.  This method may only be called if tree sequence recording has been turned on with initializeTreeSeq().  If simplify is T (the default), simplification will be done immediately prior to output; this is almost always desirable, unless a model wishes to avoid simplification entirely.  (Note that if simplification is not done, then all genomes since the last simplification will be marked as samples in the resulting tree sequence.)  A binary tree sequence file will be written to the specified path; a filename extension of .trees is suggested for this type of file.

Normally, the full SLiM script used to generate the tree sequence is written out to the provenance entry of the tree sequence file, to the model subkey of the parameters top-level key.  Supplying F for includeModel suppresses output of the full script.

A Dictionary object containing user-generated metadata may be supplied with the metadata parameter.  If present, this dictionary will be serialized as JSON and attached to the saved tree sequence under a key named user_metadata, within the SLiM key.  If pyslim is used to read the tree sequence in Python, this metadata will automatically be deserialized and made available at ts.metadata["SLiM"]["user_metadata"].  This metadata dictionary is not used by SLiM, or by pyslim, tskit, or msprime; you may use it for any purpose you wish.  Note that metadata may actually be any subclass of Dictionary, such as the SLiMSim simulation object sim, or a LogFile instance.  However, only the keys and values contained by the object’s Dictionary superclass state will be serialized into the metadata; properties of the subclass will be ignored.

– (void)treeSeqRememberIndividuals(object<Individual> individuals, [logical$ permanent = T])

Mark the individuals specified by individuals to be kept across tree sequence table simplification.  This method may only be called if tree sequence recording has been turned on with initializeTreeSeq().  All currently living individuals are always kept across simplification; this method does not need to be called, and indeed should not be called, for that purpose.  Instead, treeSeqRememberIndividuals() allows any individual, including dead individuals, to be kept in the final tree sequence.  Typically this would be used, for example, to keep particular individuals that you wanted to be able to trace ancestry back to in later analysis.  However, this is not the typical usage pattern for tree sequence recording; most models will not need to call this method.

There are two ways to keep individuals across simplification.  If permanent is T (the default), then the specified individuals will be permanently remembered: their genomes will be added to the current sample, and they will always be present in the tree sequence.  Permanently remembering a large number of individuals will, of course, markedly increase memory usage and runtime.

Supplying F for permanent will instead mark the individuals only for (temporary) retention: their genomes will not be added to the sample, and they will appear in the final tree sequence only if one of their genomes is retained across simplification.  In other words, the rule of thumb for retained individuals is simple: if a genome is kept by simplification, the genome’s corresponding individual is kept also, if it is retained.  Note that permanent remembering takes priority; calling this function with permanent=F on an individual that has previously been permanently remembered will not remove it from the sample.

The behavior of simplification for individuals retained with permanent=F depends upon the value of the retainCoalescentOnly flag passed to initializeTreeSeq(); here we will discuss the behavior of that flag in detail.  First of all, genomes are always removed by simplification unless they are (a) part of the final generation, (b) ancestral to the final generation, (c) a genome of a permanently remembered individual, or (d) ancestral to a permanently remembered individual.  If retainCoalescentOnly is T (the default), they are also always removed if they are not a branch point (i.e., a coalescent node or most recent common ancestor) in the tree sequence.  In some cases it may be useful to retain a genome and its associated individual when it is simply an intermediate node in the ancestry (i.e., in the middle of a branch).  This can be enabled by setting retainCoalescentOnly to F in your call to initializeTreeSeq().  In this case, ancestral genomes that are intermediate (“unary nodes”, in tskit parlance) and are within an individual that has been retained using the permanent=F flag here are kept, along with the retained individual itself.  Since setting retainCoalescentOnly to F will prevent the unary nodes for retained individuals from being pruned, simplification may often be unable to prune very much at all from the tree sequence, and memory usage and runtime may increase rapidly.  If you are retaining many individuals, this setting should therefore be used only with caution; it is not necessary if you are purely interested in the most recent common ancestors.  See the pyslim documentation for further discussion of retaining and remembering individuals and the effects of the retainCoalescentOnly flag.

The metadata (age, location, etc) that are stored in the resulting tree sequence are those values present at either (a) the final generation, if the individual is alive at the end of the simulation, or (b) the last time that the individual was remembered, if not.  Calling treeSeqRememberIndividuals() on an individual that is already remembered will cause the archived information about the remembered individual to be updated to reflect the individual’s current state.  A case where this is particularly important is for the spatial location of individuals in continuous-space models.  SLiM automatically remembers the individuals that comprise the first generation of any new subpopulation created with addSubpop(), for easy recapitation and other analysis.  However, since these first-generation individuals are remembered at the moment they are created, their spatial locations have not yet been set up, and will contain garbage – and those garbage values will be archived in their remembered state.  If you need correct spatial locations of first-generation individuals for your post-simulation analysis, you should call treeSeqRememberIndividuals() explicitly on the first generation, after setting spatial locations, to update the archived information with the correct spatial positions.

– (void)treeSeqSimplify(void)

Triggers an immediate simplification of the tree sequence recording tables.  This method may only be called if tree sequence recording has been turned on with initializeTreeSeq().  A call to this method will free up memory being used by entries that are no longer in the ancestral path of any individual within the current sample (currently living individuals, in other words, plus those explicitly added to the sample with treeSeqRememberIndividuals()), but it can also take a significant amount of time.  Typically calling this method is not necessary; the automatic simplification performed occasionally by SLiM should be sufficient for most models.

5.13  Class Subpopulation

5.13.1  Subpopulation properties

cloningRate => (float)

The fraction of children in the next generation that will be produced by cloning (as opposed to biparental mating).  In non-sexual (i.e. hermaphroditic) simulations, this property is a singleton float representing the overall subpopulation cloning rate.  In sexual simulations, this property is a float vector with two values: the cloning rate for females (at index 0) and for males (at index 1).

firstMaleIndex => (integer$)

The index of the first male individual in the subpopulation.  The genomes vector is sorted into females first and males second; firstMaleIndex gives the position of the boundary between those sections.  Note, however, that there are two genomes per diploid individual, and the firstMaleIndex is not premultiplied by 2; you must multiply it by 2 before using it to decide whether a given index into genomes is a genome for a male or a female.  The firstMaleIndex property is also the number of females in the subpopulation, given this design.  For non-sexual (i.e. hermaphroditic) simulations, this property has an undefined value and should not be used.

fitnessScaling <–> (float$)

A float scaling factor applied to the fitness of all individuals in this subpopulation (i.e., the fitness value computed for each individual will be multiplied by this value).  This is primarily of use in nonWF models, where fitness is absolute, rather than in WF models, where fitness is relative (and thus a constant factor multiplied into the fitness of every individual will make no difference); however, it may be used in either type of model.  This provides a simple, fast way to modify the fitness of all individuals in a subpopulation; conceptually it is similar to returning the same fitness effect for all individuals in the subpopulation from a fitness(NULL) callback, but without the complexity and performance overhead of implementing such a callback.  To scale the fitness of individuals by different (individual-specific) factors, see the fitnessScaling property of Individual.

The value of fitnessScaling is reset to 1.0 every generation, so that any scaling factor set lasts for only a single generation.  This reset occurs immediately after fitness values are calculated, in both WF and nonWF models.

genomes => (object<Genome>)

All of the genomes contained by the subpopulation; there are two genomes per diploid individual.

genomesNonNull => (object<Genome>)

All of the genomes contained by the subpopulation, as with the genomes property, if all of them are not null genomes; any null genomes present are excluded from the returned vector.  This is a convenience shorthand, sometimes useful in models that involve null genomes.

id => (integer$)

The identifier for this subpopulation; for subpopulation p3, for example, this is 3.

immigrantSubpopFractions => (float)

The expected value of the fraction of children in the next generation that are immigrants arriving from particular subpopulations.

immigrantSubpopIDs => (integer)

The identifiers of the particular subpopulations from which immigrants will arrive in the next generation.

individualCount => (integer$)

The number of individuals in the subpopulation; one-half of the number of genomes.

individuals => (object<Individual>)

All of the individuals contained by the subpopulation.  Each individual is diploid and thus contains two Genome objects.  See the sampleIndividuals() and subsetIndividuals() for fast ways to get a subset of the individuals in a subpopulation.

lifetimeReproductiveOutput => (integer)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), lifetimeReproductiveOutput contains the value of the Individual property reproductiveOutput for all individuals in the subpopulation that died in the last selection/mortality generation cycle stage (or, for WF models, immediately after reproduction).  This allows access to the lifetime reproductive output of individuals in the subpopulation at the end of their lives.  If pedigree tracking is not on, this property is unavailable.

lifetimeReproductiveOutputF => (integer)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), lifetimeReproductiveOutputF contains the value of the Individual property reproductiveOutput for all female individuals in the subpopulation that died in the last selection/mortality generation cycle stage (or, for WF models, immediately after reproduction).  This property is undefined if separate sexes have not been enabled, or if pedigree tracking is not on.

lifetimeReproductiveOutputM => (integer)

If pedigree tracking is turned on with initializeSLiMOptions(keepPedigrees=T), lifetimeReproductiveOutputM contains the value of the Individual property reproductiveOutput for all male individuals in the subpopulation that died in the last selection/mortality generation cycle stage (or, for WF models, immediately after reproduction).  This property is undefined if separate sexes have not been enabled, or if pedigree tracking is not on.

selfingRate => (float$)

The expected value of the fraction of children in the next generation that will be produced by selfing (as opposed to biparental mating).  Selfing is only possible in non-sexual (i.e. hermaphroditic) simulations; for sexual simulations this property always has a value of 0.0.

sexRatio => (float$)

For sexual simulations, the sex ratio for the subpopulation.  This is defined, in SLiM, as the fraction of the subpopulation that is male; in other words, it is actually the M:(M+F) ratio.  For non-sexual (i.e. hermaphroditic) simulations, this property has an undefined value and should not be used.

spatialBounds => (float)

The spatial boundaries of the subpopulation.  The length of the spatialBounds property depends upon the spatial dimensionality declared with initializeSLiMOptions().  If the spatial dimensionality is zero (as it is by default), the value of this property is float(0) (a zero-length float vector).  Otherwise, minimums are supplied for each coordinate used by the dimensionality of the simulation, followed by maximums for each.  In other words, if the declared dimensionality is "xy", the spatialBounds property will contain values (x0, y0, x1, y1); bounds for the z coordinate will not be included in that case, since that coordinate is not used in the simulation’s dimensionality.  This property cannot be set, but the setSpatialBounds() method may be used to achieve the same thing.

tag <–> (integer$)

A user-defined integer value.  The value of tag is initially undefined, and it is an error to try to read it; if you wish it to have a defined value, you must arrange that yourself by explicitly setting its value prior to using it elsewhere in your code.  The value of tag is not used by SLiM; it is free for you to use.  See also the getValue() and setValue() methods (provided by the Dictionary class; see the Eidos manual), for another way of attaching state to subpopulations.

5.13.2  Subpopulation methods

– (No<Individual>$)addCloned(object<Individual>$ parent)

Generates a new offspring individual from the given parent by clonal reproduction, queues it for addition to the target subpopulation, and returns it.  The new offspring will not be visible as a member of the target subpopulation until the end of the offspring generation life cycle stage.  The subpopulation of parent will be used to locate applicable mutation() and  modifyChild() callbacks governing the generation of the offspring individual.

Note that this method is only for use in nonWF models.  See addCrossed() for further general notes on the addition of new offspring individuals.

– (No<Individual>$)addCrossed(object<Individual>$ parent1, object<Individual>$ parent2, [Nfs$ sex = NULL])

Generates a new offspring individual from the given parents by biparental sexual reproduction, queues it for addition to the target subpopulation, and returns it.  The new offspring will not be visible as a member of the target subpopulation until the end of the offspring generation life cycle stage.  Attempting to use a newly generated offspring individual as a mate, or to reference it as a member of the target subpopulation in any other way, will result in an error.  In most models the returned individual is not used, but it is provided for maximal generality and flexibility.

The new offspring individual is generated from parent1 and parent2 by crossing them.  In sexual models parent1 must be female and parent2 must be male; in hermaphroditic models, parent1 and parent2 are unrestricted.  If parent1 and parent2 are the same individual in a hermaphroditic model, that parent self-fertilizes, or “selfs”, to generate the offspring sexually (note this is not the same as clonal reproduction).  Such selfing is considered “incidental” by addCrossed(), however; if the preventIncidentalSelfing flag of initializeSLiMOptions() is T, supplying the same individual for parent1 and parent2 is an error (you must check for and prevent incidental selfing if you set that flag in a nonWF model).  If non-incidental selfing is desired, addSelfed() should be used instead.

The sex parameter specifies the sex of the offspring.  A value of NULL means “make the default choice”; in non-sexual models it is the only legal value for sex, and does nothing, whereas in sexual models it causes male or female to be chosen with equal probability.  A value of "M" or "F" for sex specifies that the offspring should be male or female, respectively.  Finally, a float value from 0.0 to 1.0 for sex provides the probability that the offspring will be male; a value of 0.0 will produce a female, a value of 1.0 will produce a male, and for intermediate values SLiM will draw the sex of the offspring randomly according to the specified probability.  Unless you wish the bias the sex ratio of offspring, the default value of NULL should generally be used.

Note that any defined, active, and applicable recombination(), mutation(), and modifyChild() callbacks will be called as a side effect of calling this method, before this method even returns.  For recombination() and mutation() callbacks, the subpopulation of the parent that is generating a given gamete is used; for modifyChild() callbacks the situation is more complex.  In most biparental mating events, parent1 and parent2 will belong to the same subpopulation, and modifyChild() callbacks for that subpopulation will be used, just as in WF models.  In certain models (such as models of pollen flow and broadcast spawning), however, biparental mating may occur between parents that are not from the same subpopulation; that is legal in nonWF models, and in that case, modifyChild() callbacks for the subpopulation of parent1 are used (since that is the maternal parent).

If the modifyChild() callback process results in rejection of the proposed child, a new offspring individual will not be generated, and this method will return NULL.  To force the generation of an offspring individual from a given pair of parents, you could loop until addCrossed() succeeds, but note that if your modifyChild() callback rejects all proposed children from those particular parents, your model will then hang, so care must be taken with this approach.  Usually, nonWF models do not force generation of offspring in this manner; rejection of a proposed offspring by a modifyChild() callback typically represents a phenomenon such as post-mating reproductive isolation or lethal genetic incompatibilities that would reduce the expected litter size, so the default behavior is typically desirable.

Note that this method is only for use in nonWF models, in which offspring generation is managed manually by the model script; in such models, addCrossed() must be called only from reproduce() callbacks, and may not be called at any other time.  In WF models, offspring generation is managed automatically by the SLiM core.

– (No<Individual>$)addEmpty([Nfs$ sex = NULL], [Nl$ genome1Null = NULL], [Nl$ genome2Null = NULL])

Generates a new offspring individual with empty genomes (i.e., containing no mutations), queues it for addition to the target subpopulation, and returns it.  The new offspring will not be visible as a member of the target subpopulation until the end of the offspring generation life cycle stage.  No recombination() or mutation() callbacks will be called.  The target subpopulation will be used to locate applicable modifyChild() callbacks governing the generation of the offspring individual (unlike the other addX() methods, because there is no parental individual to reference).  The offspring is considered to have no parents for the purposes of pedigree tracking.  The sex parameter is treated as in addCrossed().

By default – when genome1Null and genome2Null are both NULL – null genomes will be generated instead of empty genomes only in sex-chromosome simulations, where the sex chromosome that is not being simulated is represented by a null genome; otherwise, empty genomes rather than null genomes will be created.  This default behavior can be changed by passing T or F for genome1Null or genome2Null, which will force the corresponding offspring genome to be null (T) or non-null (F).  The behavior in sex-chromosome simulations cannot be changed, since the presence of null genomes there is dictated by sex, but T or F may be passed as long as it matches what SLiM would do anyway.  In all other simulations there is little point in passing F (since that would be the default behavior anyway), but passing T can be used to make one or both genomes be null genomes, which can be useful for, e.g., modeling haploids (for which, by convention, the second genome is usually a null genome in SLiM).

Note that this method is only for use in nonWF models.  See addCrossed() for further general notes on the addition of new offspring individuals.

– (No<Individual>$)addRecombinant(No<Genome>$ strand1, No<Genome>$ strand2, Ni breaks1, No<Genome>$ strand3, No<Genome>$ strand4, Ni breaks2, [Nfs$ sex = NULL])

Generates a new offspring individual from the given parental genomes with the specified crossover breakpoints, queues it for addition to the target subpopulation, and returns it.  The new offspring will not be visible as a member of the target subpopulation until the end of the offspring generation life cycle stage.  The target subpopulation will be used to locate applicable mutation() and modifyChild() callbacks governing the generation of the offspring individual (unlike the other addX() methods, because there are potentially up to four parental individuals to reference); recombination() callbacks will not be called by this method.  This method is an advanced feature; most models will use addCrossed(), addSelfed(), or addCloned() instead.

This method supports several possible configurations for strand1, strand2, and breaks1 (and the same applies for strand3, strand4, and breaks2).  If strand1 and strand2 are both NULL, the corresponding genome in the generated offspring will be empty, as from addEmpty(), with no parental genomes and no added mutations; in this case, breaks1 must be NULL or zero-length.  If strand1 is non-NULL but strand2 is NULL, the corresponding genome in the generated offspring will be a clonal copy of strand1 with mutations added, as from addCloned(); in this case, breaks1 must similarly be NULL or zero-length.  If strand1 and strand2 are both non-NULL, the corresponding genome in the generated offspring will result from recombination between strand1 and strand2 with mutations added, as from addCrossed(), with strand1 being the initial copy strand; copying will switch between strands at each breakpoint in breaks1, which must be non-NULL but need not be sorted or uniqued (SLiM will sort and unique the supplied breakpoints internally).  (It is not currently legal for strand1 to be NULL and strand2 non-NULL; that variant may be assigned some meaning in future.)  Again, this discussion applies equally to strand3, strand4, and breaks2, mutatis mutandis.  Note that when new mutations are generated by addRecombinant(), their subpopID property will be the id of the offspring’s subpopulation, since the parental subpopulation is ambiguous; this behavior differs from the other add...() methods.

The sex parameter is interpreted exactly as in addCrossed(); see that method for discussion.  If the offspring sex is specified in any way (i.e., if sex is non-NULL), the strands provided must be compatible with the sex chosen.  If the offspring sex is not specified (i.e., if sex is NULL), the sex will be inferred from the strands provided where possible (when modeling an X or Y chromosome), or will be chosen randomly otherwise (when modeling autosomes); it will not be inferred from the sex of the individuals possessing the parental strands, even when the reproductive mode is essentially clonal from a single parent, since such inference would be ambiguous in the general case.  Similarly, the offspring is considered to have no parents for the purposes of pedigree tracking, since there may be more than two “parents” in the general case.  When modeling the X or Y, strand1 and strand2 must be X genomes (or NULL), and strand3 and strand4 must both be X genomes or both be Y genomes (or NULL).

These semantics allow several uses for addRecombinant().  When all strands are non-NULL, it is similar to addCrossed() except that the recombination breakpoints are specified explicitly, allowing very precise offspring generation without having to override SLiM’s breakpoint generation with a recombination() callback.  When only strand1 and strand3 are supplied, it is very similar to addCloned(), creating a clonal offspring, except that the two parental genomes need not belong to the same individual (whatever that might mean biologically).  Supplying only strand1 is useful for modeling clonally reproducing haploids; the second genome of every offspring will be kept empty and will not receive new mutations.  For a model of clonally reproducing haploids that undergo horizontal gene transfer (HGT), supplying only strand1 and strand2 will allow HGT from strand2 to replace segments of an otherwise clonal copy of strand1, while the second genome of the generated offspring will again be kept empty; this could be useful for modeling bacterial conjugation, for example.  Other variations are also possible.

Note that gene conversion tracts are not explicitly supported by this method; the breaks vectors provide crossover breakpoints, which may be used to implement crossovers or simple gene conversion tracts.  There is no way to specify complex gene conversion tracts with heteroduplex mismatch repair.

Note that this method is only for use in nonWF models.  See addCrossed() for further general notes on the addition of new offspring individuals.

– (No<Individual>$)addSelfed(object<Individual>$ parent)

Generates a new offspring individual from the given parent by selfing, queues it for addition to the target subpopulation, and returns it.  The new offspring will not be visible as a member of the target subpopulation until the end of the offspring generation life cycle stage.  The subpopulation of parent will be used to locate applicable mutation(), recombination(), and modifyChild() callbacks governing the generation of the offspring individual.

Since selfing requires that parent act as a source of both a male and a female gamete, this method may be called only in hermaphroditic models; calling it in sexual models will result in an error.  This method represents a non-incidental selfing event, so the preventIncidentalSelfing flag of initializeSLiMOptions() has no effect on this method (in contrast to the behavior of addCrossed(), where selfing is assumed to be incidental).

Note that this method is only for use in nonWF models.  See addCrossed() for further general notes on the addition of new offspring individuals.

– (float)cachedFitness(Ni indices)

The fitness values calculated for the individuals at the indices given are returned.  If NULL is passed, fitness values for all individuals in the subpopulation are returned.  The fitness values returned are cached values; fitness() callbacks are therefore not called as a side effect of this method.  It is always an error to call cachedFitness() from inside a fitness() callback, since fitness values are in the middle of being set up.  In WF models, it is also an error to call cachedFitness() from a late() event, because fitness values for the new offspring generation have not yet been calculated and are undefined.  In nonWF models, the population may be a mixture of new and old individuals, so instead, NAN will be returned as the fitness of any new individuals whose fitness has not yet been calculated.  When new subpopulations are first created with addSubpop() or addSubpopSplit(), the fitness of all of the newly created individuals is considered to be 1.0 until fitness values are recalculated.

– (void)configureDisplay([Nf center = NULL], [Nf$ scale = NULL], [Ns$ color = NULL])

This method customizes the display of the subpopulation in SLiMgui’s Population Visualization graph.  When this method is called by a model running outside SLiMgui, it will do nothing except type-checking and bounds-checking its arguments.  When called by a model running in SLiMgui, the position, size, and color of the subpopulation’s displayed circle can be controlled as specified below.

The center parameter sets the coordinates of the center of the subpopulation’s displayed circle; it must be a float vector of length two, such that center[0] provides the x-coordinate and center[1] provides the y-coordinate.  The square central area of the Population Visualization occupies scaled coordinates in [0,1] for both x and y, so the values in center must be within those bounds.  If a value of NULL is provided, SLiMgui’s default center will be used (which currently arranges subpopulations in a circle).

The scale parameter sets a scaling factor to be applied to the radius of the subpopulation’s displayed circle.  The default radius used by SLiMgui is a function of the subpopulation’s number of individuals; this default radius is then multiplied by scale.  If a value of NULL is provided, the default radius will be used; this is equivalent to supplying a scale of 1.0.  Typically the same scale value should be used by all subpopulations, to scale all of their circles up or down uniformly, but that is not required.

The color parameter sets the color to be used for the displayed subpopulation’s circle.  Colors may be specified by name, or with hexadecimal RGB values of the form "#RRGGBB" (see the Eidos manual).  If color is NULL or the empty string, "", SLiMgui’s default (fitness-based) color will be used.

– (void)defineSpatialMap(string$ name, string$ spatiality, numeric values, [logical$ interpolate = F], [Nif valueRange = NULL], [Ns colors = NULL])

Defines a spatial map for the subpopulation.  The map will henceforth be identified by name.  The map uses the spatial dimensions referenced by spatiality, which must be a subset of the dimensions defined for the simulation in initializeSLiMOptions().  Spatiality "x" is permitted for dimensionality "x"; spatiality "x", "y", or "xy" for dimensionality "xy"; and spatiality "x", "y", "z", "xy", "yz", "xz", or "xyz" for dimensionality "xyz".  The spatial map is defined by a grid of values supplied in parameter values.  The remaining optional parameters are described below.

Note that the semantics of this method changed in SLiM 3.5; in particular, the gridSize parameter was removed, and the interpretation of the values parameter changed as described below.  Existing code written prior to SLiM 3.5 will produce an error, due to the removed gridSize parameter, and must be revised carefully to obtain the same result, even if NULL had been passed for gridSize previously.

Beginning in SLiM 3.5, the values parameter must be a vector/matrix/array with the number of dimensions appropriate for the declared spatiality of the map; for example, a map with spatiality "x" would require a (one-dimensional) vector, spatiality "xy" would require a (two-dimensional) matrix, and a map with spatiality of "xyz" would require a three-dimensional array.  (See the Eidos manual for discussion of vectors, matrices, and arrays.)  The data in values is interpreted in such a way that a two-dimensional matrix of values, with (0, 0) at upper left and values by column, is transformed into the format expected by SLiM, with (0, 0) at lower left and values by row; in other words, the two-dimensional matrix as it prints in the Eidos console will match the appearance of the two-dimensional spatial map as seen in SLiMgui.  This is a change in behavior from versions prior to SLiM 3.5; it ensures that images loaded from disk with the Eidos class Image can be used directly as spatial maps, achieving the expected orientation, with no need for transposition or flipping.  If the spatial map is a three-dimensional array, it is read as successive z-axis “planes”, each of which is a two-dimensional matrix that is treated as described above.

Moving on to the other parameters of defineSpatialMap(): if interpolate is F, values across the spatial map are not interpolated; the value at a given point is equal to the nearest value defined by the grid of values specified.  If interpolate is T, values across the spatial map will be interpolated (using linear, bilinear, or trilinear interpolation as appropriate) to produce spatially continuous variation in values.  In either case, the corners of the value grid are exactly aligned with the corners of the spatial boundaries of the subpopulation as specified by setSpatialBoundary(), and the value grid is then stretched across the spatial extent of the subpopulation in such a manner as to produce equal spacing between the values along each dimension.  The setting of interpolation only affects how values between these grid points are calculated: by nearest-neighbor, or by linear interpolation.  Interpolation of spatial maps with periodic boundaries is not handled specially; to ensure that the edges of a periodic spatial map join smoothly, simply ensure that the grid values at the edges of the map are identical, since they will be coincident after periodic wrapping.

The valueRange and colors parameters travel together; either both are unspecified, or both are specified.  They control how map values will be transformed into colors, by SLiMgui and by the spatialMapColor() method.  The valueRange parameter establishes the color-mapped range of spatial map values, as a vector of length two specifying a minimum and maximum; this does not need to match the actual range of values in the map.  The colors parameter then establishes the corresponding colors for values within the interval defined by valueRange: values less than or equal to valueRange[0] will map to colors[0], values greater than or equal to valueRange[1] will map to the last colors value, and intermediate values will shade continuously through the specified vector of colors, with interpolation between adjacent colors to produce a continuous spectrum.  This is much simpler than it sounds in this description; see the recipes in chapter 15 for an illustration of its use.

Note that at present, SLiMgui will only display spatial maps of spatiality "x", "y", or "xy"; the color-mapping parameters will simply be ignored by SLiMgui for other spatiality values (even if the spatiality is a superset of these values; SLiMgui will not attempt to display an "xyz" spatial map, for example, since it has no way to choose which 2D slice through the xyz space it ought to display).  The spatialMapColor() method will return translated color strings for any spatial map, however, even if SLiMgui is unable to display the spatial map.  If there are multiple spatial maps that SLiMgui is capable of displaying, it choose one for display by default, but other maps may be selected from the context menu on the individuals view (with a right-click or control-click).

– (void)outputMSSample(integer$ sampleSize, [logical$ replace = T], [string$ requestedSex = "*"], [Ns$ filePath = NULL], [logical$ append = F], [logical$ filterMonomorphic = F])

Output a random sample from the subpopulation in MS format.  Positions in the output will span the interval [0,1].  A sample of genomes (not entire individuals, note) of size sampleSize from the subpopulation will be output.  The sample may be done either with or without replacement, as specified by replace; the default is to sample with replacement.  A particular sex of individuals may be requested for the sample, for simulations in which sex is enabled, by passing "M" or "F" for requestedSex; passing "*", the default, indicates that genomes from individuals should be selected randomly, without respect to sex.  If the sampling options provided by this method are not adequate, see the outputMS() method of Genome for a more flexible low-level option.

If the optional parameter filePath is NULL (the default), output will be sent to Eidos’s output stream.  Otherwise, output will be sent to the filesystem path specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.

If filterMonomorphic is F (the default), all mutations that are present in the sample will be included in the output.  This means that some mutations may be included that are actually monomorphic within the sample (i.e., that exist in every sampled genome, and are thus apparently fixed).  These may be filtered out with filterMonomorphic = T if desired; note that this option means that some mutations that do exist in the sampled genomes might not be included in the output, simply because they exist in every sampled genome.

See outputSample() and outputVCFSample() for other output formats.  Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (void)outputSample(integer$ sampleSize, [logical$ replace = T], [string$ requestedSex = "*"], [Ns$ filePath = NULL], [logical$ append = F])

Output a random sample from the subpopulation in SLiM’s native format.  A sample of genomes (not entire individuals, note) of size sampleSize from the subpopulation will be output.  The sample may be done either with or without replacement, as specified by replace; the default is to sample with replacement.  A particular sex of individuals may be requested for the sample, for simulations in which sex is enabled, by passing "M" or "F" for requestedSex; passing "*", the default, indicates that genomes from individuals should be selected randomly, without respect to sex.  If the sampling options provided by this method are not adequate, see the output() method of Genome for a more flexible low-level option.

If the optional parameter filePath is NULL (the default), output will be sent to Eidos’s output stream.  Otherwise, output will be sent to the filesystem path specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.

See outputMSSample() and outputVCFSample() for other output formats.  Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (void)outputVCFSample(integer$ sampleSize, [logical$ replace = T], [string$ requestedSex = "*"], [logical$ outputMultiallelics = T], [Ns$ filePath = NULL], [logical$ append = F], [logical$ simplifyNucleotides = F], [logical$ outputNonnucleotides = T])

Output a random sample from the subpopulation in VCF format.  A sample of individuals (not genomes, note – unlike the outputSample() and outputMSSample() methods) of size sampleSize from the subpopulation will be output.  The sample may be done either with or without replacement, as specified by replace; the default is to sample with replacement.  A particular sex of individuals may be requested for the sample, for simulations in which sex is enabled, by passing "M" or "F" for requestedSex; passing "*", the default, indicates that genomes from individuals should be selected randomly, without respect to sex.  If the sampling options provided by this method are not adequate, see the outputVCF() method of Genome for a more flexible low-level option.

If the optional parameter filePath is NULL (the default), output will be sent to Eidos’s output stream.  Otherwise, output will be sent to the filesystem path specified by filePath, overwriting that file if append if F, or appending to the end of it if append is T.

The parameters outputMultiallelics, simplifyNucleotides, and outputNonnucleotides affect the format of the output produced; see the reference documentation for further discussion.

See outputMSSample() and outputSample() for other output formats.  Output is generally done in a late() event, so that the output reflects the state of the simulation at the end of a generation.

– (logical)pointInBounds(float point)

Returns T if point is inside the spatial boundaries of the subpopulation, F otherwise.  For example, for a simulation with "xy" dimensionality, if point contains exactly two values constituting an (x,y) point, the result will be T if and only if ((point[0]>=x0) & (point[0]<=x1) & (point[1]>=y0) & (point[1]<=y1)) given spatial bounds (x0, y0, x1, y1).  This method is useful for implementing absorbing or reprising boundary conditions.  This may only be called in simulations for which continuous space has been enabled with initializeSLiMOptions().

The length of point must be an exact multiple of the dimensionality of the simulation; in other words, point may contain values comprising more than one point.  In this case, a logical vector will be returned in which each element is T if the corresponding point in point is inside the spatial boundaries of the subpopulation, F otherwise.

– (float)pointPeriodic(float point)

Returns a revised version of point that has been brought inside the periodic spatial boundaries of the subpopulation (as specified by the periodicity parameter of initializeSLiMOptions()) by wrapping around periodic spatial boundaries.  In brief, if a coordinate of point lies beyond a periodic spatial boundary, that coordinate is wrapped around the boundary, so that it lies inside the spatial extent by the same magnitude that it previously lay outside, but on the opposite side of the space; in effect, the two edges of the periodic spatial boundary are seamlessly joined.  This is done iteratively until all coordinates lie inside the subpopulation’s periodic boundaries.  Note that non-periodic spatial boundaries are not enforced by this method; they should be enforced using pointReflected(), pointStopped(), or some other means of enforcing boundary constraints (which can be used after pointPeriodic() to bring the remaining coordinates into bounds; coordinates already brought into bounds by pointPeriodic() will be unaffected by those calls).  This method is useful for implementing periodic boundary conditions.  This may only be called in simulations for which continuous space  and at least one periodic spatial dimension have been enabled with initializeSLiMOptions().

The length of point must be an exact multiple of the dimensionality of the simulation; in other words, point may contain values comprising more than one point.  In this case, each point will be processed as described above and a new vector containing all of the processed points will be returned.

– (float)pointReflected(float point)

Returns a revised version of point that has been brought inside the spatial boundaries of the subpopulation by reflection.  In brief, if a coordinate of point lies beyond a spatial boundary, that coordinate is reflected across the boundary, so that it lies inside the boundary by the same magnitude that it previously lay outside the boundary.  This is done iteratively until all coordinates lie inside the subpopulation’s boundaries.  This method is useful for implementing reflecting boundary conditions.  This may only be called in simulations for which continuous space has been enabled with initializeSLiMOptions().

The length of point must be an exact multiple of the dimensionality of the simulation; in other words, point may contain values comprising more than one point.  In this case, each point will be processed as described above and a new vector containing all of the processed points will be returned.

– (float)pointStopped(float point)

Returns a revised version of point that has been brought inside the spatial boundaries of the subpopulation by clamping.  In brief, if a coordinate of point lies beyond a spatial boundary, that coordinate is set to exactly the position of the boundary, so that it lies on the edge of the spatial boundary.  This method is useful for implementing stopping boundary conditions.  This may only be called in simulations for which continuous space has been enabled with initializeSLiMOptions().

The length of point must be an exact multiple of the dimensionality of the simulation; in other words, point may contain values comprising more than one point.  In this case, each point will be processed as described above and a new vector containing all of the processed points will be returned.

– (float)pointUniform([integer$ n = 1])

Returns a new point (or points, for n > 1) generated from uniform draws for each coordinate, within the spatial boundaries of the subpopulation.  The returned vector will contain n points, each comprised of a number of coordinates equal to the dimensionality of the simulation, so it will be of total length n*dimensionality.  This may only be called in simulations for which continuous space has been enabled with initializeSLiMOptions().

– (void)removeSubpopulation(void)

Removes this subpopulation from the model.  The subpopulation is immediately removed from the list of active subpopulations, and the symbol representing the subpopulation is undefined.  The subpopulation object itself remains unchanged until children are next generated (at which point it is deallocated), but it is no longer part of the simulation and should not be used.

Note that this method is only for use in nonWF models, in which there is a distinction between a subpopulation being empty and a subpopulation being removed from the simulation; an empty subpopulation may be re-colonized by migrants, whereas as a removed subpopulation no longer exists at all.  WF models do not make this distinction; when a subpopulation is empty it is automatically removed.  WF models should therefore call setSubpopulationSize(0) instead of this method; setSubpopulationSize() is the standard way for WF models to change the subpopulation size, including to a size of 0.

– (object<Individual>)sampleIndividuals(integer$ size, [logical$ replace = F], [No<Individual>$ exclude = NULL], [Ns$ sex = NULL], [Ni$ tag = NULL], [Ni$ minAge = NULL], [Ni$ maxAge = NULL], [Nl$ migrant = NULL])

Returns a vector of individuals, of size less than or equal to parameter size, sampled from the individuals in the target subpopulation.  Sampling is done without replacement if replace is F (the default), or with replacement if replace is T.  The remaining parameters specify constraints upon the pool of individuals that will be considered candidates for the sampling.  Parameter exclude, if non-NULL, may specify a specific individual that should not be considered a candidate (typically the focal individual in some operation).  Parameter sex, if non-NULL, may specify a sex ("M" or "F") for the individuals to be drawn, in sexual models.  Parameter tag, if non-NULL, may specify a tag value for the individuals to be drawn.  Parameters minAge and maxAge, if non-NULL, may specify a minimum or maximum age for the individuals to be drawn, in nonWF models.  Parameter migrant, if non-NULL, may specify a required value for the migrant property of the individuals to be drawn (so T will require that individuals be migrants, F will require that they not be).  If the candidate pool is smaller than the requested sample size, all eligible candidates will be returned (in randomized order); the result will be a zero-length vector if no eligible candidates exist (unlike sample()).

This method is similar to getting the individuals property of the subpopulation, using operator [] to select only individuals with the desired properties, and then using sample() to sample from that candidate pool.  However, besides being much simpler than the equivalent Eidos code, it is also much faster, and it does not fail if less than the full sample size is available.  See subsetIndividuals() for a similar method that returns a full subset, rather than a sample.

– (void)setCloningRate(numeric rate)

Set the cloning rate of this subpopulation.  The rate is changed to rate, which should be between 0.0 and 1.0, inclusive (see the SLiM manual for further details).  Clonal reproduction can be enabled in both non-sexual (i.e. hermaphroditic) and sexual simulations.  In non-sexual simulations, rate must be a singleton value representing the overall clonal reproduction rate for the subpopulation.  In sexual simulations, rate may be either a singleton (specifying the clonal reproduction rate for both sexes) or a vector containing two numeric values (the female and male cloning rates specified separately, at indices 0 and 1 respectively).  During mating and offspring generation, the probability that any given offspring individual will be generated by cloning – by asexual reproduction without gametes or meiosis – will be equal to the cloning rate (for its sex, in sexual simulations) set in the parental (not the offspring!) subpopulation.

– (void)setMigrationRates(io<Subpopulation> sourceSubpops, numeric rates)

Set the migration rates to this subpopulation from the subpopulations in sourceSubpops to the corresponding rates specified in rates; in other words, rates gives the expected fractions of the children in this subpopulation that will subsequently be generated from parents in the subpopulations sourceSubpops (see the SLiM manual for further details).  This method will only set the migration fractions from the subpopulations given; migration rates from other subpopulations will be left unchanged (explicitly set a zero rate to turn off migration from a given subpopulation).  The type of sourceSubpops may be either integer, specifying subpopulations by identifier, or object, specifying subpopulations directly.

– (void)setSelfingRate(numeric$ rate)

Set the selfing rate of this subpopulation.  The rate is changed to rate, which should be between 0.0 and 1.0, inclusive (see the SLiM manual for further details).  Selfing can only be enabled in non-sexual (i.e. hermaphroditic) simulations.  During mating and offspring generation, the probability that any given offspring individual will be generated by selfing – by self-fertilization via gametes produced by meiosis by a single parent – will be equal to the selfing rate set in the parental (not the offspring!) subpopulation.

– (void)setSexRatio(float$ sexRatio)

Set the sex ratio of this subpopulation to sexRatio.  As defined in SLiM, this is actually the fraction of the subpopulation that is male; in other words, the M:(M+F) ratio.  This will take effect when children are next generated; it does not change the current subpopulation state.  Unlike the selfing rate, the cloning rate, and migration rates, the sex ratio is deterministic: SLiM will generate offspring that exactly satisfy the requested sex ratio (within integer roundoff limits).

– (void)setSpatialBounds(numeric bounds)

Set the spatial boundaries of the subpopulation to bounds.  This method may be called only for simulations in which continuous space has been enabled with initializeSLiMOptions().  The length of bounds must be double the spatial dimensionality, so that it supplies both minimum and maximum values for each coordinate.  More specifically, for a dimensionality of "x", bounds should supply (x0, x1) values; for dimensionality "xy" it should supply (x0, y0, x1, y1) values; and for dimensionality "xyz" it should supply (x0, y0, z0, x1, y1, z1) (in that order).  These boundaries will be used by SLiMgui to calibrate the display of the subpopulation, and will be used by methods such as pointInBounds(), pointReflected(), pointStopped(), and pointUniform().  The default spatial boundaries for all subpopulations span the interval [0,1] in each dimension.  Spatial dimensions that are periodic (as established with the periodicity parameter to initializeSLiMOptions()) must have a minimum coordinate value of 0.0 (a restriction that allows the handling of periodicity to be somewhat more efficient).  The current spatial bounds for the subpopulation may be obtained through the spatialBounds property.

– (void)setSubpopulationSize(integer$ size)

Set the size of this subpopulation to size individuals (see the SLiM manual for further details).  This will take effect when children are next generated; it does not change the current subpopulation state.  Setting a subpopulation to a size of 0 does have some immediate effects that serve to disconnect it from the simulation: the subpopulation is removed from the list of active subpopulations, the subpopulation is removed as a source of migration for all other subpopulations, and the symbol representing the subpopulation is undefined.  In this case, the subpopulation itself remains unchanged until children are next generated (at which point it is deallocated), but it is no longer part of the simulation and should not be used.

 (string)spatialMapColor(string$ name, numeric value)

Looks up the spatial map indicated by name, and uses its color-translation machinery (as defined by the valueRange and colors parameters to defineSpatialMap()) to translate each element of value into a corresponding color string.  If the spatial map does not have color-translation capabilities, an error will result.  See the documentation for defineSpatialMap() for information regarding the details of color translation.  See the Eidos manual for further information on color strings.

– (object<Image>$)spatialMapImage(string$ name, [Ni$ width = NULL], [Ni$ height = NULL], [logical$ centers = F], [logical$ color = T])

Looks up the spatial map indicated by name, and returns an Image object sampled from it.  The image will be width pixels wide and height pixels tall; the intrinsic size of the spatial map itself will be used if one of these parameters is NULL.  The image will be oriented in the same way as it is displayed in SLiMgui (which conceptually entails a transformation from matrix coordinates, which store values by column, to standard image coordinates, which store values by row; see the Eidos manual’s documentation of Image for details).  This method may only be called for 2D spatial maps at present.

The sampling of the spatial map can be done in one of two ways, as controlled by the centers parameter.  If centers is T, a (width+1) × (height+1) grid of lines that delineates width × height rectangular pixels will be overlaid on top of the spatial map, and values will be sampled from the spatial map at the center of each of these pixels.  If centers is F (the default), a width × height grid of lines will be overlaid on top of the spatial map, and values will be sampled from the spatial map at the vertices of the grid.  If interpolation is not enabled for the spatial map, these two options will both recover the original matrix of values used to define the spatial map (assuming, here and below, that width and height are NULL).  If interpolation is enabled for the spatial map, however, centers == F will recover the original values, but will not capture the “typical” value of each pixel in the image; centers == T, on the other hand, will not recover the original values, but will capture the “typical” value of each pixel in the image (i.e., the value at the center of each pixel, as produced by interpolation).  The figures in section 15.11 may be helpful for visualizing the difference between these options; the overlaid grids span the full extent of the spatial map, just as shown in that section.

If color is T (the default), the valueRange and colors parameters supplied to defineSpatialMap() will be used to translate map values to RGB color values as described in the documentation of that method, providing the same appearance as in SLiMgui; of course those parameters must have been supplied, otherwise an error will result.  If color is F, on the other hand, a grayscale image will be produced that directly reflects the map values without color translation.  In this case, this method needs to translate map values, which can have any float value, into grayscale pixel values that are integers in [0, 255].  To do so, the map values are multiplied by 255.0, clamped to [0.0, 255.0], and then rounded to the nearest integer.  This translation scheme essentially assumes that map values are in [0, 1]; for spatial maps that were defined using the floatK channel of a grayscale PNG image, this should recover the original image’s pixel values.  (If a different translation scheme is desired, color=T with the desired valueRange and colors should be used.)

 (float)spatialMapValue(string$ name, float point)

Looks up the spatial map indicated by name, and uses its mapping machinery (as defined by the gridSize, values, and interpolate parameters to defineSpatialMap()) to translate the coordinates of point into a corresponding map value.  The length of point must be equal to the spatiality of the spatial map; in other words, for a spatial map with spatiality "xz", point must be of length 2, specifying the x and z coordinates of the point to be evaluated.  Interpolation will automatically be used if it was enabled for the spatial map.  Point coordinates are clamped into the range defined by the spatial boundaries, even if the spatial boundaries are periodic; use pointPeriodic() to wrap the point coordinates first if desired.  See the documentation for defineSpatialMap() for information regarding the details of value mapping.

Beginning in SLiM 3.3, point may contain more than one point to be looked up.  In this case, the length of point must be an exact multiple of the spatiality of the spatial map; for a spatial map with spatiality "xz", for example, the length of point must be an exact multiple of 2, and successive pairs of elements from point (elements 0 and 1, then elements 2 and 3, etc.) will be taken as the x and z coordinates of the points to be evaluated.  This allows spatialMapValue() to be used in a vectorized fashion.

– (object<Individual>)subsetIndividuals([No<Individual>$ exclude = NULL], [Ns$ sex = NULL], [Ni$ tag = NULL], [Ni$ minAge = NULL], [Ni$ maxAge = NULL], [Nl$ migrant = NULL])

Returns a vector of individuals subset from the individuals in the target subpopulation.  The parameters specify constraints upon the subset of individuals that will be returned.  Parameter exclude, if non-NULL, may specify a specific individual that should not be included (typically the focal individual in some operation).  Parameter sex, if non-NULL, may specify a sex ("M" or "F") for the individuals to be returned, in sexual models.  Parameter tag, if non-NULL, may specify a tag value for the individuals to be returned.  Parameters minAge and maxAge, if non-NULL, may specify a minimum or maximum age for the individuals to be returned, in nonWF models.  Parameter migrant, if non-NULL, may specify a required value for the migrant property of the individuals to be returned (so T will require that individuals be migrants, F will require that they not be).

This method is shorthand for getting the individuals property of the subpopulation, and then using operator [] to select only individuals with the desired properties; besides being much simpler than the equivalent Eidos code, it is also much faster.  See sampleIndividuals() for a similar method that returns a sample taken from a chosen subset of individuals.

– (void)takeMigrants(object<Individual> migrants)

Immediately moves the individuals in migrants to the target subpopulation (removing them from their previous subpopulation).  Individuals in migrants that are already in the target subpopulation are unaffected.  Note that the indices and order of individuals and genomes in both the target and source subpopulations will change unpredictably as a side effect of this method.

Note that this method is only for use in nonWF models, in which migration is managed manually by the model script.  In WF models, migration is managed automatically by the SLiM core based upon the migration rates set for each subpopulation with setMigrationRates().

5.14  Class Substitution

5.14.1  Substitution properties

id => (integer$)

The identifier for this mutation.  Each mutation created during a run receives an immutable identifier that will be unique across the duration of the run, and that identifier is carried over to the Substitution object when the mutation fixes.

fixationGeneration => (integer$)

The generation in which this mutation fixed.

mutationType => (object<MutationType>$)

The MutationType from which this mutation was drawn.

nucleotide <–> (string$)

A string representing the nucleotide associated with this mutation; this will be "A", "C", "G", or "T".  If the mutation is not nucleotide-based, this property is unavailable.

nucleotideValue <–> (integer$)

An integer representing the nucleotide associated with this mutation; this will be 0 (A), 1 (C), 2 (G), or 3 (T).  If the mutation is not nucleotide-based, this property is unavailable.

originGeneration => (integer$)

The generation in which this mutation arose.

position => (integer$)

The position in the chromosome of this mutation.

selectionCoeff => (float$)

The selection coefficient of the mutation, drawn from the distribution of fitness effects of its MutationType.

subpopID <–> (integer$)

The identifier of the subpopulation in which this mutation arose.  This value is carried over from the Mutation object directly; if a “tag” value was used in the Mutation object, that value will carry over to the corresponding Substitution object.  The subpopID in Substitution is a read-write property to allow it to be used as a “tag” in the same way, if the origin subpopulation identifier is not needed.

tag <–> (integer$)

A user-defined integer value.  The value of tag is carried over automatically from the original Mutation object.  Apart from that, the value of tag is not used by SLiM; it is free for you to use.

5.14.2  Substitution methods