## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Demographic component functions
##
## x - size this autumn
## y - size next autumn
## S - sex
## A - age
## G - genotype
## Nt - standardised population density
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

mk.flist <- function(sets) {
    mydims <- sapply(sets,length)
    mylist <- vector("list", prod(mydims))
    dim(mylist) <- mydims
    dimnames(mylist) <- sets
    return(mylist)
}

## ~~~~~~~~~ SURVIVAL ~~~~~~~~~

p.surv.list <- mk.flist(list(S=c("F","M"), A=c(0,+1)))

p.surv.list[["F", "0"]] <- function(x, Nt, mPar) {
    nu <- mPar["s.a0.F.(Intercept)"]+mPar["s.a0.F.capWgt"]*x+
          mPar["s.a0.F.Nt"]*Nt+mPar["s.a0.F.obsY"]*mPar["obsY"]
    return(invlogit(nu))
}
p.surv.list[["F", "1"]] <- function(x, G, A, Nt, mPar, gSwitch) {
    prefix <- "s.a1.F"
    if (prefix %in% names(gSwitch) & !gSwitch[prefix]) { G = 0 }
    nu <- mPar["s.a1.F.(Intercept)"]+mPar["s.a1.F.capWgt"]*x+
          mPar["s.a1.F.APS071add"]*G+
          mPar["s.a1.F.poly(ageY, 2, raw = TRUE)1"]*A+mPar["s.a1.F.poly(ageY, 2, raw = TRUE)2"]*A^2+
          mPar["s.a1.F.Nt"]*Nt+mPar["s.a1.F.Nt:APS071add"]*G*Nt+mPar["s.a1.F.obsY"]*mPar["obsY"]
    return(invlogit(nu))
}
p.surv.list[["M", "0"]] <- function(x, G, Nt, mPar, gSwitch) {
    prefix <- "s.a0.M"
    if (prefix %in% names(gSwitch) & !gSwitch[prefix]) { G = 0 }
    nu <- mPar["s.a0.M.(Intercept)"]+mPar["s.a0.M.capWgt"]*x+
          mPar["s.a0.M.Nt"]*Nt+mPar["s.a0.M.capWgt:Nt"]*x*Nt+mPar["s.a0.M.obsY"]*mPar["obsY"]+
          mPar["s.a0.M.APS071add"]*G
    return(invlogit(nu))
}
p.surv.list[["M", "1"]] <- function(x, G, A, Nt, mPar, gSwitch) {
    prefix <- "s.a1.M"
    if (prefix %in% names(gSwitch) & !gSwitch[prefix]) { G = 0 }
    nu <- mPar["s.a1.M.(Intercept)"]+mPar["s.a1.M.capWgt"]*x+
          mPar["s.a1.M.APS071add"]*G+mPar["s.a1.M.ageY"]*A+
          mPar["s.a1.M.Nt"]*Nt+mPar["s.a1.M.obsY:APS071add"]*G*mPar["obsY"]+
          mPar["s.a1.M.obsY"]*mPar["obsY"]
    return(invlogit(nu))
}

p.surv <- function(x, G, S, A, Nt, mPar, gSwitch=numeric(0))
{
    ## expect S and A to have length=1
    if (length(S) != 1 | length(A) != 1)
        stop("survival function not vectorised for S(ex) and (A)ge")
    ## assign the required function
    if       (S=="F") {
        if        (A ==  0) {
            f <- p.surv.list[["F", "0"]]
        } else if (A >=  1) {
            f <- p.surv.list[["F", "1"]]
        } else stop("invalid (A)ge")
    } else if (S=="M") {
        if        (A ==  0) {
            f <- p.surv.list[["M", "0"]]
        } else if (A >=  1) {
            f <- p.surv.list[["M", "1"]]
        } else stop("invalid (A)ge")
    } else stop("invalid (S)ex")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}

## ~~~~~~~~~ GROWTH ~~~~~~~~~

d.grow.list <- mk.flist(list(S=c("F","M"), A=c(0,+1)))

d.grow.list[["F","0"]] <- function(y, x, Nt, mPar) {
    mu <- mPar["g.a0.F.(Intercept)"]+mPar["g.a0.F.capWgt"]*x+mPar["g.a0.F.Nt"]*Nt
    sg <- mPar["g.a0.F.sigma"]
    return(dnorm(y,mu,sg))
}
d.grow.list[["F","1"]] <- function(y, x, G, A, Nt, mPar) {
    mu <- mPar["g.a1.F.(Intercept)"] + mPar["g.a1.F.capWgt"]*x + mPar["g.a1.F.poly(ageY, 2, raw = TRUE)1"]*A +
          mPar["g.a1.F.Nt"]*Nt + mPar["g.a1.F.ageY:Nt"]*Nt*A + mPar["g.a1.F.poly(ageY, 2, raw = TRUE)2"]*A^2
    sg <- mPar["g.a1.F.sigma"]
    return(dnorm(y,mu,sg))
}
d.grow.list[["M","0"]] <- function(y, x, Nt, mPar) {
    mu <- mPar["g.a0.M.(Intercept)"]+mPar["g.a0.M.capWgt"]*x+mPar["g.a0.M.Nt"]*Nt+mPar["g.a0.M.obsY"]*mPar["obsY"]
    sg <- mPar["g.a0.M.sigma"]
    return(dnorm(y,mu,sg))
}
d.grow.list[["M","1"]] <- function(y, x, G, A, Nt, mPar) {
    mu <- mPar["g.a1.M.(Intercept)"] + mPar["g.a1.M.capWgt"]*x
    sg <- mPar["g.a1.M.sigma"]
    return(dnorm(y,mu,sg))
}

d.grow <- function(y, x, G, S, A, Nt, mPar)
{
    ## expect S and A to have length=1
    if (length(S) != 1 | length(A) != 1)
        stop("growth function not vectorised for S(ex) and (A)ge")
    ## assign the required function
    if       (S=="F") {
        if        (A ==  0) {
            f <- d.grow.list[["F", "0"]]
        } else if (A >=  1) {
            f <- d.grow.list[["F", "1"]]
        } else stop("invalid (A)ge")
    } else if (S=="M") {
        if        (A ==  0) {
            f <- d.grow.list[["M", "0"]]
        } else if (A >=  1) {
            f <- d.grow.list[["M", "1"]]
        } else stop("invalid (A)ge")
    } else stop("invalid (S)ex")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}

## ~~~~~~~~~ FEMALE PROBABILITY OF REPRODUCTION ~~~~~~~~~

p.repr.list <- mk.flist(list(A=c(0,+1)))

p.repr.list[["0"]] <- function(x, Nt, mPar) {
    nu <- mPar["r.a0.F.(Intercept)"]+mPar["r.a0.F.capWgt"]*x+
          mPar["r.a0.F.Nt"]*Nt+mPar["r.a0.F.obsY"]*mPar["obsY"]+
          mPar["r.a0.F.capWgt:obsY"]*x*mPar["obsY"]
    return(invlogit(nu))
}
p.repr.list[["1"]] <- function(A, Nt, mPar) {
    nu <- mPar["r.a1.F.(Intercept)"]+
          mPar["r.a1.F.poly(ageY, 2, raw = TRUE)1"]*A+mPar["r.a1.F.poly(ageY, 2, raw = TRUE)2"]*A^2+
          mPar["r.a1.F.obsY"]*mPar["obsY"]+mPar["r.a1.F.ageY:obsY"]*A*mPar["obsY"]
    return(invlogit(nu))
}

p.repr <- function(x, G, A, Nt, mPar)
{
    ## expect S and A to have length=1
    if (length(A) != 1)
        stop("female P(reproduction) function not vectorised for (A)ge")
    ## assign the required function
    if        (A ==  0) {
        f <- p.repr.list[["0"]]
    } else if (A >=  1) {
        f <- p.repr.list[["1"]]
    } else stop("invalid (A)ge")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}

## ~~~~~~~~~ FEMALE PROBABILITY OF TWINNING ~~~~~~~~~

p.twin.list <- mk.flist(list(A=c(0,+1)))

p.twin.list[["0"]] <- function(x, Nt, mPar) {
    return(0)
}
p.twin.list[["1"]] <- function(x, A, Nt, mPar) {
    nu <- mPar["t.a1.F.(Intercept)"]+mPar["t.a1.F.capWgt"]*x+
          mPar["t.a1.F.poly(ageY, 2, raw = TRUE)1"]*A+mPar["t.a1.F.poly(ageY, 2, raw = TRUE)2"]*A^2+
          mPar["t.a1.F.Nt"]*Nt+mPar["t.a1.F.obsY"]*mPar["obsY"]
    return(invlogit(nu))
}

p.twin <- function(x, G, A, Nt, mPar)
{
    ## expect S and A to have length=1
    if (length(A) != 1)
        stop("female P(twinning) function not vectorised for (A)ge")
    ## assign the required function
    if        (A ==  0) {
        f <- p.twin.list[["0"]]
    } else if (A >=  1) {
        f <- p.twin.list[["1"]]
    } else stop("invalid (A)ge")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}

## ~~~~~~~~~ OFFSPRING SPRING SURVIVAL FUNCTION ~~~~~~~~~

p.offsurv.list <- mk.flist(list(A=c(0,+1), S.off=c("F","M"), T.off=c("0","1")))

p.offsurv.list[["0","F","0"]] <- function(x, Nt, mPar) {
    nu <- mPar["s.off.a0.(Intercept)"]+mPar["s.off.a0.capWgtMum"]*x+
          mPar["s.off.a0.Ntm1"]*Nt+mPar["s.off.a0.obsY"]*mPar["obsY"]
    return(invlogit(nu))
}
p.offsurv.list[["0","M","0"]] <- function(x, Nt, mPar) {
    nu <- mPar["s.off.a0.(Intercept)"]+mPar["s.off.a0.capWgtMum"]*x+
          mPar["s.off.a0.Ntm1"]*Nt+mPar["s.off.a0.obsY"]*mPar["obsY"]+mPar["s.off.a0.sexM"]
    return(invlogit(nu))
}
p.offsurv.list[["1","F","0"]] <- function(x, A, Nt, mPar, isTwn) {
    nu <- mPar["s.off.a1.(Intercept)"]+mPar["s.off.a1.capWgtMum"]*x+
          mPar["s.off.a1.Ntm1"]*Nt+mPar["s.off.a1.obsY"]*mPar["obsY"]
    return(invlogit(nu))
}
p.offsurv.list[["1","M","0"]] <- function(x, A, Nt, mPar, isTwn) {
    nu <- mPar["s.off.a1.(Intercept)"]+mPar["s.off.a1.capWgtMum"]*x+
          mPar["s.off.a1.Ntm1"]*Nt+mPar["s.off.a1.obsY"]*mPar["obsY"]+mPar["s.off.a1.sexM"]
    return(invlogit(nu))
}
p.offsurv.list[["1","F","1"]] <- function(x, A, Nt, mPar, isTwn) {
    nu <- mPar["s.off.a1.(Intercept)"]+mPar["s.off.a1.capWgtMum"]*x+
          mPar["s.off.a1.Ntm1"]*Nt+mPar["s.off.a1.obsY"]*mPar["obsY"]+mPar["s.off.a1.isTwnMat"]
    return(invlogit(nu))
}
p.offsurv.list[["1","M","1"]] <- function(x, A, Nt, mPar, isTwn) {
    nu <- mPar["s.off.a1.(Intercept)"]+mPar["s.off.a1.capWgtMum"]*x+
          mPar["s.off.a1.Ntm1"]*Nt+mPar["s.off.a1.obsY"]*mPar["obsY"]+
          mPar["s.off.a1.sexM"]+mPar["s.off.a1.isTwnMat"]
    return(invlogit(nu))
}

