#AES 6-28-15
#
# these functions are designed as helpers and interfaces for creating simcoal histories.
# the basic data structure is a data frame that has the same columns as the elements in a
# simcoal history entry:
# time, source, sink, migrants, new size, growth rate, migr. matrix
#
create.new.history <- function(npop=3,
deepestPopcoal=10000,
method=c("allroot","exponential")[2]
)
{
if (npop<2) {stop("function needs at least 2 populations")}
history <- data.frame(
time=NA, source=NA, sink=NA, migrants=NA, new.size=NA, growth.rate=NA, migr.matrix=NA
)
history <- history[rep(1,npop-1),]
history$time <- deepestPopcoal
history$migr.matrix <- 0
history$growth.rate <- 1
history$migrants <- 1
history$growth.rate <- 0
history$new.size <- 1
history$sink <- 0
history$source <- 1:dim(history)[1]
if (method=="exponential")
{
history$time <- round(rexp(npop-1,rate=1/(deepestPopcoal/2)))
}
history
}
simcoal.history.plot <- function(history
)
{
npop <- max(c(history$source,history$sink))+1
pops <- 0:(npop-1)
plot(1~1,type="n",
ylim=c(0,max(history$time)*1.2),
xlim=c(-1,npop),axes=F,xlab="population",ylab="time")
axis(1,labels=pops,at=0:(npop-1))
axis(2)
for (p in 0:(npop-1))
{
x.source <- p
p.hist <- history[history$source==p,]
if (dim(p.hist)[1]>0)
for (e in 1:dim(p.hist)[1])
{
x.sink <- p.hist$sink[e]
y <- p.hist$time[e]
points(x=c(x.source,x.source),
y=c(0,y), type="l")
arrows(x.source,y,x.sink,y)
}
}
###now deal with the sink-only situations (should be one)
spops <- unique(history$sink[!history$sink%in%history$source])
for (i in spops)
{
arrows(i,0,i,max(history$time)*1.2)
}
}
simcoal.history.change <- function(history,
click,
dblclick
)
{
if ((!is.null(click)) & (!is.null(dblclick)))
{
oldhist <- history
src <- round(click$x)
if (src %in% c(history$source,history$sink))
{
history <- history[history$source!=src,]
history <- history[c(1:dim(history)[1],1),]
row <- dim(history)[1]
history[row,] <- c(abs(round(dblclick$y)),
abs(src),
abs(round(dblclick$x)),
1,
1,
0,
0)
# history
}
#check and make sure that the oldest sink does not sink into another deme
history <- history[order(-history$time),]
if (history[1,3] %in% history[,2]) {history <- history[-1,]}
}
if (is.history(history)) history else oldhist
}
is.history <- function(history)
{
err <- F
msg <- NULL
##check for names
if (prod(names(history) %in% c("time", "source", "sink", "migrants", "new.size", "growth.rate", "migr.matrix"))!=1) err <- T
if (prod(c("time", "source", "sink", "migrants", "new.size", "growth.rate", "migr.matrix")%in%names(history))!=1) err <- T
if (err) msg <- c(msg,"problem with names")
######## this code is essentially worthless, but the problem
######## needs solving
##check to make sure that everybody coalesces
##first run through the sources
last.sink <- history$sink[history$time==max(history$time)]
if (length(unique(last.sink))>1) #multiple sinks at the "root"
{
err <- T
msg <- c(msg,"multiple sinks at deepest time")
}
last.sink <- last.sink[1]
history$coal <- FALSE
for (s in 1:dim(history)[1])
{
snk <- history[s,"sink"]
}
if (err)
{
FALSE
} else {
TRUE
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.