powered by NetLogo

view/download model file: HW-drift.nlogo

This agent-based model seeks to simulate Hardy-Weinberg equilibrium in a random-mating population. All Hardy-Weinberg assumptions are followed here except for an infinite population size. Therefore, this model also simulates genetic drift.

The organisms ("turtles") in this model navigate through space with a fixed orientation but at random speeds. Turtles are divided into males (arrowheads) and females (circles) and are further distinguished by their genotypes at two loci. The first locus (loc1) is A/G polymorphic and the second locus (loc2) is C/T polymorphic. Provided the population limit is not reached, hatchlings are created whenever two turtles in the same generation and of opposite sex come across one another. Hatchlings then randomly inherit one allele per locus from each parent. Lifespans are randomly distributed according to an approximate Poisson distribution with a mean set by the user. In this model, one year is equivalent to 50 ticks (each tick equals approximately one week).

The initial population size is set as "number-turtles." This is also the population limit. New hatchlings will not be born while the population size equals number-turtles.

The ratio of males to females can be set in the "male-female-ratio" slider. New hatchlings will also be assigned their sexes according to this ratio.

Initial genotype frequencies are set by four sliders. Only homozygote frequencies are set (with the homozygote and heterozygote frequencies summing to 1). Actual observed genotype numbers will be rounded if necessary.

"Setup" and "Go" to begin!

For clarity, only the frequency of one allele at each locus is plotted (with the frequencies of both alleles at a single locus summing to 1). The allele that is plotted can be toggled in the choosers below the plot.

Turtles are initially colored according to genotype at one of the two loci. To toggle which locus is colored, press the "color turtles at other locus" button.

The output screen, displaying genotype and allele frequencies, is updated every "year" (50 ticks). The output can be manually updated using the button below.

Set the population size to around 100 to more easily witness the stochastic effects of genetic drift. The population should reach fixation at both loci relatively rapidly. Then set the population size higher (to around 1000). The population should approximate Hardy-Weinberg equilibrium and take much longer to reach fixation.

Set both genotype frequencies to 0.25 at one locus. See if the genotype frequences stay in 1:2:1 equilibrium. Set the genotype frequencies at the other locus to 0.4 and 0.4. See if the the genotype frequencies gravitate towards a 1:2:1 ratio.

I am currently working to incorporate recombination and to track linkage disequilribium in the model. Retaining these simple rules, I also hope to incorporate gene flow, mutation, and natural selection in this model.

Original Model Copyright Notice:

Copyright 2010 Kenneth Chiou. All rights reserved.

Permission to use, modify or redistribute this model is hereby
granted, provided that both of the following requirements are followed:

a) this copyright notice is included.

b) this model will not be redistributed for profit without permission
from Kenneth Chiou. Contact Kenneth Chiou for appropriate licenses for
redistribution for profit.

Department of Anthropology

Campus Box 1114

Washington University

St. Louis, MO 63130

kenneth.chiou [at] wustl.edu

http://kennychiou.com

globals [sperm egg parent-generation color-locus]

turtles-own [sex generation deathday age loc1 loc2]

to setup

ca

ask patches [set pcolor black]

set color-locus one-of ["loc1" "loc2"]

create-turtles number-turtles [

setxy random-xcor random-ycor

set age 0

set generation 0

;; Poisson distribution with mean set by user

set deathday precision (random-normal mean-lifespan (sqrt mean-lifespan)) 2

]

ask n-of (male-female-ratio * number-turtles) turtles [

set sex "male"

;set color blue

]

ask turtles with [sex != "male"] [

set sex "female"

set shape "dot"

;set color red

]

assign-genotypes

ask turtles [assign-color]

report-freqs

type "Turtles inititially colored according to genotype at locus " print color-locus

end

to assign-genotypes

ask n-of (freqAA * number-turtles) turtles [

set loc1 ["A" "A"]

]

ask n-of (freqGG * number-turtles) turtles with [loc1 != ["A" "A"]] [

set loc1 ["G" "G"]

]