p.offsurv <- function(x, G, A, Nt, mPar, S.off, T.off)
{
    ## expect S and A to have length=1
    if (length(A) != 1)
        stop("offspring survival function not vectorised for (A)ge")
    ## assign the required function
    if        (A == 0) {
        if        (S.off == "F") {
            if        (T.off == 0) {
                f <- p.offsurv.list[["0","F","0"]]
            } else if (T.off == 1) {
                return(0) # age 0 females cannot twin
            } else stop("invalid offspring (T)win status")
        } else if (S.off == "M") {
            if        (T.off == 0) {
                f <- p.offsurv.list[["0","M","0"]]
            } else if (T.off == 1) {
                return(0) # age 0 females cannot twin
            } else stop("invalid offspring (T)win status")
        } else stop("invalid offspring (S)ex")
    } else if (A >= 1) {
        if        (S.off == "F") {
            if        (T.off == 0) {
                f <- p.offsurv.list[["1","F","0"]]
            } else if (T.off == 1) {
                f <- p.offsurv.list[["1","F","1"]]
            } else stop("invalid offspring (T)win status")
        } else if (S.off == "M") {
            if        (T.off == 0) {
                f <- p.offsurv.list[["1","M","0"]]
            } else if (T.off == 1) {
                f <- p.offsurv.list[["1","M","1"]]
            } else stop("invalid offspring (T)win status")
        } else stop("invalid offspring (S)ex")
    } else stop("invalid (A)ge")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}

## ~~~~~~~~~ OFFSPRING SIZE DISTRIBUTION ~~~~~~~~~

d.offsize.list <- mk.flist(list(S.off=c("F","M"), T.off=c("0","1")))

d.offsize.list[["F","0"]] <- function(y, x, A, Nt, mPar) {
    mu <- mPar["sz.off.(Intercept)"]+mPar["sz.off.capWgtMum"]*x+
          mPar["sz.off.ageMum"]*A+
          mPar["sz.off.Ntm1"]*Nt+
          mPar["sz.off.obsY"]*mPar["obsY"]+
          mPar["sz.off.ageMum:obsY"]*A*mPar["obsY"]
    sg <- mPar["sz.off.sigma"]
    return(dnorm(y,mu,sg))
}
d.offsize.list[["M","0"]] <- function(y, x, A, Nt, mPar) {
    mu <- mPar["sz.off.(Intercept)"]+mPar["sz.off.capWgtMum"]*x+
          mPar["sz.off.ageMum"]*A+
          mPar["sz.off.Ntm1"]*Nt+mPar["sz.off.sexM"]+
          mPar["sz.off.obsY"]*mPar["obsY"]+
          mPar["sz.off.ageMum:obsY"]*A*mPar["obsY"]

    sg <- mPar["sz.off.sigma"]
    return(dnorm(y,mu,sg))
}
d.offsize.list[["F","1"]] <- function(y, x, A, Nt, mPar) {
    mu <- mPar["sz.off.(Intercept)"]+mPar["sz.off.capWgtMum"]*x+
          mPar["sz.off.ageMum"]*A+
          mPar["sz.off.Ntm1"]*Nt+mPar["sz.off.isTwnMat"]+
          mPar["sz.off.obsY"]*mPar["obsY"]+
          mPar["sz.off.ageMum:obsY"]*A*mPar["obsY"]
    sg <- mPar["sz.off.sigma"]
    return(dnorm(y,mu,sg))
}
d.offsize.list[["M","1"]] <- function(y, x, A, Nt, mPar) {
    mu <- mPar["sz.off.(Intercept)"]+mPar["sz.off.capWgtMum"]*x+
          mPar["sz.off.ageMum"]*A+
          mPar["sz.off.Ntm1"]*Nt+mPar["sz.off.sexM"]+mPar["sz.off.isTwnMat"]+
          mPar["sz.off.obsY"]*mPar["obsY"]+
          mPar["sz.off.ageMum:obsY"]*A*mPar["obsY"]
    sg <- mPar["sz.off.sigma"]
    return(dnorm(y,mu,sg))
}

d.offsize <- function(y, x, G, A, Nt, mPar, S.off, T.off)
{
    ## expect S and A to have length=1
    if (length(S.off) != 1 | length(T.off) != 1)
        stop("offspring size function not vectorised for offspring S(ex), female (A)ge and (T)win status")
    ## assign the required function
    if (all(A >= 0)) {
        if        (S.off == "F") {
            if        (T.off == 0) {
                f <- d.offsize.list[["F","0"]]
            } else if (T.off == 1) {
                f <- d.offsize.list[["F","1"]]
            } else stop("invalid offspring (T)win status")
        } else if (S.off == "M") {
            if        (T.off == 0) {
                f <- d.offsize.list[["M","0"]]
            } else if (T.off == 1) {
                f <- d.offsize.list[["M","1"]]
            } else stop("invalid offspring (T)win status")
        } else stop("invalid offspring (S)ex")
    } else stop("invalid (A)ge")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}

## ~~~~~~~~~ MALE MATING SUCCESS ~~~~~~~~~

n.mrepro.list <- mk.flist(list(A=c("0","1")))

n.mrepro.list[["0"]] <- function(x, G, Nt, mPar, gSwitch) {
    prefix <- "n.off.a0.M"
    if (prefix %in% names(gSwitch) & !gSwitch[prefix]) { G = 0 }
    nu <- mPar["n.off.a0.M.(Intercept)"] + mPar["n.off.a0.M.capWgt"]*x +
          mPar["n.off.a0.M.APS071add"]*G + mPar["n.off.a0.M.Nt"]*Nt + mPar["n.off.a0.M.obsY"]*mPar["obsY"]
    return(exp(nu))
}
n.mrepro.list[["1"]] <- function(x, G, Nt, mPar, gSwitch) {
    prefix <- "n.off.a1.M"
    if (prefix %in% names(gSwitch) & !gSwitch[prefix]) { G = 0 }
    nu <- mPar["n.off.a1.M.(Intercept)"] + mPar["n.off.a1.M.capWgt"]*x +
          mPar["n.off.a1.M.APS071add"]*G + mPar["n.off.a1.M.APS071add:Nt"]*G*Nt +
          mPar["n.off.a1.M.Nt"]*Nt + mPar["n.off.a1.M.obsY"]*mPar["obsY"]
    return(exp(nu))
}

n.mrepro <- function(x, G, A, Nt, mPar, gSwitch=numeric(0))
{
    ## expect S and A to have length=1
    if (length(A) != 1)
        stop("male reproduction function not vectorised for (A)ge")
    ## assign the required function
    if        (A ==  0) {
        f <- n.mrepro.list[["0"]]
    } else if (A >=  1) {
        f <- n.mrepro.list[["1"]]
    } else stop("invalid (A)ge")
    ## get the required arguments as a list of atomic 'names'
    fargs <- names(formals(f))
    fargs <- sapply(fargs, as.name)
    ## call the function and return
    return(do.call("f", fargs))
}


#' ## START MODULE 2.4
#' Objective: Edit extent, projection, dimension, resolution of raster layers or shapefiles
#'
#' tested on R versions 3.1.X, 3.2.X
#'
#' Load packages and set working directory
#+ load packages
   library(rgdal)     # fxns: readOGR, writeOGR
   library(raster)    # fxns: crop, mask
#  set path
   path.root <- "~/Documents/Intro-Spatial-R/"
   path.mod <- paste(path.root, "module2", sep = "")
   setwd(path.mod)
#'
#' ### Crop a polygon file to another polygon
#' Import shapefile to be altered
#'
#+ import shapefile
#  CP study area; the "mask" for cropping
   cp.region <- readOGR(dsn = "data", layer = "COP_boundpoly_aea")
   class(cp.region)  # examine class

#  North American states/provinces to be altered
   states <- readOGR(dsn = "data", layer = "na_states_aea")
   class(states)  # examine class
#'
#' Subset states (UT, AZ, CO, NM) in Colorado Plateau region
#'  - NOTE: str() to determine shapefile characteristics
#'     here, states$CODE returns all state-based codes
#'  - NOTE: rgdal can be squirrelly, requiring NAs to be excluded, it crashes if NA present
#'
#+ subset states
   head(states@data)  # examine shapepoly data
   states$CODE  # state codes
   cp.states <- states[states$CODE == "UT" | states$CODE == "CO" |
                             states$CODE == "NM" | states$CODE == "AZ", ]

#    cp.states <- states[states$CODE == "UT" & !is.na(states$CODE) |
#                        states$CODE == "CO" & !is.na(states$CODE) |
#                        states$CODE == "NM" & !is.na(states$CODE) |
# 	                   states$CODE == "AZ" & !is.na(states$CODE), ]
   cp.states@data  # examine subsetted states
#'
#+ giggle plots
   plot(states)# all of North America
   plot(cp.states, add = T, col = "blue")# the subsetted states
   plot(cp.region, add = T, col = "red")# the study region, taking long time
#'
#' Crop states to the CP region
#'
#+ crop states
   cp.statesCROP <- crop(cp.states,cp.region)
   plot(cp.states)  # giggle plot
## output shapefile if desired; examine in ArcGIS if desired
   # writeOGR(cp.statesCROP, dsn = "./outdata", layer = "cp.statesCROP",
   # morphToESRI = T, driver = "ESRI Shapefile")
#'
#' ### Polygon crop of raster
#' This is a 2-step process that is easy to construct as function if desired.
#'
#+ import raster
   tave <- raster("data/tave_yr_av.img")
   tave  # examine raster
   summary(cp.region)  # examine crop polygon (from above)
#'
#' Note the different projections; must convert 1 to match other (see Module 2.2)
#'
#+ transform to match projections
   cp.regionWGS <- spTransform(cp.region, CRS = CRS(projection(tave)))
   cp.regionWGS  # now same projection as tave

## giggle plots; goal is crop of tave to match red in plot
   plot(tave)
   plot(cp.regionWGS, add = T, col = "red")
#'
#' Step #1; `mask()` function w/CP polygon as the mask applied to tave
#'
#+ mask tave
   taveCROP.1 <- mask(tave, cp.regionWGS)

## giggle plots; LOL here .....
   plot(taveCROP.1)# NOTE extent is extent of tave
   plot(extent(taveCROP.1), add = T)
#'
#' Step #2; `crop()` function to subset the masked tave to the extent of the CP region
#'
#+ crop tave to CP region
   taveCROP.2 <- crop(taveCROP.1, cp.regionWGS)

## giggle plots ...
   plot(taveCROP.2)
   plot(cp.regionWGS, add = T)

## outfile cropped raster if desired
   #writeRaster(taveCROP.2, filename = "outdata/cp.taveCROP2.img", format = "HFA")
#'
#' ### Crop raster using another raster
#' Assume raster of region to serve as crop; here cp.rast (see Module 2.2)
#'
#+ crop raster by raster
   ext.rast <- raster(resolution = 0.008333333, extent(cp.regionWGS))
   cp.rast <- rasterize(cp.regionWGS, field = "Id", ext.rast)
   cp.rast  # examine

## raster to be cropped
## same projection/resolution as cp.rast?  if not see Module 2.3
   tave  # examine

## some giggle plots; crop goal is red
   plot(tave)
   plot(cp.rast, add = T, col = "red")

## crop tave raster w/cp.rast raster
   taveCROP.3 <- crop(tave, cp.rast)

## write out file of cropped raster if desired
   #writeRaster(taveCROP.3, filename = "outdata/cp.taveCROP3.img", format = "HFA")

## giggle plots; NOTE that crop is the cp.rast extent, not just CP region
   plot(taveCROP.3)
   plot(cp.rast, add = T, col = "red")

## giggle plots
   par(mfrow = c(1, 2))
   plot(taveCROP.3)
   plot(cp.regionWGS, add = T, border = "black")

## outfile cropped raster if desired
   #writeRaster(taveCROP.3, filename = "outdata/cp.taveCROP3.img", format = "HFA")
#'
#' Crop a polygon to a raster
#'
#+ load shapefile
   soil <- readOGR(dsn = "data", layer = "soils")  # be patient here ... ~3 min runtime
   soil # examine polygon
   cp.rast # examine raster; both have same projection?  if not see Module 2.2/2.3

