Skip to content

Commit

Permalink
implement initializeChromosome()
Browse files Browse the repository at this point in the history
  • Loading branch information
bhaller committed Sep 20, 2024
1 parent 2c1be0d commit bd373a3
Show file tree
Hide file tree
Showing 20 changed files with 1,223 additions and 670 deletions.
105 changes: 65 additions & 40 deletions QtSLiM/help/SLiMHelpFunctions.html

Large diffs are not rendered by default.

201 changes: 200 additions & 1 deletion SLiMgui/SLiMHelpFunctions.rtf
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,206 @@ A utility function,
\f3\i \
\pard\pardeftab720\li720\fi-446\ri720\sb180\sa60\partightenfactor0
\f1\i0\fs18 \cf2 (void)initializeGeneConversion(numeric$\'a0nonCrossoverFraction, numeric$\'a0meanLength, numeric$\'a0simpleConversionFraction, [numeric$\'a0bias\'a0=\'a00], [logical$\'a0redrawLengthsOnFailure\'a0=\'a0F])\
\f1\i0\fs18 \cf2 \kerning1\expnd0\expndtw0 (void)initializeChromosome(integer$\'a0id, integer$\'a0start, integer$\'a0length, [string$\'a0type\'a0=\'a0"A"], [Ns$\'a0symbol\'a0=\'a0NULL], [Ns$\'a0name\'a0=\'a0NULL], [integer$\'a0mutationRuns\'a0=\'a00])\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0

\f2\fs20 \cf2 Calling this function, added in SLiM\'a05, initiates the configuration of a chromosome in the species being initialized. That chromosome is then the \'93focal chromosome\'94 for subsequent genetic initialization functions \'96 specifically, for
\f1\fs18 initializeAncestralNucleotides()
\f2\fs20 ,
\f1\fs18 initializeGeneConversion()
\f2\fs20 ,
\f1\fs18 initializeGenomicElement()
\f2\fs20 ,
\f1\fs18 initializeHotspotMap()
\f2\fs20 ,
\f1\fs18 initializeMutationRate()
\f2\fs20 , and
\f1\fs18 initializeRecombinationRate()
\f2\fs20 . If you wish to call
\f1\fs18 initializeChromosome()
\f2\fs20 at all (which is not required), you must call it
\f3\i before
\f2\i0 calling any of those genetic initialization functions, so that the focal chromosome is created
\f3\i before
\f2\i0 being configured further; otherwise, SLiM will assume that you want a default single-chromosome model, and when
\f1\fs18 initializeChromosome()
\f2\fs20 is called later (contradicting that assumption), an error will result.\
Furthermore, there are some other initialization functions must be called before
\f1\fs18 initializeChromosome()
\f2\fs20 if they are called at all \'96 specifically,
\f1\fs18 initializeSex()
\f2\fs20 ,
\f1\fs18 initializeTreeSeq()
\f2\fs20 ,
\f1\fs18 initializeSpecies()
\f2\fs20 , and
\f1\fs18 initializeSLiMOptions()
\f2\fs20 . This is so that
\f1\fs18 initializeChromosome()
\f2\fs20 knows the context within which the new chromosome is to be created; if these methods have not been called when
\f1\fs18 initializeChromosome()
\f2\fs20 is called, the default context is assumed (non-sexual, no tree-sequence recording, single-species, non-nucleotide-based), and an error will result downstream if one of those functions is later called (indicating that those assumptions might be incorrect).\
The parameters to
\f1\fs18 initializeChromosome()
\f2\fs20 configure the chromosome created. They will be discussed out of order here, because that order of presentation will, I hope, be clearer.\
There are three parameters that in some way identify the chromosome. First, the required
\f1\fs18 id
\f2\fs20 parameter provides an
\f1\fs18 integer
\f2\fs20 identifier for the chromosome, which can be used to look up the chromosome later in the simulation; it can be any non-negative
\f1\fs18 integer
\f2\fs20 value, but must be unique within the species (two chromosomes in the same species cannot have the same
\f1\fs18 id
\f2\fs20 ). Often it is an empirical chromosome number, for convenience and clarity; if modeling human chromosome 7, for example, you might provide
\f1\fs18 7
\f2\fs20 . Second, the
\f1\fs18 symbol
\f2\fs20 parameter provides a
\f1\fs18 string
\f2\fs20 identifier for the chromosome, which can also be used to look up the chromosome later in the simulation. If
\f1\fs18 NULL
\f2\fs20 (the default) is passed for
\f1\fs18 symbol
\f2\fs20 , the chromosome\'92s default
\f1\fs18 symbol
\f2\fs20 value will be the
\f1\fs18 string
\f2\fs20 version of its
\f1\fs18 id
\f2\fs20 (
\f1\fs18 "7"
\f2\fs20 for an
\f1\fs18 id
\f2\fs20 of
\f1\fs18 7
\f2\fs20 , for example). The chromosome\'92s
\f1\fs18 symbol
\f2\fs20 value will be used to identify the chromosome in output \'96 in VCF output, for example, and in SLiMgui. It must be non-empty (not
\f1\fs18 ""
\f2\fs20 ), no more than three characters long, and unique within the species. Third, the
\f1\fs18 name
\f2\fs20 parameter can be any
\f1\fs18 string
\f2\fs20 value; if
\f1\fs18 NULL
\f2\fs20 (the default) is passed, the
\f1\fs18 name
\f2\fs20 value will be
\f1\fs18 ""
\f2\fs20 . The
\f1\fs18 name
\f2\fs20 is not used by SLiM, and can be used in any way you wish.\
There are two parameters that configure the extent of the chromosome, in
\f1\fs18 integer
\f2\fs20 base positions. The
\f1\fs18 start
\f2\fs20 parameter sets the first valid base position in the chromosome. Usually this is simply
\f1\fs18 0
\f2\fs20 , but if, for example, you wish to model a specific subset of an empirical chromosome and match its base positions, you might use a different (non-negative
\f1\fs18 integer
\f2\fs20 ) value. The
\f1\fs18 length
\f2\fs20 parameter sets the length, in base positions, of the chromosome, and must be greater than or equal to
\f1\fs18 1
\f2\fs20 . The last valid base position in the chromosome will be
\f1\fs18 start+length-1
\f2\fs20 . Attempting to add a genomic element or a mutation before the first position or after the last position will raise an error. Similarly, the last position of the chromosome must match the last position specified for recombination, mutation, and hotspot maps for that chromosome, but not all positions on a chromosome have to actually be used in the model (i.e., not all positions must be covered by a genomic element).\
The
\f1\fs18 type
\f2\fs20 parameter specifies the type of chromosome to be created. There are numerous options, and they are somewhat complex. First of all, in hermaphroditic models
\f1\fs18 type
\f2\fs20 will generally be one of:\
\pard\pardeftab720\li907\ri360\sa60\partightenfactor0