ask n-of (.5 * (1 - freqAA - freqGG) * number-turtles) turtles with [loc1 != ["A" "A"]] with [loc1 != ["G" "G"]] [

set loc1 ["A" "G"]

]

ask turtles with [loc1 != ["A" "A"]] with [loc1 != ["G" "G"]] with [loc1 != ["A" "G"]] [

set loc1 ["G" "A"]

]

ask n-of (freqCC * number-turtles) turtles [

set loc2 ["C" "C"]

]

ask n-of (freqTT * number-turtles) turtles with [loc2 != ["C" "C"]] [

set loc2 ["T" "T"]

]

ask n-of (.5 * (1 - freqCC - freqTT) * number-turtles) turtles with [loc2 != ["C" "C"]] with [loc2 != ["T" "T"]] [

set loc2 ["C" "T"]

]

ask turtles with [loc2 != ["C" "C"]] with [loc2 != ["T" "T"]] with [loc2 != ["C" "T"]] [

set loc2 ["T" "C"]

]

end

to go

tick

ask turtles [

drop-dead

set age precision (age + 1 / 50) 2

fd random-float 1

;assign-color

]

mate

if ticks mod 50 = 0 [report-freqs]

if not any? turtles [stop]

update-plot

if ((((count turtles with [loc1 = ["A" "A"]] +

.5 * (count turtles with [loc1 = ["A" "G"]] +

count turtles with [loc1 = ["G" "A"]]) /

(count turtles)) = 0)

or ((count turtles with [loc1 = ["G" "G"]] +

.5 * (count turtles with [loc1 = ["A" "G"]] +

count turtles with [loc1 = ["G" "A"]]) /

(count turtles)) = 0))

and (((count turtles with [loc2 = ["C" "C"]] +

.5 * (count turtles with [loc2 = ["C" "T"]] +

count turtles with [loc2 = ["T" "C"]]) /

(count turtles)) = 0)

or ((count turtles with [loc2 = ["T" "T"]] +

.5 * (count turtles with [loc2 = ["C" "T"]] +

count turtles with [loc2 = ["T" "C"]]) /

(count turtles))= 0))) [

report-freqs

stop

]

end

to mate

ask turtles with [sex = "male"] [

if count turtles < number-turtles [

set sperm sentence (one-of loc1) (one-of loc2)

set parent-generation [generation] of self

;; enforce mating only within a generation

if any? other turtles-here with [sex = "female"] with [generation = [generation] of self] [

ask one-of other turtles-here with [sex = "female"] with [generation = [generation] of self] [

set egg sentence (one-of loc1) (one-of loc2)

reproduce

]

]

]

]

end

to reproduce

hatch 1 [

assign-sex

set age 0

set generation parent-generation + 1

set deathday precision (random-normal mean-lifespan (sqrt mean-lifespan)) 2

inherit-alleles

assign-color

set heading random-float 360

]

end

to assign-sex

ifelse random-float 1 < male-female-ratio [

set sex "male"

set shape "default"

;set color blue

] [

set sex "female"

set shape "dot"

;set color red

]

end

to inherit-alleles

set loc1 sentence (item 0 sperm) (item 0 egg)

set loc2 sentence (item 1 sperm) (item 1 egg)

end

to switch-color

ifelse color-locus = "loc1" [set color-locus "loc2"] [set color-locus "loc1"]

ask turtles [assign-color]

type "Turtles now colored according to genotype at locus " print color-locus

end

to assign-color

if color-locus = "loc1" [

if loc1 = ["A" "A"] [set color blue]

if loc1 = ["A" "G"] or loc1 = ["G" "A"] [set color green]

if loc1 = ["G" "G"] [set color yellow]

]

if color-locus = "loc2" [

if loc2 = ["C" "C"] [set color red]

if loc2 = ["C" "T"] or loc2 = ["T" "C"] [set color pink]

if loc2 = ["T" "T"] [set color white]

]

end

to drop-dead

if age >= deathday [die]

end

to report-freqs

if not any? turtles [stop]

clear-output