## crop polygon w/extent of raster
   soilCROP.1 <- crop(soil,extent(cp.rast))
## giggle plots
   par(mfrow = c(1, 2))
   plot(soil)
   plot(cp.regionWGS, add = T, col = "red")
   plot(soilCROP.1)
   plot(cp.rast, add = T, col = "red")
#'
#' ## END MODULE 2.4
#'
#' Create R markdown file from R script
#+
   knitr::spin("Rscripts/M2.4-alterextent_shapefileraster.r", knit = F, format = "Rmd")


#' Bumblebee: Quantify Disease Transmission Within and Between Population Groups
#'
#' @description
#' Bumblebee uses counts of directed transmission pairs identified between samples
#' from population groups of interest to estimate the flow of transmissions within
#' and between those population groups accounting for sampling heterogeneity.
#'
#' Population groups might include: communities, geographical regions, age-gender
#' groupings or arms of a randomized-clinical trial.
#'
#' Counts of observed directed transmission pairs can be obtained from deep-sequence
#' phylogenetic data (via phyloscanner) or known epidemiological contacts. Note:
#' Deep-sequence data is also commonly referred to as high-throughput or
#' next-generation sequence data. See references to learn more about phyloscanner.
#'
#' @section The \code{estimate_transmission_flows()} function:
#' To estimate transmission flows, that is, the relative probability of transmission
#' within and between population groups accounting for variable sampling the among
#' the population groups the function: \code{estimate_transmission_flows_and_ci()}
#' computes the conditional probability, \code{theta_hat} that a pair of pathogen
#' sequences is from a specific population group pairing given that the pair is
#' linked.
#'
#' For two population groups of interest \eqn{(u,v)} \code{theta_hat} is denoted by
#'
#' \deqn{\hat{\theta_{ij}} = Pr(pair from groups (i,j) | pair is linked), where i = u,v and j = u,v .}
#'
#' To learn more and try some examples, see documentation of the
#' \code{estimate_transmission_flows()} function and the bumblebee package
#' website \url{https://magosil86.github.io/bumblebee/}.
#'
#' @seealso See the following functions for details on estimating transmission flows
#' and corresponding confidence intervals: \code{estimate_transmission_flows_and_ci},
#' \code{estimate_theta_hat} and \code{estimate_multinom_ci}.
#'
#' @section Cite the package:
#' Please cite the package using the following reference:
#' Lerato E. Magosi, Marc Lipsitch (2021). Bumblebee: Quantify Disease
#' Transmission Within and Between Population Groups. R package version
#' 0.1.0 \url{https://magosil86.github.io/bumblebee/}
#'
#' @author
#' Lerato E. Magosi \email{lmagosi@hsph.harvard.edu} or
#' \email{magosil86@gmail.com}
#'
#' @references
#' \enumerate{
#'
#'    \item Magosi LE, et al., Deep-sequence phylogenetics to quantify patterns of
#'          HIV transmission in the context of a universal testing and treatment
#'          trial – BCPP/ Ya Tsie trial. To submit for publication, 2021.
#'
#'    \item Carnegie, N.B., et al., Linkage of viral sequences among HIV-infected
#' 		 village residents in Botswana: estimation of linkage rates in the
#' 		 presence of missing data. PLoS Computational Biology, 2014. 10(1):
#' 		 p. e1003430.
#'
#'    \item Goodman, L. A. On Simultaneous Confidence Intervals for Multinomial Proportions
#' 		 Technometrics, 1965. 7, 247-254.
#'
#'    \item Glaz, J., Sison, C.P. Simultaneous confidence intervals for multinomial proportions.
#' 		 Journal of Statistical Planning and Inference, 1999. 82:251-262.
#'
#'    \item May, W.L., Johnson, W.D. Constructing two-sided simultaneous confidence intervals for
#' 		 multinomial proportions for small counts in a large number of cells.
#' 		 Journal of Statistical Software, 2000. 5(6).
#' 		 Paper and code available at https://www.jstatsoft.org/v05/i06.
#'
#'    \item Ratmann, O., et al., Inferring HIV-1 transmission networks and sources of
#' 		 epidemic spread in Africa with deep-sequence phylogenetic analysis.
#' 		 Nature Communications, 2019. 10(1): p. 1411.
#'
#'    \item Sison, C.P and Glaz, J. Simultaneous confidence intervals and sample size determination
#' 		 for multinomial proportions. Journal of the American Statistical Association,
#' 		 1995. 90:366-369.
#'
#'    \item Wymant, C., et al., PHYLOSCANNER: Inferring Transmission from Within- and
#' 		 Between-Host Pathogen Genetic Diversity. Molecular Biology and Evolution,
#' 		 2017. 35(3): p. 719-733.
#' }
#'
#' @docType package
#' @name bumblebee-package
#' @aliases bumblebee
#'
#' @keywords internal
#' @importFrom dplyr %>%
"_PACKAGE"


thresh<-function(x,lam){
	# s=solve(A)%*%x
# 	if(lam==0) return(s)
# 	max(1-lam/crossprod(x,s)^(1/2),0)*s
	if(lam==0) return(x)
	max(1-lam/sum(x^2)^(1/2) , 0)*x
}

admmSel<-function(dat,lam,m1,m2,rho=1,cores=1,elist=NULL){
	n=dim(dat)[1]
	print("Calculating Statistics:")
	d=dim(dat)[2]
	if(is.null(elist)) elist= get.edgelist(graph.full(d))
	g=graph.edgelist(elist,directed=F)
	K = Kvec2(dat,m1,m2,elist)
	G = Gamma.ret2(dat,m1,m2,cores=dim(dat)[2],ge=elist)
	dd=dim(G[[1]]$v)[1]
	#dd=dim(G[[1]])[1]

	Ginv=mclapply(1:d,function(x) G[[x]]$v %*% ((1/((1/n)*G[[x]]$d^2+rho)) * t(G[[x]]$v)),mc.cores=d)
	#Ginv=mclapply(1:d,function(x) solve(G[[x]]+rho*diag(dd)),mc.cores=cores)
	print("Done.")
	znode = matrix(rnorm(d*m1)*1e-10,d,m1)
	zedge = array(rnorm(m2*m2*dim(elist)[1])*1e-10,dim=c(m2,m2,dim(elist)[1]))
	tol=Inf
	x=xold=y=zz=lapply(1:d,function(x)rep(0,dim(G[[x]]$v)[1]))
	admmout=list()
	lam=rev(sort(lam))
	if(d>=100) cores = detectCores()
	for(lamind in 1:length(lam)){
		print(paste("Run ",lamind," Begun"))
		if(lamind>1){
			x=admmout[[lamind-1]]$x
			y=admmout[[lamind-1]]$y
			zz=admmout[[lamind-1]]$zz
		}
		tol=Inf
		iter=0
		while(tol>1e-3 & iter<500){
		iter=iter+1
		# x step
		xold=x
		zedge_old=zedge
		znode_old=znode
		#print(lapply(y,function(x)length(x)))
		x=mclapply(1:d,function(i){
		#	print(dim(Ginv[[i]]))
		#	print(length(K[[i]]))
		#	print(length(y[[i]]))
			Ginv[[i]]%*%(-K[[i]] - y[[i]] + rho*zz[[i]])
		},mc.cores=cores)
		#z-y step
		for(i in 1:d){
			ii=sum(neighbors(g,i)<i)
			c= (ii)*m2^2+1
			ind=c: (c+m1-1)
			znode[i,] = (x[[i]][ind] + y[[i]][ind]/rho )
			znode[i,] = thresh(znode[i,],.01*lam[lamind]/rho)
			y[[i]][ind] = y[[i]][ind] + rho*( x[[i]][ind] - znode[i,])
			zz[[i]][ind] = znode[i,]
			for(j in neighbors(g,i)){

						jj =which(neighbors(g,i)==j)
						ii = which(neighbors(g,j)==i)

					if(i<j){
						c1 = m1+(jj-1)*m2^2+1
						c2 = (ii-1)*m2^2+1
					}else{
						c2 = m1+(ii-1)*m2^2+1
						c1 = (jj-1)*m2^2+1
					}

					e= which(elist[,1]%in%c(i,j) & elist[,2]%in%c(i,j))
					#c1 = ifelse(j>i , m1 + (j-2)*m2+1 ,(j-1)*m2+1 )
					#c2 = ifelse(j<i , m1 + (i-2)*m2+1 ,(i-1)*m2+1 )
					#if(length(e)==0) next
					#c1 = m1+(jj-1)*m2^2+1
					#c2 = (ii-1)*m2^2+1
					ind1 =c1:(c1+m2^2-1)
					ind2 =c2:(c2+m2^2-1)
					#print(ind1)
					#print(length(y[[i]]))
					#print(ind2)
					#print(length(y[[j]]))
					zedge[,,e] = .5* (x[[i]][ind1] + x[[j]][ind2] +
									y[[i]][ind1]/rho + y[[j]][ind2]/rho)
					zedge[,,e]=matrix( thresh(zedge[,,e],lam[lamind]/rho) , m2 , m2)

					y[[i]][ind1] = y[[i]][ind1] + rho*(x[[i]][ind1] - c(zedge[,,e]))
					y[[j]][ind2] = y[[j]][ind2] + rho*(x[[j]][ind2] - c(zedge[,,e]))
					zz[[i]][ind1] = c(zedge[,,e])
					zz[[j]][ind2] = c(zedge[,,e])
				}
			}

		#print(mean(abs(unlist(x)-unlist(zz))))
		#tol = mean(abs(unlist(xold)-unlist(x)))/mean(abs(unlist(xold))) #+ .5*mean(abs(unlist(x)-unlist(zz)))
		tol = ( sum(abs(zedge-zedge_old)) + sum(abs(znode-znode_old)) ) #/(sum(abs(znode_old))+sum(abs(zedge_old)))
			print(paste("tol:",tol))
		}
		#return(list(znode=znode,zedge=zedge))#list(z=zz,x=x,y=y,znode=znode,zedge=zedge))
		admmout[[lamind]]= list(x=x,y=y,zz=zz,znode=znode,zedge=zedge)
	}
	return(admmout)
}