\f1\fs18 \cf2 "A"
\f2\fs20 (autosome), the default, specifying a diploid autosomal chromosome. For biparental crosses, each parent generates an offspring haplosome by recombination between that parent\'92s two haplosomes (normal meiosis).\

\f1\fs18 "H"
\f2\fs20 (haploid), specifying a haploid autosomal chromosome. Note that for biparental crosses, the offspring\'92s haplosome for this chromosome would be generated by recombination between the haplosomes of the two parents; for clonal reproduction, it would be generated clonally from the single haplosome of the parent. Other haploid biparental inheritance patterns are supported in sexual models (see below).\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
\cf2 Some sex-chromosome types are supported only in sexual models:\
\pard\pardeftab720\li907\ri360\sa60\partightenfactor0

\f1\fs18 \cf2 "X"
\f2\fs20 (X), specifying an X chromosome that is diploid (XX) in females, haploid (X\'96) in males, as in both the XY and X0 sex-determination systems; note that in males two haplosome objects are still present, the second of which is a null haplosome.\

\f1\fs18 "Y"
\f2\fs20 (Y), specifying a Y chromosome that is haploid (Y) in males, absent (\'96) in females, as in the XY sex-determination system; note that in females a null haplosome object is still present.\

\f1\fs18 "Z"
\f2\fs20 (Z), specifying a Z chromosome that is diploid (ZZ) in males, haploid (Z\'96) in females, as in the ZW sex-determination system; note that in females two haplosome objects are still present, the second of which is a null haplosome.\

\f1\fs18 "W"
\f2\fs20 (W), specifying a W chromosome that is haploid (W) in females, absent (\'96) in males, as in the ZW sex-determination system; note that in males a null haplosome object is still present.\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
\cf2 And there are some haploid chromosome types that are also supported only in sexual models:\
\pard\pardeftab720\li907\ri360\sa60\partightenfactor0

\f1\fs18 \cf2 "HF"
\f2\fs20 (haploid female-inherited), specifying a haploid autosomal chromosome that is inherited by both sexes from the first (female) parent in biparental crosses. This could be used to model mitochondrial DNA, for example, since it is inherited in (approximately) this manner.\

\f1\fs18 "FL"
\f2\fs20 (female line), specifying a haploid autosomal chromosome that is inherited only by females, from the female parent, and is represented by a null haplosome in males. This is similar to type
\f1\fs18 "W"
\f2\fs20 but is not considered a sex chromosome, and could be used for other such genetic elements.\

\f1\fs18 "HM"
\f2\fs20 (haploid male-inherited), specifying a haploid autosomal chromosome that is inherited by both sexes from the second (male) parent in biparental crosses. This could be used to model genetic elements inherited by both sexes through the male line; it might be useful in modeling a UV sex-determination system, for example, depending upon the modeling approach chosen.\

\f1\fs18 "ML"
\f2\fs20 (male line), specifying a haploid autosomal chromosome that is inherited only by males, from the male parent, and is represented by a null haplosome in females. This is similar to type
\f1\fs18 "Y"
\f2\fs20 but is not considered a sex chromosome, and could be used for other such genetic elements.\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
\cf2 Finally, some additional values of
\f1\fs18 type
\f2\fs20 are supported for backward compatibility (not intended for use in new models):\
\pard\pardeftab720\li907\ri360\sa60\partightenfactor0

\f1\fs18 \cf2 "H-"
\f2\fs20 (haploid-null), specifying a haploid autosomal chromosome that is inherited only clonally (and will produce an error if a biparental cross ever occurs in the model), followed by a null haplosome. This mirrors how haploid models were constructed in SLiM prior to SLiM\'a05, for backward compatibility. This is somewhat similar to type
\f1\fs18 "H"
\f2\fs20 except that it keeps a null chromosome in the second slot.\

\f1\fs18 "-Y"
\f2\fs20 (null-Y) specifying a Y chromosome that is haploid (\'96Y) in males, absent (\'96 \'96) in females; note that in males a null haplosome is present as the first haplosome, and in females two null haplosomes are present. This mirrors how models of the Y were constructed in SLiM prior to SLiM 5, and how
\f1\fs18 initializeSex("Y")
\f2\fs20 single-chromosome models still work for backward compatibility. This is the same as type
\f1\fs18 "Y"
\f2\fs20 except that it keeps a null haplosome in the first slot for all individuals.\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0
\cf2 Finally, the
\f1\fs18 mutationRuns
\f2\fs20 parameter specifies how many mutation runs the chromosome should use. If
\f1\fs18 mutationRuns
\f2\fs20 is not
\f1\fs18 0
\f2\fs20 , SLiM will use the value given as the number of mutation runs inside
\f1\fs18 Haplosome
\f2\fs20 objects for the chromosome; if it is
\f1\fs18 0
\f2\fs20 (the default), SLiM will calculate a number of mutation runs that it estimates will work well. Internally, SLiM divides haplosomes into a sequence of consecutive mutation runs, allowing more efficient internal computations. The optimal mutation run length is short enough that each mutation run is relatively unlikely to be modified by mutation/recombination events when inherited, but long enough that each mutation run is likely to contain a relatively large number of mutations; these priorities are in tension, so an intermediate balance between them is generally desirable. The optimal number of mutation runs will depend upon the machine and even the compiler used to build SLiM, so SLiM\'92s default value may not be optimal; for maximal performance it can thus be beneficial to experiment with different values and find the optimal value for the simulation \'96 a process which SLiM can assist with (see section 21.4). Specifying the number of mutation runs is an advanced technique, but in some cases it can improve performance significantly.\
The order in which
\f1\fs18 initializeChromosome()
\f2\fs20 calls are made is generally unimportant, since the chromosomes assort independently of each other anyway, but SLiM will preserve the order in which they were defined for you (for the
\f1\fs18 chromosomes
\f2\fs20 property of Species, for display in SLiMgui, for writing out to VCF, and so forth). All of the above types of chromosomes can be defined any number of times; you can have any number of autosomal chromosomes, for example. In a sexual model you could even have multiple defined X and Y chromosomes \'96 not in the sense of a female being XX, but in the sense of a female being X
\fs13\fsmilli6667 \sub 1
\fs20 \nosupersub X
\fs13\fsmilli6667 \sub 1
\fs20 \nosupersub X
\fs13\fsmilli6667 \sub 2
\fs20 \nosupersub X
\fs13\fsmilli6667 \sub 2
\fs20 \nosupersub , where X
\fs13\fsmilli6667 \sub 1
\fs20 \nosupersub and X
\fs13\fsmilli6667 \sub 2
\fs20 \nosupersub are two different kinds of X chromosome. Similarly, you could define both an X and a Z for a species, if you wish; each would segregate correctly according to the sex of the offspring. In sexual models in SLiM the sex of an offspring is determined randomly or given by the user in script; it is not a function of the sex chromosomes present in the individual, although the sex chromosomes present in the individual will correlate with sex. In other words, SLiM does not know and does not care what sex-determination system the species is using; the chromosomes follow the sex, rather than the sex following the chromosomes. This should allow any sex-determination system to be modeled, even if it is unusual, non-genetic, etc.\
\pard\pardeftab720\li720\fi-446\ri720\sb180\sa60\partightenfactor0

\f1\fs18 \cf2 \expnd0\expndtw0\kerning0
(void)initializeGeneConversion(numeric$\'a0nonCrossoverFraction, numeric$\'a0meanLength, numeric$\'a0simpleConversionFraction, [numeric$\'a0bias\'a0=\'a00], [logical$\'a0redrawLengthsOnFailure\'a0=\'a0F])\
\pard\pardeftab720\li547\ri720\sb60\sa60\partightenfactor0

\f2\fs20 \cf2 Calling this function switches the recombination model from a \'93simple crossover\'94 model to a \'93double-stranded break (DSB)\'94 model, and configures the details of the gene conversion tracts that will therefore be modeled. The fraction of DSBs that will be modeled as non-crossover events is given by
Expand Down
9 changes: 6 additions & 3 deletions VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ development head (in the master branch):
x parameter name changes: calcFST(), calcPairHeterozygosity(), calcHeterozygosity(), calcWattersonsTheta(), calcInbreedingLoad(), calcPi(), calcTajimasD()
x parameter name changes: addEmpty(), addRecombinant()
API additions:
(object<Chromosome>$)initializeChromosome(integer$ id, integer$ start, integer$ length, [string$ type = "A"], [Ns$ symbol = NULL], [Ns$ name = NULL], [integer$ mutationRuns = 0])
initializeSex(): should now allow, and default to, NULL which should be used for all new models; "A" / "X" / "Y" should still be allowed for backward compatibility
x (void)initializeChromosome(integer$ id, integer$ start, integer$ length, [string$ type = "A"], [Ns$ symbol = NULL], [Ns$ name = NULL], [integer$ mutationRuns = 0])
x initializeSex(): should now allow, and default to, NULL which should be used for all new models; "A" / "X" / "Y" should still be allowed for backward compatibility
x Haplosome class:
x property: chromosome => (object<Chromosome>$)
x Chromosome class:
Expand All @@ -60,6 +60,9 @@ development head (in the master branch):
revise recipes for new terminology (but they will require more revision downstream)
fix calc...() functions for new terminology (but they will require more revision downstream)
policy change: mutationRuns= for initializeSLiMOptions() has been deprecated and will error if used; pass that option to initializeChromosome() instead
policy change: the old "haplosome type" (A/X/Y) in the genome metadata is now a chromosome type (different) in the haplosome metadata
policy change: similarly, haplosome type A/X/Y in SLiM output (e.g., outputFull()) is now a chromosome type (different)
policy change: initialization order is a bit stricter; initializeSex() with "X" or "Y" must come earlier, before calls that would define an implicit "A" chromosome


version 4.3 (Eidos version 3.3):
Expand Down Expand Up @@ -310,7 +313,7 @@ version 4.0 (Eidos version 3.0):
– (object<Individual>)nearestNeighborsOfPoint(float point, io<Subpopulation>$ exerterSubpop, [integer$ count = 1]) - parameters switched
– (float)strength(object<Individual>$ receiver, [No<Individual> exerters = NULL]) - no change
– (float)totalOfNeighborStrengths(object<Individual> receivers, [No<Subpopulation>$ exerterSubpop = NULL]) - added exerterSubpop
change InteractionType::evaluate() API: (void)evaluate(io<Subpopulation> subpops) - `subpops` now required, remove `immediate`
change InteractionType::evaluate() API: (void)evaluate(io<Subpopulation> subpops) - `subpops` now required, remove `immediate`
remove the `subpop` pseudo-parameter from interaction() callbacks; receiver.subpop and exerter.subpop should now be used, and are not always the same
revised recipes for these changes (for evaluate() now requiring subpops, in all cases; no other changes needed): 15.2, 15.3 I/II/III/IV, 15.4, 15.5, 15.6, 15.7, 15.8, 15.9, 15.10, 15.11, 15.12, 16.10, 16.11, 16.18
note that these changes break backward compatibility for most models, and break backward reproducibility for many (due to distances not being rounded off from double to float in some code paths now)
Expand Down
Loading

0 comments on commit bd373a3

Please sign in to comment.