let freq-AA precision ((count turtles with [loc1 = ["A" "A"]]) / count turtles) 3

let freq-GG precision ((count turtles with [loc1 = ["G" "G"]]) / count turtles) 3

let freq-AG precision (((count turtles with [loc1 = ["A" "G"]]) +

(count turtles with [loc1 = ["G" "A"]])) / count turtles) 3

let freq-CC precision ((count turtles with [loc2 = ["C" "C"]]) / count turtles) 3

let freq-CT precision (((count turtles with [loc2 = ["C" "T"]]) +

(count turtles with [loc2 = ["T" "C"]])) / count turtles) 3

let freq-TT precision ((count turtles with [loc2 = ["T" "T"]]) / count turtles) 3

let freq-A precision (((count turtles with [loc1 = ["A" "A"]]) +

.5 * ((count turtles with [loc1 = ["A" "G"]]) + (count turtles with [loc1 = ["G" "A"]]))) / count turtles) 3

let freq-G precision (((count turtles with [loc1 = ["G" "G"]]) +

.5 * ((count turtles with [loc1 = ["A" "G"]]) + (count turtles with [loc1 = ["G" "A"]]))) / count turtles) 3

let freq-C precision (((count turtles with [loc2 = ["C" "C"]]) +

.5 * ((count turtles with [loc2 = ["C" "T"]]) + (count turtles with [loc2 = ["T" "C"]]))) / count turtles) 3

let freq-T precision (((count turtles with [loc2 = ["T" "T"]]) +

.5 * ((count turtles with [loc2 = ["C" "T"]]) + (count turtles with [loc2 = ["T" "C"]]))) / count turtles) 3

output-type "Time (years): " output-print precision (ticks / 50) 2

output-type "freq of AA: " output-print freq-AA

output-type "freq of AG: " output-print freq-AG

output-type "freq of GG: " output-print freq-GG

output-type "freq of CC: " output-print freq-CC

output-type "freq of CT: " output-print freq-CT

output-type "freq of TT: " output-print freq-TT

output-type "A allele: " output-print freq-A

output-type "G allele: " output-print freq-G

output-type "C allele: " output-print freq-C

output-type "T allele: " output-print freq-T

end

to update-plot

set-current-plot "freq-alleles-plot"

let freq-A precision (((count turtles with [loc1 = ["A" "A"]]) +

.5 * ((count turtles with [loc1 = ["A" "G"]]) + (count turtles with [loc1 = ["G" "A"]]))) / count turtles) 3

let freq-G precision (((count turtles with [loc1 = ["G" "G"]]) +

.5 * ((count turtles with [loc1 = ["A" "G"]]) + (count turtles with [loc1 = ["G" "A"]]))) / count turtles) 3

let freq-C precision (((count turtles with [loc2 = ["C" "C"]]) +

.5 * ((count turtles with [loc2 = ["C" "T"]]) + (count turtles with [loc2 = ["T" "C"]]))) / count turtles) 3

let freq-T precision (((count turtles with [loc2 = ["T" "T"]]) +

.5 * ((count turtles with [loc2 = ["C" "T"]]) + (count turtles with [loc2 = ["T" "C"]]))) / count turtles) 3

set-current-plot-pen "loc1-A"

ifelse plot-allele-loc1 = "A" [plot-pen-down] [plot-pen-up]

set-plot-pen-interval 1 / 50

plot freq-A

set-current-plot-pen "loc1-G"

ifelse plot-allele-loc1 = "G" [plot-pen-down] [plot-pen-up]

set-plot-pen-interval 1 / 50

plot freq-G

set-current-plot-pen "loc2-C"

ifelse plot-allele-loc2 = "C" [plot-pen-down] [plot-pen-up]

set-plot-pen-interval 1 / 50

plot freq-C

set-current-plot-pen "loc2-T"

ifelse plot-allele-loc2 = "T" [plot-pen-down] [plot-pen-up]

set-plot-pen-interval 1 / 50

plot freq-T

end

;;kenneth.chiou [at] wustl.edu