admmSel2<-function(dat,lam,m1,m2,rho=1,cores=1,elist=NULL){
	n=dim(dat)[1]
	print("Calculating Statistics:")
	d=dim(dat)[2]
	if(is.null(elist)) elist= get.edgelist(graph.full(d))
	g=graph.edgelist(elist,directed=F)
	K = Kvec2(dat,m1,m2,elist)
	G = Gamma.ret2(dat,m1,m2,cores=dim(dat)[2],ge=elist)
	dd=dim(G[[1]]$v)[1]
	#dd=dim(G[[1]])[1]

	Ginv=mclapply(1:d,function(x) G[[x]]$v %*% ((1/((1/n)*G[[x]]$d^2+rho)) * t(G[[x]]$v)),mc.cores=d)
	#Ginv=mclapply(1:d,function(x) solve(G[[x]]+rho*diag(dd)),mc.cores=cores)
	print("Done.")
	znode = matrix(rnorm(d*m1)*1e-10,d,m1)
	zedge = array(rnorm(m2*m2*dim(elist)[1])*1e-10,dim=c(m2,m2,dim(elist)[1]))
	tol=Inf
	x=xold=y=zz=lapply(1:d,function(x)rep(0,dim(G[[x]]$v)[1]))
	admmout=list()
	lam=rev(sort(lam))
	if(d>=100) cores = detectCores()
	for(lamind in 1:length(lam)){
		print(paste("Run ",lamind," Begun"))
		if(lamind>1){
			x=admmout[[lamind-1]]$x
			y=admmout[[lamind-1]]$y
			zz=admmout[[lamind-1]]$zz
		}
		tol=Inf
		iter=0
		while(tol>1e-3 & iter<500){
		iter=iter+1
		# x step
		xold=x
		zedge_old=zedge
		znode_old=znode
		#print(lapply(y,function(x)length(x)))
		x=mclapply(1:d,function(i){
		#	print(dim(Ginv[[i]]))
		#	print(length(K[[i]]))
		#	print(length(y[[i]]))
			Ginv[[i]]%*%(-K[[i]] - y[[i]] + rho*zz[[i]])
		},mc.cores=cores)
		#z-y step
		for(i in 1:d){
			ii=sum(neighbors(g,i)<i)
			c= (ii)*m2^2+1
			ind=c: (c+m1-1)
			znode[i,] = (x[[i]][ind] + y[[i]][ind]/rho )
			znode[i,] = thresh(znode[i,],.01*lam[lamind]/rho)
			y[[i]][ind] = y[[i]][ind] + rho*( x[[i]][ind] - znode[i,])
			zz[[i]][ind] = znode[i,]
			for(j in neighbors(g,i)){

						jj =which(neighbors(g,i)==j)
						ii = which(neighbors(g,j)==i)

					if(i<j){
						c1 = m1+(jj-1)*m2^2+1
						c2 = (ii-1)*m2^2+1
					}else{
						c2 = m1+(ii-1)*m2^2+1
						c1 = (jj-1)*m2^2+1
					}

					e= which(elist[,1]%in%c(i,j) & elist[,2]%in%c(i,j))
					#c1 = ifelse(j>i , m1 + (j-2)*m2+1 ,(j-1)*m2+1 )
					#c2 = ifelse(j<i , m1 + (i-2)*m2+1 ,(i-1)*m2+1 )
					#if(length(e)==0) next
					#c1 = m1+(jj-1)*m2^2+1
					#c2 = (ii-1)*m2^2+1
					ind1 =c1:(c1+m2^2-1)
					ind2 =c2:(c2+m2^2-1)
					#print(ind1)
					#print(length(y[[i]]))
					#print(ind2)
					#print(length(y[[j]]))
					zedge[,,e] = .5* (x[[i]][ind1] + x[[j]][ind2] +
									y[[i]][ind1]/rho + y[[j]][ind2]/rho)
					zedge[,,e]=matrix( thresh(zedge[,,e],lam[lamind]/rho) , m2 , m2)

					y[[i]][ind1] = y[[i]][ind1] + rho*(x[[i]][ind1] - c(zedge[,,e]))
					y[[j]][ind2] = y[[j]][ind2] + rho*(x[[j]][ind2] - c(zedge[,,e]))
					zz[[i]][ind1] = c(zedge[,,e])
					zz[[j]][ind2] = c(zedge[,,e])
				}
			}

		#print(mean(abs(unlist(x)-unlist(zz))))
		#tol = mean(abs(unlist(xold)-unlist(x)))/mean(abs(unlist(xold))) #+ .5*mean(abs(unlist(x)-unlist(zz)))
		tol = ( sum(abs(zedge-zedge_old)) + sum(abs(znode-znode_old)) ) #/(sum(abs(znode_old))+sum(abs(zedge_old)))
			print(paste("tol:",tol))
		}
		#return(list(znode=znode,zedge=zedge))#list(z=zz,x=x,y=y,znode=znode,zedge=zedge))
		admmout[[lamind]]= list(x=x,y=y,zz=zz,znode=znode,zedge=zedge)
	}
	return(admmout)
}

#hyvar_score<-function(

################################

# coorDesc<-function(dat,lam,m1,m2){
# 	gr=Gamma.ret(dat,m1,m2)
# 	gn=Gamma.node(dat,m1,m2)
# 	kvn=Kvec.node(dat,m1)
# 	kve=Kvec.edge(dat,m2)
# 	tol=Inf
# 	d=dim(dat)[2]
# 	out.node.old=out.node=matrix(0,d,m1)
# 	out.edge.old=out.edge=array(0,dim=c(m2,m2,d*(d-1)/2))
# 	elist=get.edgelist(graph.full(d))
# 	while(tol>1e-3){
# 		for(i in 1:d){
# 			for(j in i:d){
# 				A = (gn[[i]][[j]]+gn[[j]][[i]])
# 				if(i!=j){
# 					ee= which(elist[,1]==i & elist[,2]==j)
# 					ind11 = which( (elist[,1]==j | elist[,2]==j) & elist[,1]!=i)
# 					ind12 = which( (elist[,1]==i | elist[,2]==i) & elist[,2]!=j)
# 					xx=crossprod(gr[[i]][[ee]] , out.node[i,])+
# 					    gr[[j]][[ee]] %*% out.node[j,] +
# 					    c(kve[,,ee])
# 				}else{
# 					ind11 = which( (elist[,1]==j | elist[,2]==j) )
# 					ind12 = which( (elist[,1]==i | elist[,2]==i) )
# 					xx = kvn[i,]
# 				}
# 				#print(paste(i," " ,j))
# 				#print(elist[ind11,])
# 				#print(elist[ind12,])
# 				xx=xx+Reduce("+",lapply(1:length(ind11), function(x){
# 					 if(elist[ind11[x],1]==j){
# 					 	gr[[i]][[ind11[x]]] %*% c(out.edge[,,ind12[x]])
# 					 }else{
# 					 	t(gr[[i]][[ind11[x]]]) %*% c(out.edge[,,ind12[x]])
# 					 }
# 					 }))
# 				xx=xx+Reduce("+",lapply(1:length(ind11), function(x){
# 				 if(elist[ind12[x],1]==i){
# 					 gr[[j]][[ind12[x]]] %*% c(out.edge[,,ind11[x]])
# 				}else{
# 					t(gr[[j]][[ind12[x]]]) %*% c(out.edge[,,ind11[x]])
# 				}
#
# 				 }))
# 				if(i==j){
# 					out.node[i,]=thresh(-xx,A,lam)
# 				}else{
# 					out.edge[,,ee] = matrix( thresh(-xx,A,lam) , m2,m2)
# 				}
# 			}
# 		}
# 		#print(out.edge)
# 		#print(out.node)
# 		#break
# 		tol = mean(abs(out.edge-out.edge.old))
# 		tol= tol + mean(abs(out.node.old-out.node))
# 		print(tol)
# 		out.node.old = out.node
# 		out.edge.old=out.edge
# 	}
# 	return(list(edge=out.edge,node=out.node))
# }


# Solution by Ismail Prada & Andreas Säuberli

# Lena Jäger
# Eyetracking: From experiment design to statistical and machine learning-based data analysis
# Assignment 4: Frequentist statistical analysis of a psycholinguistic eye-tracking-while-reading experiment

# Data set:
#    For a detailed description of the data set used in this assignment, please refer to:
#    Jäger, Mertzen, Van Dyke, & Vasishth: 'Interference patterns for subject-verb
#        agreement and reflexives revisited:  A large-sample study',
#        Journal of Memory and Language, 2020

# Experimental design:
#   2x2x2 fully crossed factorial desing:
#     Factor I: Dependency type: {subject-verb agreement; reflexive-antecedent binding}
#     Factor II: Grammaticality: {grammatical; ungrammatical}
#     Factor III: Similarity-based interference: {interference; no-intererence}

# Condition labels:
#   a  Agreement; grammatical; interference
#   b. Agreement; grammatical; no interference
#   c. Agreement; ungrammatical; no interference
#   d. Agreement; ungrammatical; interference
#   e. Reflexive; grammatical; interference
#   f. Reflexive; grammatical; no interference
#   g. Reflexive; ungrammatical; no interference
#   h. Reflexive; ungrammatical; interference

# Column names:
#   subj: subject id
#   item: item id
#   cond: condition id
#   acc: comprehension question response accuracy
#   roi: region of interest
#   FPRT: first-pass reading times in ms
#   TFT: total fixation times in ms
#   FPR: first-pass regression (binary)

library(coda)
library(plyr)
library(ggplot2)
library(xtable)
library(dplyr)
require(tidyr)
library(tidyverse)
extrafont::loadfonts()
library(reshape2)
require(lme4)

### RESEARCH QUESTIONS:
# 1. Are fixation times different in subject-verb agreement versus reflexive-antecedent dependencies?
# --> main effect of dependency type
# 2. Are fixation times different in ungrammatical versus grammatical conditions?
# --> main effect of grammaticality
# 3. Are fixation times affected by interference?
# --> main effect of interference
# 4. Does the grammaticality effect differ between the two dependency types?
# --> interaction between grammaticality and dependency type
# 5. Does the interference effect differ between grammatical and ungrammatical conditions?
# --> interaction between interference and grammaticality
# 6. Does the interference effect differ between dependency types?
# --> interaction between interference and dependency type
# 7. Does the (possible) difference in the sensitivity to the interference manipulation of
#     grammatical versus ungrammatical conditions differ between subject-verb agreement and reflexive-antecedent dependencies?
# --> 3-way interaction between interference, grammaticality and dependency type

# Critical region: were/was/himself/themselves (= roi 12)
# Dependent variable: total fixation times

#### Load and format the data
d <- read.table(file='dataJMVV.txt', sep = '\t')

#### Inspect the data and answer the following questions:
# How many conditions are there? How many instances of each condition?
# 8 conditions (+filler), counts:
# a      b      c      d      e      f  filler      g      h
# 22659  22659  22659  22596  22680  22638 482412  22680  22617
# How many subjects and items are there?
# 181 subjects
# 176 items
# NOTE: This could also be answered by converting these columns to factors first and then use str()
# How many times did each subject see each item? Hint: use xtabs() )
# 21 times
# What was the average response accuracy for each of the conditions? Hint: use tapply()
# a           b           c           d           e           f
# -0.05560704 -0.05838740 -0.05004634 -0.06133829 -0.07129630 -0.05751391
# filler           g           h
# -0.04718788 -0.05185185 -0.05292479
########################################################
head(d, 3)
d$cond <- factor(d$cond)
summary(d$cond)
length(unique(d$subj))
length(unique(d$item))
xtabs(~subj+item, d)
tapply(d$acc, d$cond, mean)
########################################################

### Convert the subj, item and cond columns to factors
########################################################
d$subj <- factor(d$subj)
d$item <- factor(d$item)
d$cond <- factor(d$cond)
str(d)
########################################################

# Exlcude filler trials and remove all rows from other than the critical region (roi 12)
########################################################
d_crit <- d[d$cond != "filler" & d$roi == 12, ]
########################################################

# Note: when removing all rows with a certain level of a factor, this level still exists, it simply has 0 instances:
summary(d$cond) # before removing the fillers
summary(d_crit$cond) # after removing the fillers
# We can fix this by simply conveting cond to a factor again:
########################################################
d_crit$cond <- factor(d_crit$cond)
########################################################

#### Define contrasts
# Create hypothesis matrix from the given research questions
# main effects of dependency and grammaticality and their interaction (applied in Model 1 and 2)
X_H <- matrix(c( 1/8,  1/8,  1/8,  1/8,  1/8,  1/8,  1/8,  1/8, # Intercept
                 1/4,  1/4,  1/4,  1/4, -1/4, -1/4, -1/4, -1/4, # Main effect dependency type
                -1/4, -1/4,  1/4,  1/4, -1/4, -1/4,  1/4,  1/4, # Main effect grammaticality
                 1/4, -1/4, -1/4,  1/4,  1/4, -1/4, -1/4,  1/4, # Main effect of interference
                -1/4, -1/4,  1/4,  1/4,  1/4,  1/4, -1/4, -1/4, # Grammaticality x Dependency
                -1/4,  1/4, -1/4,  1/4, -1/4,  1/4, -1/4,  1/4, # Interference x Grammaticality
                 1/4, -1/4, -1/4,  1/4, -1/4,  1/4,  1/4, -1/4, # Interference x Dependency type
                -1/4,  1/4, -1/4,  1/4,  1/4, -1/4,  1/4, -1/4  # Interference x Grammaticality x Dependency
), byrow=TRUE, nrow = 8)

# Compute the inverse of X_H
########################################################
library(MASS)  # need this for ginv()
X_C <- ginv(X_H)
########################################################

# For better readibility add column and row names:
rownames(X_C) <- c('a','b','c','d','e','f','g','h')
colnames(X_C) <- c('Intercept','Dep','Gram','Int','Gram_x_Dep','Int_x_Gram','Int_x_Dep','Int_x_Gram_x_Dep')

# Remove intercept column
########################################################
X_C_bar <- X_C[,2:ncol(X_C)]
########################################################

# Apply the contrasts to the cond column
########################################################
contrasts(d_crit$cond) <- X_C_bar
########################################################

#--------------------------------------------------------
#--------------------------------------------------------
# OR:
# Alternative: code contrasts as numerical columns in the dataframe and use these as predictors in the model

# NOTE: Why did they use d and not d_crit here?
d_crit$Dep <- ifelse(d_crit$cond %in% c('a', 'b', 'c', 'd'), .5, -.5) # main effect of dependency type: agr=0.5, refl=-0.5
d_crit$Gram <- ifelse(d_crit$cond %in% c('a', 'b', 'e', 'f'), -.5, .5) # main effect of grammaticality: gram=-.5, ungram=.5
# ... add the other contrasts
########################################################
d_crit$Int <- ifelse(d_crit$cond %in% c('a', 'd', 'e', 'h'), .5, -.5)
d_crit$Gram_x_Dep <- ifelse(d_crit$cond %in% c('c', 'd', 'e', 'f'), .5, -.5)
d_crit$Int_x_Gram <- ifelse(d_crit$cond %in% c('b', 'd', 'f', 'h'), .5, -.5)
d_crit$Int_x_Dep <- ifelse(d_crit$cond %in% c('a', 'd', 'f', 'g'), .5, -.5)
d_crit$Int_x_Gram_x_Dep <- ifelse(d_crit$cond %in% c('b', 'd', 'e', 'g'), .5, -.5)
########################################################

#--------------------------------------------------------
#--------------------------------------------------------

# Remove trials in which the dependent variable (TFT) is zero (i.e., trials in which the critical region was never fixated)
########################################################
d_crit_tft <- d_crit[d_crit$TFT != 0, ]
########################################################
# How many trials (=rows) in % are removed by selecting only the ones with TFT larger than 0?
# 0.07765415 => 7.77% of all trials were removed
########################################################
1 - nrow(d_crit_tft) / nrow(d_crit)
########################################################

# Fit a linear mixed model with log transformed total fixation times as dependent variable and the above defined contrasts as predictor variables (independent variables)
library(lme4)
########################################################
# With contrasts coded as columns:
m <- lmer(log(TFT)~
            Dep+
            Gram+
            Int+
            Gram_x_Dep+
            Int_x_Gram+
            Int_x_Dep+
            Int_x_Gram_x_Dep+
            (1|subj)+
            (1|item),
            data=d_crit_tft)
########################################################
# With contrasts coded using contrasts():
m <- lmer(log(TFT)~cond+(1|subj)+(1|item), data=d_crit_tft)
summary(m)

# Interpret the model output verbally.
########################################################
# t values for Dep and Gram are large enough to be significant,
# i.e. dependency type and grammaticality have a significant
# effect on logarithmic total fixation time.
# The estimated betas for these contrasts are positive, which means:
# - Subject-verb agreement has larger TFT than reflexive-antecedent binding
# - Ungrammatical items have larger TFT than grammatical ones
# The other contrasts do not show significant effects.
########################################################

# We have modeled log(TFT). However, for the conceptual interpretation, it is often easier to express the effect sizes on the ms-scale rather than the log-ms scale
# Compute the effect sizes of the predictors to the ms-scale. H

# Effect of dependency type on the ms scale
########################################################
# NOTE: Not sure if this is really what they mean...

# A change from "reflexive" to "agreement" dependency type increases log(TFT) by 0.2775904
# This corresponds to multiplying TFT by e^0.2775904 = 1.319945
ms_effects <- exp(fixef(m))
ms_effects["condDep"]

# For example, the average TFT for the "reflexive" dependency type is 553.5267 ms:
average_reflexive_tft <-
    d_crit_tft %>%
    filter(cond %in% c("e", "f", "g", "h")) %>%
    summarize(mean(TFT))

# Applying a factor of 1.319945 would mean an expected increase by 177.0983 ms
# when changing the dependency type to "agreement":
ms_increase <- average_reflexive_tft * ms_effects["condDep"] - average_reflexive_tft
########################################################


#!/usr/local/bin/Rscript --vanilla

###############################################################################
# METAREP : High-Performance Comparative Metagenomics Framework (http://www.jcvi.org/metarep)
# Copyright(c)  J. Craig Venter Institute (http://www.jcvi.org)
#
# Licensed under The MIT License
# Redistributions of files must retain the above copyright notice.
#
# link http://www.jcvi.org/metarep METAREP Project
# package metarep
# version METAREP v 1.3.2
# author Johannes Goll
# lastmodified 2010-07-09
# license http://www.opensource.org/licenses/mit-license.php The MIT License
###############################################################################

library(edgeR);
library(methods);

## get command line arguments
args 					= commandArgs(TRUE)

infile 					= args[1];
outfile 				= args[2];
propround 				= as.numeric(args[3]);
pvalround 				= as.numeric(args[4]);
startIndexPopulationB	= as.numeric(args[5]);
populationNameA			= args[6];
populationNameB			= args[7];

## get edgeR DGE List object
targets = read.delim(infile,stringsAsFactors=F);
dgeList = readDGE(targets);
features = rownames(dgeList$counts);
m  = as.matrix(dgeList$counts);

## get number of datasets
ncols = as.numeric(length(m[1,]));
nrows = as.numeric(length(m[,1]));

## get counts for each population
posA = seq(1,(startIndexPopulationB-1));

posB = seq(startIndexPopulationB,ncols);
cntA = apply(m[,posA],1,sum);
cntB = apply(m[,posB],1,sum);

## estimate common dispersion
commonDispersion = estimateCommonDisp(dgeList);

## execute exact negative binomial test
edgeResults = exactTest(commonDispersion,pair=c(populationNameA,populationNameB));
edgeResultTable = edgeResults$table;

## top ten results for smear plot
#topTenEdgeResults = topTags(edgeResults);
#pdf(outfile||".pdf");

## init metarep result matrix
columns  = c("id","count1","count2","logConc","logFC","disp","p_value","b_value","q_value");
metarepResults = data.frame(matrix(rep(NA,9*nrows),ncol=9),stringsAsFactors=F);
colnames(metarepResults) = columns;

## set metarep result values
metarepResults[,1] = features;
metarepResults[,2] = cntA;
metarepResults[,3] = cntB;
metarepResults[,4] = round(edgeResultTable$logConc,4);
metarepResults[,5] = round(edgeResultTable$logFC,4);
metarepResults[,6] = round(commonDispersion$common.dispersion,4);
metarepResults[,7] = round(edgeResultTable$p.value,pvalround);
metarepResults[,8] = round(p.adjust(edgeResultTable$p.value, method = "fdr"),pvalround);
metarepResults[,9] = round(p.adjust(edgeResultTable$p.value, method = "bonferroni"),pvalround);

## write results to tab delimites output file
write.table(metarepResults,file=outfile,row.names=F,sep ="\t",eol="\n",append=F,quote=F);

## exit
q(status=0)


stem <- c("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸")
branch <- c("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥")
stembranch <- function(year) {
  return(paste0(stem[(year-3)%%10], branch[(year-3)%%12]))
}


########################### BayesKin ###########################
## Bayesian estimates of rigid body kinematics
## Andy Pohl
## UofC - Faculty of Kinesiology

## Written by: Andy Pohl
## UofC - Faculty of Kinesiology
## June-Dec 2020
## Revision 1: April 2021
################################################################

##################### generate_results.r  ###################
## processes_results table for a batch of simulations
#############################################################

# preliminaries
rm(list = ls()) # clear workspace

library('dplyr')
library('latex2exp')
library('xtable')
library('coda')
WORKING_DIR = "" # Replace with the location of the BayesKin/src directory on the local PC.
setwd(WORKING_DIR)
RESULTS_DIR = paste0(WORKING_DIR, "/src/") # location of results directory

setwd(RESULTS_DIR)
# Load results file

FILENAME = "" # Filename of .rda result file produced by process_results.r
results = readRDS(FILENAME)
results = data.frame(results, stringsAsFactors = F)
results$model = factor(results$model, levels = c('LS', "Bayes_p1", "Bayes_p2", "Bayes_p3", "Bayes_p4", "Bayes_p5"))
results$parameter = factor(results$parameter, levels = c('r1', "r2", "theta1", "theta2", "theta3", "sigma"))
# Convert r/sigma to mm
results[results$parameter %in% c('r1', 'r2', 'sigma'),c('est', 'quantile.1', 'quantile.2', 'quantile.3', 'quantile.4', 'quantile.5')] = results[results$parameter %in% c('r1', 'r2', 'sigma'),c('est', 'quantile.1', 'quantile.2', 'quantile.3', 'quantile.4', 'quantile.5')]*1000

# Set constants
POSES = c("SingleLink", "DoubleLink", "TripleLink")
MODELS = c("LS", "Bayes_p1", "Bayes_p2", "Bayes_p3", "Bayes_p4", "Bayes_p5")
PARMS = c("r1", "r2", "theta1", "theta2", "theta3", "sigma")
PARMLABS = list(r1=TeX("$r_1 \\,  (mm)$"), r2=TeX("$r_2  \\, (mm)$"), theta1=TeX("$\\theta_1 \\, (^o)$"),
                theta2=TeX("$\\theta_2 \\, (^o)$"), theta3=TeX("$\\theta_3\\, (^o) "), sigma=TeX("$\\sigma \\, (mm)$"))
MODELLABS = c("LS", "Bayes P1", "Bayes P2", "Bayes P3", "Bayes P4", "Bayes P5")

TRUEVALS = list(r1 = 0.07*1000, r2 = 0.03*1000,
                theta1 = -55, theta2 = -110, theta3 = -10, sigma = 1.5/1000 *1000)

################################################################################
## FILTERING Poor MCMC convergence
################################################################################
# identify poor MCMC convergence
bad_seeds = results %>% group_by(pose) %>% filter(rhat>1.1) %>% select(pose, model, seed) %>% distinct()
bad_seeds %>% summarise(n_distinct(seed))

results = results[!((results$seed %in% bad_seeds$seed[bad_seeds$pose == 'SingleLink']) & (results$pose == 'SingleLink')),]
results = results[!((results$seed %in% bad_seeds$seed[bad_seeds$pose == 'DoubleLink']) & (results$pose == 'DoubleLink')),]
results = results[!((results$seed %in% bad_seeds$seed[bad_seeds$pose == 'TripleLink']) & (results$pose == 'TripleLink')),]

# filter to only 1000 iterations per pose
results_temps = results[results$pose =='SingleLink',]
temp_seeds = unique(results_temps$seed)
results_temps = results_temps[results_temps$seed %in% temp_seeds[1:1000],]

results_tempd = results[results$pose =='DoubleLink',]
temp_seeds = unique(results_tempd$seed)
results_tempd = results_tempd[results_tempd$seed %in% temp_seeds[1:1000],]

results_tempt = results[results$pose =='TripleLink',]
temp_seeds = unique(results_tempt$seed)
results_tempt = results_tempt[results_tempt$seed %in% temp_seeds[1:1000],]

results = rbind(results_temps, results_tempd, results_tempt)

results %>% group_by(pose) %>% summarise(n_distinct(seed))

################################################################################
## MCMC convergence summary
################################################################################

MCMC_summary = results %>% filter(model != "LS") %>%
    group_by(pose, model, parameter) %>%
    summarise( mean_neff = mean(rhat), sd_neff = sd(rhat))

xtable(MCMC_summary)

################################################################################
## Table 1: Bias, variance, mse and RMSE
################################################################################

tab1 = results %>% group_by(pose, model, parameter) %>% summarize(bias = mean(est), var = sd(est)^2)

parms = c("r1", "r2", "theta1", "theta2", "theta3", "sigma")
for(i in 1:length(parms)){
    tab1$bias[tab1$parameter == parms[i]] = tab1$bias[tab1$parameter == parms[i]] - TRUEVALS[[parms[i]]]
}
tab1$bias[tab1$parameter %in% c('r1', 'r2', 'sigma')] = tab1$bias[tab1$parameter %in% c('r1', 'r2', 'sigma')]
tab1$mse = tab1$bias^2 + tab1$var
tab1$rmse = sqrt(tab1$mse)

print(xtable(tab1[,c('pose', 'model', 'parameter', 'rmse')], digits = 3), include.rowname=F)

################################################################################
## FIGURE 1 strip charts
################################################################################
deltadeg = 2
deltar = .02 *1000
axislimits = list(r1 = TRUEVALS[[1]] +  c(-deltar, deltar),
                  r2 = TRUEVALS[[2]] +  c(-deltar, deltar),
                  theta1 = TRUEVALS[[3]] + c(-deltadeg, deltadeg),
                  theta2 = TRUEVALS[[4]] + c(-deltadeg, deltadeg),
                  theta3 = TRUEVALS[[5]] + c(-deltadeg, deltadeg),
                  sigma = c(0, 0.01))
axislimits$sigma = axislimits$sigma*1000

colors = list(grey = rgb(97/255, 97/255,97/255, 0.2),
              orange = rgb(241/255, 136/255,5/255, 1),
              blue = rgb(18/255, 78/255,120/255,  0.2),
              red = rgb(162/255, 0/255,33/255, 0.2),
              green = rgb(76/255, 159/255, 112/255, 0.2),
              purple = rgb(217/255, 187/255, 249/255, 0.2),
              pink = rgb(217/255, 3/255, 104/255, 0.2))

point_cols = list(colors$pink, colors$blue, colors$green, colors$purple)

# Adjust the following to choose what is plotted in the nparmsx4 grid of plots.
MODELS = c("LS", "Bayes_p1", "Bayes_p2", "Bayes_p3")
MODELLABS = c("LS", "Bayes P1", "Bayes P2", "Bayes P3")
################################################################################
## Single Link
################################################################################
sl_results = results %>% filter(pose == 'SingleLink')
par(mfcol = c(4,4), mar = c(3, 1, 1,1), mgp = c(2,0.5,0), cex.lab = 1.2, cex.main = 1.2)
for(i in 1:length(MODELS)){
    m_results = sl_results %>% filter(model == MODELS[i])
    ps = unique(m_results$parameter)
    for(j in 1:length(ps)){
        est = m_results %>% filter(parameter == ps[j]) %>% select(est)
        if(j ==1){
            plot(x = est[,1], y = runif(length(est[,1]), 0, 0.1),
                 xlim = get(as.character(ps[j]),axislimits), ylim = c(-0.03,0.25),
                 pch = 16, col = point_cols[[i]],
                 xlab = get(as.character(ps[j]),PARMLABS),
                 ylab =NA, yaxt='n', bty = 'n',
                 main = MODELLABS[i])
        }else{
            plot(x = est[,1], y = runif(length(est[,1]), 0, 0.1),
                 xlim = get(as.character(ps[j]),axislimits), ylim = c(-0.03,0.25),
                 pch = 16, col =  point_cols[[i]],
                 xlab = get(as.character(ps[j]),PARMLABS),  bty = 'n',
                 ylab =NA, yaxt='n')
        }

        segments(x0=TRUEVALS[[ps[j]]], y0=-0.02, x1=TRUEVALS[[ps[j]]], y1=0.12, col = colors$orange, lwd=1.5)
    }
}

################################################################################
## Double Link
################################################################################
sl_results = results %>% filter(pose == 'DoubleLink')
par(mfcol = c(5,4), mar = c(3, 1, 1,1), mgp = c(2,0.5,0), cex.lab = 1.2, cex.main = 1.2)
for(i in 1:length(MODELS)){
    m_results = sl_results %>% filter(model == MODELS[i])
    ps = unique(m_results$parameter)
    for(j in 1:length(ps)){
        est = m_results %>% filter(parameter == ps[j]) %>% select(est)
        if(j ==1){
            plot(x = est[,1], y = runif(length(est[,1]), 0, 0.1),
                 xlim = get(as.character(ps[j]),axislimits), ylim = c(-0.03,0.25),
                 pch = 16, col = point_cols[[i]],
                 xlab = get(as.character(ps[j]),PARMLABS), ylab =NA, yaxt='n', bty = 'n',
                 main = MODELLABS[i])
        }else{
            plot(x = est[,1], y = runif(length(est[,1]), 0, 0.1),
                 xlim = get(as.character(ps[j]),axislimits),ylim = c(-0.03,0.25),
                 pch = 16, col = point_cols[[i]],
                 xlab = get(as.character(ps[j]),PARMLABS), ylab =NA, yaxt='n', bty = 'n')
        }

        segments(x0=TRUEVALS[[ps[j]]], y0=-0.02, x1=TRUEVALS[[ps[j]]], y1=0.12, col = colors$orange, lwd=1.5)
    }
}

################################################################################
## Triple Link
################################################################################
sl_results = results %>% filter(pose == 'TripleLink')
par(mfcol = c(6,4), mar = c(3, 1, 1,1), mgp = c(2,0.5,0), cex.lab = 1.2, cex.main = 1.2)
for(i in 1:length(MODELS)){
    m_results = sl_results %>% filter(model == MODELS[i])
    ps = unique(m_results$parameter)
    for(j in 1:length(ps)){
        est = m_results %>% filter(parameter == ps[j]) %>% select(est)
        if(j ==1){
            plot(x = est[,1], y = runif(length(est[,1]), 0, 0.1),
                 xlim = get(as.character(ps[j]),axislimits), ylim = c(-0.03,0.25),
                 pch = 16, col = point_cols[[i]],
                 xlab = get(as.character(ps[j]),PARMLABS), ylab =NA, yaxt='n', bty = 'n',
                 main = MODELLABS[i])
        }else{
            plot(x = est[,1], y = runif(length(est[,1]), 0, 0.1),
                 xlim = get(as.character(ps[j]),axislimits), ylim = c(-0.03,0.25),
                 pch = 16, col = point_cols[[i]],
                 xlab = get(as.character(ps[j]),PARMLABS), ylab =NA, yaxt='n', bty = 'n')
        }
        segments(x0=TRUEVALS[[ps[j]]], y0=-0.02, x1=TRUEVALS[[ps[j]]], y1=0.12, col = colors$orange, lwd=1.5)
    }
}

################################################################################
## Table 2: EQULIIVANCE
################################################################################

## Prior 1
p1 = results %>% filter(model =='Bayes_p1' )
Bayes_perf = data.frame(seed = numeric(), pose = character(), model = character(), parameter = character(),
                        equilivance_ls = numeric(), equilivance_true = numeric(),outperformed = numeric())
for(i in 1:length(POSES)){
    temp = p1 %>% filter(pose == POSES[i])
    ps = unique(temp$parameter)
    for(j in 1:length(ps)){
        print(sprintf("Computing Pose %s, parameter: %s", POSES[i], ps[j]))
        temp1 = temp %>% filter(parameter == ps[j])
        seeds = unique(temp1$seed)
        for(k in 1:length(seeds)){
            tmpseed = seeds[k]
            print(sprintf("    seed: %s", as.character(tmpseed)))

            ls_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'LS') %>% select(est)
            bayes_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'Bayes_p1') %>% select(est)

            # Equilivance of Bayes and LS
            if((temp$est[k] - (2* temp1$ts_se[k]) < ls_est)  &(temp1$est[k] + (2* temp1$ts_se[k]) > ls_est)){
                tmpcvgls = 1
            } else{
                tmpcvgls =0
            }

            # equilivance of Bayes and True Val
            if((temp$est[k] - (2* temp1$ts_se[k]) < TRUEVALS[[ps[j]]])  &(temp1$est[k] + (2* temp1$ts_se[k]) > TRUEVALS[[ps[j]]])){
                tmpcvgtrue = 1
            } else{
                tmpcvgtrue =0
            }

            tmpimprv = as.numeric((abs(bayes_est - TRUEVALS[[ps[j]]])) < (abs(ls_est  - TRUEVALS[[ps[j]]])))

            toappend = data.frame(seed = tmpseed, pose = POSES[i], model = "Bayes_p1", parameter = ps[j],
                                  equilivance_ls = tmpcvgls, equilivance_true = tmpcvgtrue, outperformed = tmpimprv)
            Bayes_perf = rbind(Bayes_perf, toappend)

        }

    }
}

Bayes_perf_p1 = Bayes_perf %>% group_by(pose, model, parameter) %>% summarize(equilivance_ls = mean(equilivance_ls), equilivance_true = mean(equilivance_true),
                                                                              perf = mean(outperformed))

## Prior 2
p2 = results %>% filter(model =='Bayes_p2' )
Bayes_perf = data.frame(seed = numeric(), pose = character(), model = character(), parameter = character(),
                        equilivance_ls = numeric(), equilivance_true = numeric(),outperformed = numeric())
for(i in 1:length(POSES)){
    temp = p2 %>% filter(pose == POSES[i])
    ps = unique(temp$parameter)
    for(j in 1:length(ps)){
        print(sprintf("Computing Pose %s, parameter: %s", POSES[i], ps[j]))
        temp1 = temp %>% filter(parameter == ps[j])
        seeds = unique(temp1$seed)
        for(k in 1:length(seeds)){
            tmpseed = seeds[k]
            print(sprintf("    seed: %s", as.character(tmpseed)))

            ls_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'LS') %>% select(est)
            bayes_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'Bayes_p2') %>% select(est)

            # Equilivance of Bayes and LS
            if((temp$est[k] - (2* temp1$ts_se[k]) < ls_est)  &(temp1$est[k] + (2* temp1$ts_se[k]) > ls_est)){
                tmpcvgls = 1
            } else{
                tmpcvgls =0
            }

            # equilivance of Bayes and True Val
            if((temp$est[k] - (2* temp1$ts_se[k]) < TRUEVALS[[ps[j]]])  &(temp1$est[k] + (2* temp1$ts_se[k]) > TRUEVALS[[ps[j]]])){
                tmpcvgtrue = 1
            } else{
                tmpcvgtrue =0
            }

            tmpimprv = as.numeric((abs(bayes_est - TRUEVALS[[ps[j]]])) < (abs(ls_est  - TRUEVALS[[ps[j]]])))

            toappend = data.frame(seed = tmpseed, pose = POSES[i], model = "Bayes_p2", parameter = ps[j],
                                  equilivance_ls = tmpcvgls, equilivance_true = tmpcvgtrue, outperformed = tmpimprv)
            Bayes_perf = rbind(Bayes_perf, toappend)

        }

    }
}

Bayes_perf_p2 = Bayes_perf %>% group_by(pose, model, parameter) %>% summarize(equilivance_ls = mean(equilivance_ls), equilivance_true = mean(equilivance_true),
                                                                              perf = mean(outperformed))

## Prior 3
p3 = results %>% filter(model =='Bayes_p3' )
Bayes_perf = data.frame(seed = numeric(), pose = character(), model = character(), parameter = character(),
                        equilivance_ls = numeric(), equilivance_true = numeric(),outperformed = numeric())
for(i in 1:length(POSES)){
    temp = p3 %>% filter(pose == POSES[i])
    ps = unique(temp$parameter)
    for(j in 1:length(ps)){
        print(sprintf("Computing Pose %s, parameter: %s", POSES[i], ps[j]))
        temp1 = temp %>% filter(parameter == ps[j])
        seeds = unique(temp1$seed)
        for(k in 1:length(seeds)){
            tmpseed = seeds[k]
            print(sprintf("    seed: %s", as.character(tmpseed)))

            ls_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'LS') %>% select(est)
            bayes_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'Bayes_p3') %>% select(est)

            # Equilivance of Bayes and LS
            if((temp$est[k] - (2* temp1$ts_se[k]) < ls_est)  &(temp1$est[k] + (2* temp1$ts_se[k]) > ls_est)){
                tmpcvgls = 1
            } else{
                tmpcvgls =0
            }

            # equilivance of Bayes and True Val
            if((temp$est[k] - (2* temp1$ts_se[k]) < TRUEVALS[[ps[j]]])  &(temp1$est[k] + (2* temp1$ts_se[k]) > TRUEVALS[[ps[j]]])){
                tmpcvgtrue = 1
            } else{
                tmpcvgtrue =0
            }

            tmpimprv = as.numeric((abs(bayes_est - TRUEVALS[[ps[j]]])) < (abs(ls_est  - TRUEVALS[[ps[j]]])))

            toappend = data.frame(seed = tmpseed, pose = POSES[i], model = "Bayes_p3", parameter = ps[j],
                                  equilivance_ls = tmpcvgls, equilivance_true = tmpcvgtrue, outperformed = tmpimprv)
            Bayes_perf = rbind(Bayes_perf, toappend)

        }

    }
}

Bayes_perf_p3 = Bayes_perf %>% group_by(pose, model, parameter) %>% summarize(equilivance_ls = mean(equilivance_ls), equilivance_true = mean(equilivance_true),
                                                                              perf = mean(outperformed))

## Prior 4
p4 = results %>% filter(model =='Bayes_p4' )
Bayes_perf = data.frame(seed = numeric(), pose = character(), model = character(), parameter = character(),
                        equilivance_ls = numeric(), equilivance_true = numeric(),outperformed = numeric())
for(i in 1:length(POSES)){
    temp = p4 %>% filter(pose == POSES[i])
    ps = unique(temp$parameter)
    for(j in 1:length(ps)){
        print(sprintf("Computing Pose %s, parameter: %s", POSES[i], ps[j]))
        temp1 = temp %>% filter(parameter == ps[j])
        seeds = unique(temp1$seed)
        for(k in 1:length(seeds)){
            tmpseed = seeds[k]
            print(sprintf("    seed: %s", as.character(tmpseed)))

            ls_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'LS') %>% select(est)
            bayes_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'Bayes_p4') %>% select(est)

            # Equilivance of Bayes and LS
            if((temp$est[k] - (2* temp1$ts_se[k]) < ls_est)  &(temp1$est[k] + (2* temp1$ts_se[k]) > ls_est)){
                tmpcvgls = 1
            } else{
                tmpcvgls =0
            }

            # equilivance of Bayes and True Val
            if((temp$est[k] - (2* temp1$ts_se[k]) < TRUEVALS[[ps[j]]])  &(temp1$est[k] + (2* temp1$ts_se[k]) > TRUEVALS[[ps[j]]])){
                tmpcvgtrue = 1
            } else{
                tmpcvgtrue =0
            }

            tmpimprv = as.numeric((abs(bayes_est - TRUEVALS[[ps[j]]])) < (abs(ls_est  - TRUEVALS[[ps[j]]])))

            toappend = data.frame(seed = tmpseed, pose = POSES[i], model = "Bayes_p4", parameter = ps[j],
                                  equilivance_ls = tmpcvgls, equilivance_true = tmpcvgtrue, outperformed = tmpimprv)
            Bayes_perf = rbind(Bayes_perf, toappend)

        }

    }
}

Bayes_perf_p4 = Bayes_perf %>% group_by(pose, model, parameter) %>% summarize(equilivance_ls = mean(equilivance_ls), equilivance_true = mean(equilivance_true),
                                                                              perf = mean(outperformed))

## Prior 5
p5 = results %>% filter(model =='Bayes_p5' )
Bayes_perf = data.frame(seed = numeric(), pose = character(), model = character(), parameter = character(),
                        equilivance_ls = numeric(), equilivance_true = numeric(),outperformed = numeric())
for(i in 1:length(POSES)){
    temp = p5 %>% filter(pose == POSES[i])
    ps = unique(temp$parameter)
    for(j in 1:length(ps)){
        print(sprintf("Computing Pose %s, parameter: %s", POSES[i], ps[j]))
        temp1 = temp %>% filter(parameter == ps[j])
        seeds = unique(temp1$seed)
        for(k in 1:length(seeds)){
            tmpseed = seeds[k]
            print(sprintf("    seed: %s", as.character(tmpseed)))

            ls_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'LS') %>% select(est)
            bayes_est = results %>% filter(seed == tmpseed, parameter == ps[j], pose == POSES[i], model == 'Bayes_p5') %>% select(est)

            # Equilivance of Bayes and LS
            if((temp$est[k] - (2* temp1$ts_se[k]) < ls_est)  &(temp1$est[k] + (2* temp1$ts_se[k]) > ls_est)){
                tmpcvgls = 1
            } else{
                tmpcvgls =0
            }

            # equilivance of Bayes and True Val
            if((temp$est[k] - (2* temp1$ts_se[k]) < TRUEVALS[[ps[j]]])  &(temp1$est[k] + (2* temp1$ts_se[k]) > TRUEVALS[[ps[j]]])){
                tmpcvgtrue = 1
            } else{
                tmpcvgtrue =0
            }

            tmpimprv = as.numeric((abs(bayes_est - TRUEVALS[[ps[j]]])) < (abs(ls_est  - TRUEVALS[[ps[j]]])))

            toappend = data.frame(seed = tmpseed, pose = POSES[i], model = "Bayes_p5", parameter = ps[j],
                                  equilivance_ls = tmpcvgls, equilivance_true = tmpcvgtrue, outperformed = tmpimprv)
            Bayes_perf = rbind(Bayes_perf, toappend)

        }

    }
}

Bayes_perf_p5 = Bayes_perf %>% group_by(pose, model, parameter) %>% summarize(equilivance_ls = mean(equilivance_ls), equilivance_true = mean(equilivance_true),
                                                                              perf = mean(outperformed))
Bayes_perf = rbind(Bayes_perf_p1, Bayes_perf_p2, Bayes_perf_p3, Bayes_perf_p4, Bayes_perf_p5)

Bayes_perf

################################################################################
## Computational time.
################################################################################
comp_time = results %>% select(pose, seed, model, run_time) %>% group_by(pose, model)
comp_time = unique(comp_time)
comp_time = comp_time %>% summarise(run_time_mean = mean(run_time), run_time_sd = sd(run_time))

#   temp = Bayes_perf %>% group_by(pose, model, parameter) %>% summarise(equilivance = mean(coverage), perf = mean(outperformed))
xtable(comp_time, digits = 2)

#####################################################################################
## Plot likelihoods
#####################################################################################
source('./library.r')

set.seed(4)

## 1) Specify parameters
n.links = 3               # Number of links.
seg.length = c(0.45, 0.35, 0.25)         # Length of segment specified in m. NB: Pataky pg 2.
r_true = c(0.07, 0.03)      # Origin location in m.
theta_true = c(-55, -110, -10)          # Rotation angle in deg. NB: specified to avoid 0/360 issue
# and mirroring solutions.
sigma_true = 1.5/1000       # Measurement noise in m. NB Noise specified as 1.5mm
# midpoint of range explored by Pataky et al.
true_vals = c(r_true = r_true, theta_true = theta_true, sigma_true = sigma_true)

# Generate posture
links = list(gen_link(seg.length = seg.length[1],
                      plate.center = 0.7*seg.length[1]),
             gen_link(seg.length = seg.length[2],
                      plate.center = 0.5*seg.length[2]),
             gen_link(seg.length = seg.length[3],
                      plate.center = 0.5*seg.length[3]))
posture = gen_posture(links, r = r_true, theta = theta_true)
y = gen_obs(posture, sigma_true)

LS_result = LS_soln(y, links,
                    inits = true_vals,
                    init_type = 'random' )
inits = c(0.0446749866008758, 0.012961977859959, -40.1004006620497, 88.534386176616, 142.351554371417)
# lik for r
rs = seq(-1, 1, by = 0.01)
costs = matrix(NA, nrow = length(rs), ncol = length(rs))
for(i in 1:length(rs)){
    for(j in 1:length(rs)){
        costs[i,j] = cost(params = c(rs[i], rs[j], true_vals[3:5]), y =y, links = links)
    }
}

filled.contour(x=rs, y = rs, z=costs,
               color = function(n) rev(hcl.colors(n, "Spectral")),
               main = 'Cost for R', xlab = 'r1', ylab = 'r2', nlevels = 30,
               plot.axes={points(true_vals[1], true_vals[2], pch = 3, col = 'green')
                   points(LS_result$r.hat[1], LS_result$r.hat[2], pch = 3, col = 'blue')
                   points(inits[1], inits[2], pch = 3, col = 'black')
                   axis(1, seq(-1, 1, by = 0.1))
                   axis(2, seq(-1, 1, by = 0.1))})

# lik for theta 1 vs 2
thetas = seq(-360, 360, by = 1)
costs = matrix(NA, nrow = length(thetas), ncol = length(thetas))
for(i in 1:length(thetas)){
    for(j in 1:length(thetas)){
        costs[i,j] = cost(params = c(true_vals[1:2], thetas[i], thetas[j], true_vals[5]), y =y, links = links)
    }
}

filled.contour(x=thetas, y = thetas, z=costs,
               color = function(n) rev(hcl.colors(n, "Spectral")),
               main = 'Cost for theta', xlab = 'theta1', ylab = 'theta2', nlevels = 30,
               plot.axes={points(true_vals[3], true_vals[4], pch = 3, col = 'green')
                   points(LS_result$theta.hat[1], LS_result$theta.hat[2], pch = 3, col = 'blue')
                   points(inits[3], inits[4], pch = 3, col = 'black')
                   axis(1, seq(-360, 360, by = 45))
                   axis(2, seq(-360, 360, by = 45))})

# lik for theta 2 vs 3
thetasi = seq(-135, 135, length.out = 500)
thetasj = seq(-45, 270, length.out = 500)

costs = matrix(NA, nrow = length(thetasi), ncol = length(thetasj))
for(i in 1:length(thetasi)){
    for(j in 1:length(thetasj)){
        costs[i,j] = cost(params = c(true_vals[1:3], thetasi[i], thetasj[j]), y=y, links = links)
    }
}

filled.contour(x=thetasi, y = thetasj, z=costs,
               color = function(n) rev(hcl.colors(n, "Spectral")),
               main = "LS Cost", xlab = TeX('$\\theta_2$'), ylab = TeX('$\\theta_3$'), nlevels = 30,
               plot.axes={points(true_vals[4], true_vals[5], pch = 19, col = rgb(241/255, 136/255,5/255, 1))
                   points(LS_result$theta.hat[2], LS_result$theta.hat[3], pch = 19, col = rgb(217/255, 3/255, 104/255, 1))
                   points(inits[4], inits[5], pch = 19, col = 'black')
                   axis(1, seq(-135, 135, by = 45))
                   axis(2, seq(-45, 270, by = 45))})

## lik for sigma
sigmas = seq(1e-3, 1, length.out = 10000)
lls = rep(NA, length(sigmas))
for(i in 1:length(sigmas)){
    lls[i] = loglikelihood(hat = c(true_vals[1:5], log(sigmas[i])), y=y, links = links)
}

plot(x = log(sigmas), y=lls, type = 'l', main = 'LL for sigma', xlab = 'log(sigma)')
abline(v=log(true_vals[6]), col = 'red')

plot_system(posture, y)
posture_hat = gen_posture(links = links, r = LS_result$r.hat, theta = LS_result$theta.hat)
plot_system(posture_hat, y, add=T)


model_updatephase <- function (cumulTT = 354.582294511779,
         leafNumber_t1 = 4.620511621863958,
         cumulTTFromZC_39 = 0.0,
         isMomentRegistredZC_39 = 0,
         gAI = 0.3255196285135,
         grainCumulTT = 0.0,
         dayLength = 12.7433275303389,
         vernaprog = 1.0532526829571554,
         minFinalNumber = 6.879410413987549,
         fixPhyll = 91.2,
         isVernalizable = 1,
         dse = 105.0,
         pFLLAnth = 2.22,
         dcd = 100.0,
         dgf = 450.0,
         degfm = 0.0,
         maxDL = 15.0,
         sLDL = 0.85,
         ignoreGrainMaturation = FALSE,
         pHEADANTH = 1.0,
         choosePhyllUse = 'Default',
         p = 120.0,
         phase_t1 = 1.0,
         cumulTTFromZC_91 = 0.0,
         phyllochron = 91.2,
         hasLastPrimordiumAppeared_t1 = 0,
         finalLeafNumber_t1 = 0.0){
    #'- Name: UpdatePhase -Version: 1.0, -Time step: 1
    #'- Description:
    #'            * Title: UpdatePhase Model
    #'            * Author: Pierre MARTRE
    #'            * Reference: Modeling development phase in the
    #'                Wheat Simulation Model SiriusQuality.
    #'                See documentation at http://www1.clermont.inra.fr/siriusquality/?page_id=427
    #'            * Institution: INRA Montpellier
    #'            * Abstract: This strategy advances the phase and calculate the final leaf number
    #'
    #'- inputs:
    #'            * name: cumulTT
    #'                          ** description : cumul thermal times at current date
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : -200
    #'                          ** max : 10000
    #'                          ** default : 354.582294511779
    #'                          ** unit : °C d
    #'                          ** inputtype : variable
    #'            * name: leafNumber_t1
    #'                          ** description : Actual number of phytomers
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 25
    #'                          ** default :  4.620511621863958
    #'                          ** unit : leaf
    #'                          ** inputtype : variable
    #'            * name: cumulTTFromZC_39
    #'                          ** description : cumul of the thermal time ( DeltaTT) since the moment ZC_39
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 0
    #'                          ** unit : °C d-1
    #'                          ** inputtype : variable
    #'            * name: isMomentRegistredZC_39
    #'                          ** description : true if ZC_39 is registered in the calendar
    #'                          ** variablecategory : state
    #'                          ** datatype : INT
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** default : 0
    #'                          ** unit :
    #'                          ** inputtype : variable
    #'            * name: gAI
    #'                          ** description : used to calculate Terminal spikelet
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 0.3255196285135
    #'                          ** unit :
    #'                          ** inputtype : variable
    #'            * name: grainCumulTT
    #'                          ** description : cumulTT used for the grain developpment
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 0
    #'                          ** unit : °C d
    #'                          ** inputtype : variable
    #'            * name: dayLength
    #'                          ** description : length of the day
    #'                          ** datatype : DOUBLE
    #'                          ** variablecategory : auxiliary
    #'                          ** min : 0
    #'                          ** max : 24
    #'                          ** unit : h
    #'                          ** default : 12.7433275303389
    #'                          ** inputtype : variable
    #'            * name: vernaprog
    #'                          ** description : progression on a 0  to 1 scale of the vernalization
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10
    #'                          ** default :  1.0532526829571554
    #'                          ** unit :
    #'                          ** inputtype : variable
    #'            * name: minFinalNumber
    #'                          ** description : minimum final leaf number
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 25
    #'                          ** default : 6.879410413987549
    #'                          ** unit : leaf
    #'                          ** inputtype : variable
    #'            * name: fixPhyll
    #'                          ** description : Phyllochron with sowing date fix
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 91.2
    #'                          ** unit : °C d
    #'                          ** inputtype : variable
    #'            * name: isVernalizable
    #'                          ** description : true if the plant is vernalizable
    #'                          ** parametercategory : species
    #'                          ** datatype : INT
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** unit :
    #'                          ** default : 1
    #'                          ** inputtype : parameter
    #'            * name: dse
    #'                          ** description : Thermal time from sowing to emergence
    #'                          ** parametercategory : genotypic
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** default : 105
    #'                          ** unit : °C d
    #'                          ** inputtype : parameter
    #'            * name: pFLLAnth
    #'                          ** description : Phyllochronic duration of the period between flag leaf ligule appearance and anthesis
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** unit :
    #'                          ** default : 2.22
    #'                          ** inputtype : parameter
    #'            * name: dcd
    #'                          ** description : Duration of the endosperm cell division phase
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 100
    #'                          ** unit : °C d
    #'                          ** inputtype : parameter
    #'            * name: dgf
    #'                          ** description : Grain filling duration (from anthesis to physiological maturity)
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 10000
    #'                          ** default : 450
    #'                          ** unit : °C d
    #'                          ** inputtype : parameter
    #'            * name: degfm
    #'                          ** description : Grain maturation duration (from physiological maturity to harvest ripeness)
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 50
    #'                          ** default : 0
    #'                          ** unit : °C d
    #'                          ** inputtype : parameter
    #'            * name: maxDL
    #'                          ** description : Saturating photoperiod above which final leaf number is not influenced by daylength
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 24
    #'                          ** default : 15
    #'                          ** unit : h
    #'                          ** inputtype : parameter
    #'            * name: sLDL
    #'                          ** description : Daylength response of leaf production
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** default : 0.85
    #'                          ** unit : leaf h-1
    #'                          ** inputtype : parameter
    #'            * name: ignoreGrainMaturation
    #'                          ** description : true to ignore grain maturation
    #'                          ** parametercategory : species
    #'                          ** datatype : BOOLEAN
    #'                          ** default : FALSE
    #'                          ** unit :
    #'                          ** inputtype : parameter
    #'            * name: pHEADANTH
    #'                          ** description : Number of phyllochron between heading and anthesiss
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** default : 1
    #'                          ** unit :
    #'                          ** inputtype : parameter
    #'            * name: choosePhyllUse
    #'                          ** description : Switch to choose the type of phyllochron calculation to be used
    #'                          ** parametercategory : species
    #'                          ** datatype : STRING
    #'                          ** unit :
    #'                          ** default : Default
    #'                          ** inputtype : parameter
    #'            * name: p
    #'                          ** description : Phyllochron (Varietal parameter)
    #'                          ** parametercategory : species
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** default : 120
    #'                          ** unit : °C d leaf-1
    #'                          ** inputtype : parameter
    #'            * name: phase_t1
    #'                          ** description :  the name of the phase
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 7
    #'                          ** default : 1
    #'                          ** unit :
    #'                          ** inputtype : variable
    #'            * name: cumulTTFromZC_91
    #'                          ** description : cumul of the thermal time (DeltaTT) since the moment ZC_91
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 5000
    #'                          ** default : 0
    #'                          ** unit : °C d-1
    #'                          ** inputtype : variable
    #'            * name: phyllochron
    #'                          ** description : Phyllochron
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 1000
    #'                          ** default : 91.2
    #'                          ** unit : °C d leaf-1
    #'                          ** inputtype : variable
    #'            * name: hasLastPrimordiumAppeared_t1
    #'                          ** description : if Last Primordium has Appeared
    #'                          ** variablecategory : state
    #'                          ** datatype : INT
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** default : 0
    #'                          ** unit :
    #'                          ** inputtype : variable
    #'            * name: finalLeafNumber_t1
    #'                          ** description : final leaf number
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 25
    #'                          ** default : 0
    #'                          ** unit : leaf
    #'                          ** inputtype : variable
    #'- outputs:
    #'            * name: finalLeafNumber
    #'                          ** description : final leaf number
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 25
    #'                          ** unit : leaf
    #'            * name: phase
    #'                          ** description : the name of the phase
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0
    #'                          ** max : 7
    #'                          ** unit :
    #'            * name: hasLastPrimordiumAppeared
    #'                          ** description : if Last Primordium has Appeared
    #'                          ** variablecategory : state
    #'                          ** datatype : INT
    #'                          ** min : 0
    #'                          ** max : 1
    #'                          ** unit :
    hasLastPrimordiumAppeared <- hasLastPrimordiumAppeared_t1
    finalLeafNumber <- finalLeafNumber_t1
    phase <- phase_t1
    if (phase_t1 >= 0.0 && phase_t1 < 1.0)
    {
        if (cumulTT >= dse)
        {
            phase <- 1.0
        }
        else
        {
            phase <- phase_t1
        }
    }
    else if ( phase_t1 >= 1.0 && phase_t1 < 2.0)
    {
        if (isVernalizable == 1 && vernaprog >= 1.0 || isVernalizable == 0)
        {
            if (dayLength > maxDL)
            {
                finalLeafNumber <- minFinalNumber
                hasLastPrimordiumAppeared <- 1
            }
            else
            {
                appFLN <- minFinalNumber + (sLDL * (maxDL - dayLength))
                if (appFLN / 2.0 <= leafNumber_t1)
                {
                    finalLeafNumber <- appFLN
                    hasLastPrimordiumAppeared <- 1
                }
                else
                {
                    phase <- phase_t1
                }
            }
            if (hasLastPrimordiumAppeared == 1)
            {
                phase <- 2.0
            }
        }
        else
        {
            phase <- phase_t1
        }
    }
    else if ( phase_t1 >= 2.0 && phase_t1 < 4.0)
    {
        if (isMomentRegistredZC_39 == 1)
        {
            if (phase_t1 < 3.0)
            {
                ttFromLastLeafToHeading <- 0.0
                if (choosePhyllUse == 'Default')
                {
                    ttFromLastLeafToHeading <- (pFLLAnth - pHEADANTH) * fixPhyll
                }
                else if ( choosePhyllUse == 'PTQ')
                {
                    ttFromLastLeafToHeading <- (pFLLAnth - pHEADANTH) * phyllochron
                }
                else if ( choosePhyllUse == 'Test')
                {
                    ttFromLastLeafToHeading <- (pFLLAnth - pHEADANTH) * p
                }
                if (cumulTTFromZC_39 >= ttFromLastLeafToHeading)
                {
                    phase <- 3.0
                }
                else
                {
                    phase <- phase_t1
                }
            }
            else
            {
                phase <- phase_t1
            }
            ttFromLastLeafToAnthesis <- 0.0
            if (choosePhyllUse == 'Default')
            {
                ttFromLastLeafToAnthesis <- pFLLAnth * fixPhyll
            }
            else if ( choosePhyllUse == 'PTQ')
            {
                ttFromLastLeafToAnthesis <- pFLLAnth * phyllochron
            }
            else if ( choosePhyllUse == 'Test')
            {
                ttFromLastLeafToAnthesis <- pFLLAnth * p
            }
            if (cumulTTFromZC_39 >= ttFromLastLeafToAnthesis)
            {
                phase <- 4.0
            }
        }
        else
        {
            phase <- phase_t1
        }
    }
    else if ( phase_t1 == 4.0)
    {
        if (grainCumulTT >= dcd)
        {
            phase <- 4.5
        }
        else
        {
            phase <- phase_t1
        }
    }
    else if ( phase_t1 == 4.5)
    {
        if (grainCumulTT >= dgf || gAI <= 0.0)
        {
            phase <- 5.0
        }
        else
        {
            phase <- phase_t1
        }
    }
    else if ( phase_t1 >= 5.0 && phase_t1 < 6.0)
    {
        localDegfm <- degfm
        if (ignoreGrainMaturation)
        {
            localDegfm <- -1.0
        }
        if (cumulTTFromZC_91 >= localDegfm)
        {
            phase <- 6.0
        }
        else
        {
            phase <- phase_t1
        }
    }
    else if ( phase_t1 >= 6.0 && phase_t1 < 7.0)
    {
        phase <- phase_t1
    }
    return (list ("finalLeafNumber" = finalLeafNumber,"phase" = phase,"hasLastPrimordiumAppeared" = hasLastPrimordiumAppeared))
}