# update:2022.01.15
library(shiny)
library(shinydashboard)
library(plotly)

sidebarPanel2 <- function (..., out = NULL, width = 4)
{
  div(class = paste0("col-sm-", width),
      tags$form(class = "well", ...),
      out
  )
}

theme_basic <- function() {
  fill.colour <- "white"
  theme_classic() +
    theme(plot.background    = element_rect(fill = fill.colour)) +
    theme(panel.background   = element_rect(fill = fill.colour)) +
    theme(panel.grid.major   = element_line(colour = "grey95")) +
    theme(panel.grid.major.x = element_blank()) +
    theme(axis.line          = element_blank()) +
    theme(axis.ticks.x       = element_blank()) +
    theme(axis.ticks.y       = element_line(colour = "grey95")) +
    theme(text               = element_text(colour = "grey20"))
}
#------------ ui-app.R ------------ ---
#------------ ui-header & sidebar -----
header <- dashboardHeader(title = "Probability")
sidebar <- dashboardSidebar(width = NULL,disable = FALSE,## 可以把邊邊關起來
                            sidebarMenu(
                              menuItem("Summary", tabName = "Page0", icon = icon("list")),
                              menuItem("Basic Probability", tabName = "Page1", icon = icon("list")),
                              menuItem("Discrate", tabName = "Page2", icon = icon("chart-bar")),
                              menuItem("Continuous", tabName = "Page3", icon = icon("chart-area"))
                              # menuItem("About",tabName = "final", icon = icon("address-card"))
                              # ref of icon : https://fontawesome.com/v5.15/icons
                            ))
#------------ ui-Body content -----
body <- dashboardBody(
  tags$head(tags$style(HTML('
                            /* logo */
                            .skin-blue  .main-header .logo {
                            background-color: #204969;
                            font-family: "monospace", Times, "Times New Roman", serif;
                            font-weight: bold;
                            font-size: 24px;
                            }
                             /* logo when hovered */
                            .skin-blue  .main-header .logo:hover {
                            background-color: #FFB6C1;
                            }
                            /* navbar (rest of the header) */
                            .skin-blue .main-header .navbar {
                            background-color: #f4b943;
                            }
                            /* main sidebar */
                            .skin-blue .main-sidebar {
                            background-color: #204969;
                            font-size: 16px;
                            }
                            /* body */
                            .content-wrapper, .right-side {
                            background-color: #fff7f7;
                            }
                            /* boxboxbox */
                            ') #HTML
                       ) # tags$style
            ), #tags$head
  tabItems(
    #-------------- Page0 -------------
    tabItem(tabName = "Page0",
            # Boxes need to be put in a row (or column)
            fluidRow(
              box(title = "Definitions",width = 12,
                  solidHeader = FALSE,
                  collapsible = FALSE,
                  uiOutput("summary")
                  ) # box
            ) # fluidRow
    ), # tabItem
    #-------------- Page1 -------------
    tabItem(tabName = "Page1",
            fluidRow(
              box(title = "Flipping a coin", width = 6,
                  collapsible = FALSE,
                  sidebarPanel2(
                               out = h6("A classic example of a probabilistic experiment is a fair coin toss,
                                        in which the two possible outcomes are heads or tails. In this case,
                                        The probability of flipping a head or a tail is 1/2."),
                               "Flip the coin:",
                               # sliderInput("n_coin","number",
                               #             value = 1,
                               #             min = 1,
                               #             max = 1000),
                               hr(),
                               actionButton("action1", "Flip the coin"),
                               hr(),
                               actionButton("action2", "Flip 100 times")
                  ), # sidebarPanel2
                  mainPanel(plotOutput("plot_coin"))
                  ),
              box(title = "Rolling a dice", width = 6,
                  collapsible = FALSE,
                  sidebarPanel(width = 4,
                               "Roll the dice:",
                               sliderInput("n_dice","number",
                                           value = 1,
                                           min = 1,
                                           max = 1000)
                  ),
                  mainPanel(plotOutput("plot_dice"))
              )
            )
            # ,
            # fluidRow(
            #   box(title = "coin", width = 6,
            #       collapsible = FALSE,
            #       tableOutput("data_coin")
            #   )
            # )

    ),
    #-------------- Page2 -------------
    tabItem(tabName = "Page2",
            # #----------- radioButtons ----------------------
            # fluidRow(
            #   box(title = "Discrate",width = 4,
            #       status = "warning",
            #       solidHeader = FALSE,
            #       collapsible = FALSE,
            #       "Choose one of the following major discrete distributions.",
            #       br(),
            #       radioButtons("dist1", "Distribution type:",
            #                    c("Binomial","Negative Binomial",
            #                      "Geometric","Poisson"))
            #   ),
            #   box(title = "Definitions",width = 8,
            #       status = "warning",
            #       solidHeader = FALSE,
            #       collapsible = FALSE,
            #       uiOutput("txt1")
            #       # htmlOutput("txt1")
            #       # verbatimTextOutput("txt1")
            #   )
            # ),
            #----------- bin ------------------------------------
            fluidRow(
              box(title = "Binomial", width = 6,
                  status = "warning",
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               sliderInput("n","number",
                                           value = 10,
                                           min = 10,
                                           max = 100),
                               sliderInput("p",
                                           "Probability",
                                           value = 0.6,
                                           min = 0,
                                           max = 1)
                  ),
                  mainPanel(plotOutput("plot_bin1"))
              ),
              #----------- nb ------------------------------------
              box(title = "Negative Binomial",width = 6,
                  status = "warning",
                  solidHeader = FALSE,
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               sliderInput("r","number",
                                           value = 10,
                                           min = 1,
                                           max = 100),
                               sliderInput("p_nb","Probability",
                                           value = 0.6,
                                           min = 0,
                                           max = 1)),
                  mainPanel(plotOutput("plot_nb1")))
            ),
            #----------- geo ------------------------------------
            fluidRow(
              box(title = "Geometric",width = 6,
                  status = "warning", solidHeader = FALSE,
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               sliderInput("p_geo","Probability",
                                           value = 0.6,
                                           min = 0.1,
                                           max = 1)
                  ),
                  mainPanel(plotOutput("plot_geo1"))
              ),
              #----------- Poi ------------------------------------
              box(title = "Poisson",width = 6,
                  status = "warning", solidHeader = FALSE,
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               sliderInput("lambda","lambda",
                                           value = 2,
                                           min = 0.1,
                                           max = 50)
                  ),
                  mainPanel(plotOutput("plot_poi1"))
              )
            )
    ),
    #-------------- Page3 -------------
    tabItem(tabName = "Page3",
            # fluidRow(
            #   box(title = "Continuous",width = 4,
            #       solidHeader = FALSE,
            #       collapsible = FALSE,
            #       "Choose one of the following major continuous distributions.",
            #       br(),
            #       radioButtons("dist2", "Distribution type:",
            #                    c("Uniform","Exponential","Normal"))
            #       ),
            #   box(title = "Definitions",width = 8,solidHeader = FALSE,
            #       collapsible = FALSE,
            #       uiOutput("txt2")
            #   )
            # ),
            #----------- unif ------------------------------------
            fluidRow(
              box(title = "Uniform", width = 6,
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               # numericInput("min", "Minimum", 2),
                               # numericInput("max", "Maximum", 5)
                               sliderInput("unifRange", "Range",
                                           min = 0, max = 20,
                                           value = c(2, 5))
                               ),
                  mainPanel(plotOutput("plot_unif1"))
              ),

              #----------- Exponential  ------------------------------------
              box(title = "Exponential ",width = 6,
                  solidHeader = FALSE,
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               sliderInput("lambda2","lambda",
                                           value = 2,
                                           min = 0.1,
                                           max = 5,
                                           step = 0.1)
                               ),
                  mainPanel(plotOutput("plot_exp1")))
            ),
            #----------- Normal ------------------------------------
            fluidRow(
              box(title = "Normal", width = 6,
                  collapsible = TRUE,
                  sidebarPanel(width = 4,
                               sliderInput("mu","mu",
                                           value = 175,
                                           min = 0,
                                           max = 200,
                                           step = 0.1),
                               sliderInput("sigma","sigma",
                                           value = 6,
                                           min = 0.1,
                                           max = 50,
                                           step = 0.1)
                               ),
                  mainPanel(plotOutput("plot_norm1"))
                  )
              )
    ),
    #-------------- final -------------
    tabItem(tabName = "final",
            # fluidRow(
            #   column(width = 4,
            #          box(
            #            title = "Updata:2022/01/07", width = NULL, solidHeader = TRUE, status = "warning"
            #          )
            #   )
            # ),
            fluidRow(
              infoBox("Updata", "2022/01/07", icon = icon("edit"), fill = FALSE,color = "light-blue")
            ) # fluidRow
    ) #tabItem
  ) # tabItems
) # dashboardBody
#------------ ui -----
ui <- dashboardPage(header, sidebar, body)

#------------ server -----
server <- function(input, output, session) {
  #------------ txt0 -----
  output$summary <- renderUI({
    withMathJax(includeHTML("dis_formula\\Summary.html"))
  })
  #------------ coin ------------
  # https://ithelp.ithome.com.tw/articles/10196754
  ##
  v <- reactiveValues(times = NULL)
  observeEvent(input$action1, {
    v$times <- trunc(runif(1, min = 1, max = 3))
  })
  observeEvent(input$action2, {
    v$times <- trunc(runif(100, min = 1, max = 3))
  })

  output$plot_coin <- renderPlot({
    if (is.null(v$times)) return()
    # count <- table(trunc(runif(1, min = 1, max = 3)))
    count <- table(v$times)
    sums <- integer(2)
    if(nrow(count)>1){
      sums <- count
    }else{
      ifelse(names(count)=="1",
             sums[1] <- as.numeric(count),
             sums[2] <- as.numeric(count))
    }

    # count <- as.numeric(table(trunc(runif(1, min = 1, max = 3))))[1:2]
    # count <- as.numeric(table(v$times))[1:2]
    # count[which(is.na(count))] <- 0

    dice <- data.frame(number = c("Heads","Tails"),
                       count = sums) %>%
      mutate(p = (count / sum(count)), theoretical = (1/2))

    title <- paste("Probability Distribution of coin")
    ggplot(dice) + theme_basic() +
      geom_bar(aes(x = number, y = p),
               stat = "identity", position = "dodge",
               fill = c("#a2d2ff","#bee1e6"))+
      ggtitle(title)+
      geom_hline(yintercept=1/2, linetype="dashed", color = "red")+
      # scale_x_continuous(labels = 1:2, breaks = 1:2)+
      scale_y_continuous(limits = c(0, max(dice$p)+0.05),
                         breaks = seq(0, max(dice$p)+0.05, by = 0.1))
  })
  # output$plot_coin <- renderPlot({
  #   sums <- integer(2)
  #   for (i in 1:input$n_coin) {
  #     # "roll" number between 1 and 6; add together
  #     outcome <- trunc(runif(1, min = 1, max = 3))
  #     # count result
  #     sums[outcome] <- sums[outcome] + 1
  #   }
  #   # prepare a data frame for graphing
  #   dice <- data.frame(number = c("Heads","Tails"), count = sums[1:2]) %>%
  #     mutate(p = (count / sum(count)), theoretical = (1/2))
  #
  #
  #   title <- paste("Probability Distribution of coin")
  #   ggplot(dice) + theme_basic() +
  #     geom_bar(aes(x = number, y = p),
  #              stat = "identity", position = "dodge",
  #              fill = c("#ff9e00","#00b4d8"))+
  #     ggtitle(title)+
  #     # scale_x_continuous(labels = 1:2, breaks = 1:2)+
  #     scale_y_continuous(limits = c(0, max(dice$p)+0.05),
  #                        breaks = seq(0, max(dice$p)+0.05, by = 0.1))
  # })

  # https://stackoverflow.com/questions/61287106/how-to-create-a-table-in-a-reactive-object-in-shiny

  # output$data_coin <- renderTable({
  #   tableData$d1
  # })

  #------------ dice ------------
  output$plot_dice <- renderPlot({
    sums <- integer(6)
    for (i in 1:input$n_dice) {
      # "roll" number between 1 and 6; add together
      outcome <- trunc(runif(1, min = 1, max = 7))
      # count result
      sums[outcome] <- sums[outcome] + 1
    }
    # prepare a data frame for graphing
    dice <- data.frame(number = 1:6, count = sums[1:6]) %>%
      mutate(p = (count / sum(count)), theoretical = (1/6))

    title <- paste("Probability Distribution of dice")
    ggplot(dice) + theme_basic() +
      geom_bar(aes(x = number, y = p),
               stat = "identity", position = "dodge",
               fill = c("#cdb4db","#ffc8dd","#ffafcc","#bde0fe","#a2d2ff","#bee1e6"))+
      ggtitle(title)+
      scale_x_continuous(labels = 1:6, breaks = 1:6)+
      scale_y_continuous(limits = c(0, max(dice$p)),
                         breaks = seq(0, max(dice$p), by = 0.05))+
      geom_hline(yintercept=1/6, linetype="dashed", color = "red")
  })
  #------------ button -------
  ## ## 以下為反應分配按鈕，程式碼過長
  ## n  <- 0
  ## observe({
  ##   dist1 <- input$dist1
  ##   n <- n+1
  ##   if (!is.null(dist1)) {
  ##     if (dist1=='dummy')  showActions ()
  ##     else {
  ##       if (dist1=='Binomial')
  ##         output$txt1  <- renderUI({
  ##           withMathJax(paste(input$dist1,"\n",
  ##                 "$$f(x)=\\binom{n}{x}p^{x}(1-p)^{n-x}$$","\n",
  ##                 "$$\\text{E}(X)=np$$","\n",
  ##                 "$$\\text{Var}(X)=np(1-p)$$"))
  ##
  ##         })
  ##       if (dist1=='Negative Binomial')
  ##         output$txt1  <- renderUI({
  ##           withMathJax(paste(input$dist1,"\n",
  ##                             "$$f(x)=\\binom{x+r-1}{r-1}p^{r}(1-p)^{x}$$","\n",
  ##                             "$$\\text{E}(X)=\\frac{rp}{1-p}$$","\n",
  ##                             "$$\\text{Var}(X)=\\frac{rp}{(1-p)^2}$$"))
  ##
  ##         })
  ##       if (dist1=='Geometric')
  ##         output$txt1  <- renderText (paste (input$dist1, "action C"))
  ##       if (dist1=='Poisson')
  ##         output$txt1  <- renderText (paste (input$dist1, "action C"))
  ##     }
  ##   }
  ## })

  #------------ txt1 -----
  output$txt1 <- renderUI({
    ## 會無法出現表格
    ## withMathJax(includeMarkdown(paste0("C:\\Users\\user\\R\\R_2021\\prob\\dis_formula\\",input$dist1,".md")))

    # withMathJax(includeHTML(paste0("C:\\Users\\user\\R\\R_2021\\prob\\dis_formula\\",input$dist1,".html")))
    withMathJax(includeHTML(paste0("dis_formula\\",input$dist1,".html")))
  })
  #------------ txt2 -----
  output$txt2 <- renderUI({
    ## withMathJax(includeMarkdown(paste0("C:\\Users\\user\\R\\R_2021\\prob\\dis_formula\\",input$dist1,".md")))

    # withMathJax(includeHTML(paste0("C:\\Users\\user\\R\\R_2021\\prob\\dis_formula\\",input$dist2,".html")))

    withMathJax(includeHTML(paste0("dis_formula\\",input$dist2,".html")))
    })
  #------------ Bin(n,p) #####
  output$plot_bin1 <- renderPlot({
    x <- seq(from = 0,to = input$n,by = 1) #成功次數
    plot(x,dbinom(x,size = input$n, prob=input$p), #
         pch=16,type="h", #type='l'
         main = paste("Binomial ( n=",input$n,", p=",input$p,")"),
         ylab='Probability',
         xlab ='x',
         lwd=4,
         col="deepskyblue")
  })
  #------------ NB(r,p) #####
  output$plot_nb1 <- renderPlot({
    x <- seq(from = 0,to = input$r,by = 1) #成功次數
    plot(x,dbinom(x,size = input$r, prob=input$p_nb), #
         pch=16,type="h",
         main = paste("Negative Binomial ( r=",input$r,", p=",input$p_nb,")"),
         ylab='Probability',
         xlab ='x',
         lwd=4,
         col="deepskyblue")
  })
  #------------ geo(p) #####
  output$plot_geo1 <- renderPlot({
    x <- seq(from = 0,to = 30,by = 1)
    plot(x,dgeom(x, prob=input$p_geo), #
         type = 'h',
         main = paste("Geometric ( p=",input$p_geo,")"),
         ylab = 'Probability',
         xlab = 'x',
         lwd=4,
         col="deepskyblue")
  })
  #------------ Poisson (λ) #####
  output$plot_poi1 <- renderPlot({
    x <- seq(from = 0,to = 30,by = 1)
    plot(x,dpois(x, lambda = input$lambda), #
         type = 'h', #type='o'
         main = paste("Poisson ( λ=",input$lambda,")"),
         ylab = 'Probability',
         xlab = 'x',
         lwd=4,
         col="deepskyblue")
  })
  #------------ unif (a,b) #####
  output$plot_unif1 <- renderPlot({

    # x <- seq(from = input$min-0.5,to = input$max+0.5, length=100)
    # plot(x,dunif(x,input$min,input$max),
    #      type = 'l',pch=16,
    #      main = paste("Unif ( a=",input$min,",","b=",input$max,")"),
    #      ylab = 'density',
    #      xlab = 'x',
    #      col="deepskyblue",
    #      lwd="4")

    x <- seq(from = min(input$unifRange)-3,to = max(input$unifRange)+3, length=100)
    plot(x,dunif(x,min(input$unifRange),max(input$unifRange)),
         type = 'l',pch=16,
         main = paste("Unif ( a=",min(input$unifRange),",","b=",max(input$unifRange),")"),
         ylab = 'density',
         xlab = 'x',
         col="deepskyblue",
         lwd="4")
  })
  #------------ exp (λ) ------------
  output$plot_exp1 <- renderPlot({

    x <- seq(from = min(rexp(100,input$lambda2)),to = max(rexp(100,input$lambda2)), by=0.01)
    plot(x,dexp(x,input$lambda2),
         type = 'l',pch=16,
         main = paste("Exp ( λ=",input$lambda2,")"),
         ylab = 'density',
         xlab = 'x',
         col="deepskyblue",
         lwd="4")
  })
  #------------ N(μ,σ) #####
  output$plot_norm1 <- renderPlot({
    x <- seq(from = min(rnorm(100,input$mu,input$sigma)), to = max(rnorm(100,input$mu,input$sigma)), by = 0.1)
    plot(x, dnorm(x,input$mu,input$sigma), type = "l",
         ylab = "density",
         main = paste("Normal ( μ=",input$mu,",σ=",input$sigma,")"),
         xlab = 'x',
         col="deepskyblue",
         lwd="4")
  })
}
shinyApp(ui, server)


# Fit SSD to CCME data for several metals

# Copyright 2017 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.

# We compare fits for the distributions with AIC
# Refer to https://cran.r-project.org/web/packages/fitdistrplus/vignettes/FAQ.html
# for information on the fitdistrplus package.
# Refer to AICcmodavg package for details on creating the AIC tables and
# how to do model averaging.

# Load the necessary libraries
library(AICcmodavg)
library(actuar) # for the burr distribution
library(FAdist) # for log-logistic
library(fitdistrplus)
library(ggplot2)
library(grid)
library(gridGraphics)
library(plyr)   # for doing a separate analysi by chemical
library(VGAM) # for the gompertz, pareto, gumbel distributions

source("mygofstat.r")  # corrects and error in the code in the fistdistr package (groan)
#source("C:/R-repositories/SSD-fitting/CCME-fits/mygofstat.r")

#load test data
endpoints<-read.csv("CCME data.csv",header=TRUE,as.is=TRUE, strip.white=TRUE)
#endpoints<- read_csv("C:/R-repositories/SSD-fitting/CCME-fits/CCME data.csv")

head(endpoints)

xtabs(~Chemical, data=endpoints, exclude=NULL, na.action=na.pass)

# create a directory for plots
dir.create(file.path("Plots"))

#use descdist function from fitdistrplus package to identify candidate distributions - create a Cullen Frey graph
sumstats <- plyr::ddply(endpoints, "Chemical", function(x, boot){
    # create the individual plots
    png(file.path("Plots",paste(x$Chemical,".png",sep="")), h=6, w=6, units="in", res=300)
       res <- descdist(x$Conc,discrete=FALSE, boot=boot)
    dev.off()
    # return the summary statistics as a dataframe, rather than a list
    attr(res, "class") <- NULL # remove class attribute from results
    data.frame(res)
}, boot=100)

# summary statistics
sumstats

# create list of possible distributions (the pareto and burr distributions have been commented out of the list below because they are not included in SSD Master)
fit.list <- list( lnorm  = list(data=NULL, distr="lnorm",  method="mle"),
                  llog   = list(data=NULL, distr="llog",   method="mle"), # log logistic
                  gomp   = list(data=NULL, distr="gompertz",method="mle"),
                  lgumbel= list(data=NULL, distr="lgumbel",method="mle"), # log gumbel
                  gamma  = list(data=NULL, distr="gamma",  method="mle"),
#                  pareto = list(data=NULL, distr="pareto", method="mle"),
                  weibull= list(data=NULL, distr="weibull",method="mle")
#                  burr   = list(data=NULL, distr="burr",   method="mle")
                 )

# define log-gumbel distribution
# These functions are needed because this is a non-standard distribution
dlgumbel <- function(x, location=0, scale=0, log=FALSE){
            fx <- dgumbel(log(x), location=location, scale=scale, log=FALSE)/x
            if(log) fx <- log(fx)
            fx}
qlgumbel <- function(p, location=0, scale=0, lower.tail=TRUE, log.p=FALSE){
            if(log.p) p<- exp(p)
            if(!lower.tail) p <- 1-p
            exp( qgumbel(p, location=location, scale=scale))}
plgumbel <- function(q, location=0, scale=0, lower.tail=TRUE, log.p=FALSE){
             Fq <- pgumbel(log(q), location=location, scale=scale)
             if(!lower.tail) Fq <- 1-Fq
             if(log.p) Fq <- log(Fq)
             Fq}
rlgumbel <- function(n, location=0, scale=0){ exp(rgumbel(n, location=location, scale=scale))}

#endpoints <- endpoints[ endpoints$Chemical=="Boron_CCME",]  # for testing to fit only one chemical

# Fit each distribution from the list to each chemical
fit.all <- plyr::dlply(endpoints, "Chemical", function(x, probs=c(.05,.10), nboot=1000){
      cat("Analyzing ", x[1,"Chemical"],"\n")
      # fit all of the distributions in the list to this data. If
      # a distribution fitting does not converge, then it returns NULL
      dist.fits <- plyr::tryapply(fit.list, function(distr, x){
           distr$data <- x$Conc
           if(distr$distr=="burr"){
              distr$start <-list(shape1=4, shape2=1, rate=1)
              distr$method<- "mme"
              distr$order <- 1:3
              distr$memp  <- function (x, order){sum(x^order)}
           }
           if(distr$distr=='gamma'){
             distr$start <- list(scale=var(x$Conc)/mean(x$Conc),
                                    shape=mean(x$Conc)^2/var(x$Conc)^2)
           }
           if(distr$distr == 'gompertz'){
              # use the vgam to get the parameters of the fit
              fit <- vglm(Conc~1, gompertz, data=x)
              distr$start <- list(shape=exp(unname(coef(fit)[2])), scale=exp(unname(coef(fit)[1])) )
            }
           if(distr$distr=='lgumbel'){
             distr$start <- list(location=mean(log(x$Conc)), scale=pi*sd(log(x$Conc))/sqrt(6))
           }
           if(distr$distr=='pareto'){ #use the vgam package to estimate the starting values
             fit<- vglm(Conc~1, paretoff, data=x)
             distr$start  <- list(shape=exp(unname(coef(fit))))
             distr$fix.arg<- list(scale=fit@extra$scale)
           }
           if(distr$distr=="llog" ){ # log=logistic
              distr$start <- list(shape=mean(log(x$Conc)), scale=pi*sd(log(x$Conc))/sqrt(3))
           }
           cat("   Fitting ", distr$distr,"\n")
           res <- do.call("fitdist", distr)
           print(res)
           res
      },x=x)

      # Get the aic table by hand.
      aic.table <- plyr::ldply(dist.fits, function(x){
        # extract the distribution name and AIC value
        aic <- x$aic
        distname <- x$distname
        aicc <- AICcmodavg::AICc(x) # conflict with VGAM package
        nparm <- length(x$estimate)
        data.frame(distname=distname, aic=aic, k=nparm, aicc=aicc)
      })
      aic.table <- aic.table[order(aic.table$aicc),]
      aic.table$delta.aicc <- aic.table$aicc - min(aic.table$aicc)
      aic.table$weight     <- round(exp(-aic.table$delta.aicc/2)/sum(exp(-aic.table$delta.aicc/2)),3)

      # make predictions for HC5 based on all of the distributions
      # Include a bootstrap approximation to the se of the estimates
      pred.table <- plyr::ldply(dist.fits, function(x, probs=.05, nboot=1000){
        distname <- x$distname
        pred     <- quantile(x, probs)
        fit.boot <- bootdist(x, niter=nboot)
        #browser()
        se       <- apply(quantile(fit.boot, probs=probs)$bootquant, 2, sd, na.rm=TRUE)
        lcl      <- quantile(fit.boot, probs=probs)$quantCI[1,]
        ucl      <- quantile(fit.boot, probs=probs)$quantCI[2,]
        #cat("pred.table", distname, pred, se, lcl, ucl, "\n")
        data.frame(distname=distname, quantile=probs, pred=unlist(pred$quantiles), se=se, lcl=unlist(lcl), ucl=unlist(ucl) )
      }, probs=probs, nboot=nboot)

      pred.table <- merge(pred.table, aic.table[,c("distname","weight")])

      # compute the model averaged quantiles, the model averaged lcl and ucl, and unconditional se
      q.modavg <- plyr::ddply(pred.table, "quantile", function(x){
        avg.pred <- sum(x$pred * x$weight)
        avg.lcl  <- sum(x$lcl  * x$weight)
        avg.ucl  <- sum(x$ucl  * x$weight)
        # get the unconditional se
        avg.u.se <- sqrt(sum(x$weight * (x$se^2 + (x$pred-avg.pred)^2)))
        data.frame(avg.pred=avg.pred, avg.u.se=avg.u.se, avg.lcl=avg.lcl, avg.ucl=avg.ucl)
      })
      q.modavg

      # make the cdf plot comparing all of the fits
      # capture the plot and save it
      # get the list of distributions that were fit
      dist.names <- plyr::laply(dist.fits, function(x) x$distname)
      cdfcomp(dist.fits, xlogscale=TRUE, legendtext=dist.names,
              main=paste("Empirical and theoretical CDF's - ",x[1,"Chemical"],sep=""),
              fitcol=c("red","blue","darkgreen","black","darkblue","cyan","violet"),
              fitlty=1:3)
      gridGraphics::grid.echo()
      cdf.comp.plot <- grid::grid.grab()

      #compute the goodmess of fit statistics - NOTE this does not work for burr distribution, not sure why...
      # must check to see if more than one distribution was fit - groan.
      # Also had to fix an error in compute p-value for chi2 test when df=0
      if(length(dist.fits) ==1) {gof.stat <- mygofstat(dist.fits[[1]], fitnames=dist.names)}
      if(length(dist.fits) >1 ) {gof.stat <- mygofstat(dist.fits,fitnames =dist.names)}
#      The following fails because of a bug in gofstat. See mygofstat file for details
#      if(length(dist.fits) ==1) {gof.stat <- fitdistrplus::gofstat(dist.fits[[1]], fitnames=dist.names)}
#      if(length(dist.fits) >1 ) {gof.stat <- fitdistrplus::gofstat(dist.fits,fitnames =dist.names)}

      # return the entire fitting stuff for this distibution
      list(Chemical=x[1,"Chemical"], dist.fits=dist.fits, aic.table=aic.table, pred.table=pred.table,
           q.modavg=q.modavg,
           cdf.comp.plot =cdf.comp.plot,
           gof.stat =gof.stat)
})

display.results <- function(x){
   # display the results from the fitting functions
   cat("\n\n\n\n\n\n\n\n\n *******************************************************************\n")
   cat("\n\nResults when applied to ", x$Chemical, "\n")
   cat("\n\nAICc table \n")
   print(x$aic.table)

   cat("\n\nPredictions of endpoints \n")
   print(x$pred.table)

   cat("\n\nModel averaged endpoint \n")
   print(x$q.modavg)

   cat("\n\nCDF comparative plot\n")
   grid.newpage()
   grid.draw(x$cdf.comp.plot)

   cat("\n\nGoodness of fit statistics\n")
   print(x$gof.stat)

}

# display all of the results from all of the Chemicals
plyr::l_ply(fit.all, display.results)

# save the comparative plot
plyr::l_ply(fit.all, function(x){
   file.name=file.path("Plots",paste(x$Chemical,"-comparative-plot.png",sep=""))
   png(file.name, h=6, w=6, units="in", res=300)
      grid.newpage()
      grid.draw(x$cdf.comp.plot)
   dev.off()
})

# Make a nice plot of the estimates and ci and compare them to the CCME guidelines

ccme.csv<- textConnection(
"Chemical,n, HC5, lcl, ucl, dummy, dummy, dummy
Boron  , 28 , 1.5  , 1.2 , 1.7 , 1.2  , 0.59 , 3.20
Cadmium  , 36 , 0.09  , 0.04 , 0.24 , 0.14  , 0.06 , 0.34
Chloride  , 28 , 120  , 90 , 150 , 73  , 27 , 198
Endosulfan  , 12 , 0.003  , 0.0007 , 0.01 , 0.010  , 0.0012 , 0.51
Glyphosate  , 18 , 800  , 490 , 1320 , 900  , 459 ,  2301
Silver  , 9 , 0.25  , 0.17 , 0.39 , 0.19  , 0.069 , 0.89
Uranium , 13 , 15  , 8.5 , 25 , 15  , 3.1 , 124")

ccme <- read.csv(ccme.csv, header=TRUE, as.is=TRUE, strip.white=TRUE)
ccme$dummy <- NULL
ccme$dummy.1 <- NULL
ccme$dummy.2 <- NULL
ccme$EstType <- "CCME"
ccme$n  <- NULL
ccme

# get the estimates of HC5
fit.hc5 <- plyr::ldply(fit.all, function(x){
    # extract the model averaged
    q <- x$q.modavg[ x$q.modavg$quantile == 0.05,]
    data.frame( HC5=q$avg.pred, lcl=q$avg.lcl, ucl=q$avg.ucl, EstType="ModelAvg")
})

fit.hc5$Chemical <- gsub("_CCME", "", fit.hc5$Chemical)
fit.hc5quuantile <- NULL
fit.hc5

both <- rbind(ccme, fit.hc5)
both

lab_log10 <- function (x){
   # create nice labels for the next plot
   y <- as.character(x)
   y
}

compplot <- ggplot(data=both, aes(x=Chemical, y=HC5, color=EstType))+
  geom_point( position=position_dodge(w=0.4))+
  geom_errorbar(aes(ymin=lcl, ymax=ucl), width=0.1,position=position_dodge(w=0.4))+
  scale_y_log10(labels=lab_log10)+
  #scale_color_discrete(name="Method")+
  labs(x = "Chemical")+
  ylab(bquote('Log' ~HC[5]))+
  theme(axis.text.x = element_text(angle=45,hjust = 1))+
  scale_color_manual(labels = c("Least Squares", "MLE"), values = c("red", "black"))+
  guides(colour=guide_legend("Method"))
compplot

ggsave("Plots/compplot_mod.png", compplot, width = 5.97, height = 5.97)

#calculating percent difference of HC5 values
both.hc5 <- reshape2::dcast(both, Chemical ~ EstType, value.var="HC5")

both.hc5$perdiff <- abs(both.hc5$CCME - both.hc5$ModelAvg)/(both.hc5$CCME + both.hc5$ModelAvg)*2*100
both.hc5
summarize(both.hc5,
          mean.perdiff = mean(perdiff))

#calculate width ratio (ModelAvg/CCME)
both$ci.width <- both$ucl - both$lcl
both.hc5 <- reshape2::dcast(both, Chemical ~ EstType, value.var="ci.width")

both.hc5$width.ratio <- both.hc5$ModelAvg / both.hc5$CCME
both.hc5
summarize(both.hc5,
          mean.widthratio = mean(width.ratio))


# Bilan hydrique d'une vigne enherb?e
# X.Delpuech (IFV) d'apres F.Celette, A. Ripoche, 2009
# S.Roux : quelques modifications pour param?trage, lisibilit?
#######################

###############################
# DEFINITION DES SOUS-FONCTIONS

#######
#  Fonction Somme de temp?rature base  cumsumb(vecteur temp?rature, base, ligne de d?but, ligne de fin)
#  base : definit la valeur de base pour la somme des temp?ratures, par d?faut = 10
#  x : definit le vecteur d'entr?e
#  debut : definit la ligne de debut du calcul, par d?faut = 1
#  fin : definit la ligne de fin du calcul, par d?faut la derni?re ligne de x

cumsumb<-function(x,base=10,debut=1,fin=length(x))
{
	somTb<-vector(mode="numeric",length = length(x)) #cree un vecteur vide du m?me nombre de ligne que le vecteur d'entr?e x
	ifelse (x[debut]>base,somTb[debut]<-(x[debut]-base),somTb[debut]<-0)  # Calcul la premi?re valeur de la somme de Temp en base
	for (i in (debut+1):fin)
	{
		ifelse (x[i]>base, somTb[i]<-(somTb[i-1]+x[i]-base), somTb[i]<-somTb[i-1])
	}   # Calcul des SomTb de la ligne 2 ? la fin des donn?es m?t?o
	return(somTb)
}

########
# Fonctions calcul du seuil de ruissellement  Sr(CN)

# Fonction calcul du seuil de ruissellement (p5j,cn2,p5j1,p5j2)
SeuilR<-function(p5j,cn2,p5j1,p5j2)
{
	cn1 = (4.2*cn2)/(10-0.058*cn2)
	cn3 = (23*cn2)/(10+0.13*cn2)

	#calcul du seuil de ruissellement
	if (p5j<p5j1)
		res = 254*(100/cn1-1)
	else {
		if (p5j>p5j2)
			res = 254*(100/cn3-1)
		else
			res = 254*(100/cn2-1)
	}
	return(res)

}

# Fonction calcul du ruissellement Rs(pluie,seuil ruissellement)
Ruiss<-function(P,sr) # P = pluie en mm , sr = seuil de ruissellement
{
	if (P<0.2*sr) y<-0
	else y<-((P-0.2*sr)^2/(P+0.8*sr))
	return (y)
}
###############################
# param?trage par defaut

nominal=list(p=0.6,
		Tonte="N", 							# caractere {O,N} d'activation des tontes aux dates prevues (renint LAI)(si "N", tontes automatique /LAI)
		nbtonte=c(2,2,2,0,0,0,0), 			# D?finit le nombre de tonte chaque ann?e de simulation
		inn=0.3, 							# D?finit l?INN de l?herbe
		irri="N", 							# caractere {O,N} d'activation de l?irrigation qui branche la colonne "IR" du fichier meteo
		dtonte=rep("29/03",10), 			# date des tontes activ? par le parametre "Tonte"
		dbr=rep("26/03",10), 				# dates de d?marrage de la v?g?tation de la vigne (en nombre >=sup?rieur ou ?gal au nombre d?ann?es simul?es)
		arretTr="01/11", 					# date d?arr?t de transpiration de la vigne
		ddkmax=600, 						# nombre de degr? jour pour atteindre le Kmax
		reinit="N",							# caractere {O,N} pour reinitialiser les stocks d'eau en debut d'ann?e
		pir=0, 								# Permet d?attribuer un CN diff?rent (donn? par CN_Ruiss2)  ? l?inter-rang m?me en absence d?enherbement.
		seuilpeff=2,						# seuil de pluie efficace
		kmax=rep(0.43,10),					# coefficient d?interception du rayonnement de la vigne
		levee="01/01",						# date de lev?e de l?enherbement
		flagRuiss="O",						# utilisation du module de ruissellement "O" active
		CN_Ruiss=94,						# CN (ruissellement) sous le rang
		CN_Ruiss2=84,						# CN (ruissellement) dans l?inter-rang
		herblairate=0.9,					# LAI rate de l?enherbement
		LAIinit=0.5,						# LAI initial de l?enherbement
		LAIres=0.3,							# LAI r?siduel de l?enherbement apr?s une tonte
		LLSmin=700,							# LLSmin de l?herbe
		LAItonte=3,							# LAI ? partir duquel on d?clenche une tonte automatiquement
		U=2.7,								# param?tre U d??vaporation du sol
		b1_evap=14,							# param?tre b1_evap d??vaporation du sol
		b2_evap=0.15,						# param?tre b2_evap d??vaporation du sol
		FTSWhregultr=0.6,					# FTSW du compartiment herbe ? partir de laquelle l?herbe r?gule sa transpiration
		FTSWhregulLAI=0.9,					# FTSW du compartiment herbe ? partir de laquelle l?herbe r?gule son LAI
		TTSWh=129,							# TTSW du compartiment herbe
		TTSWv=224,							# TTSW du compartiment vigne
		FTSWvregulTR=0.4,					# FTSW du compartiment vigne ? partir de laquelle la vigne r?gule sa transpiration
		ASWhinit=70.92,						# quantit? d?eau dans le compartiment vigne en d?but de simulation
		ASWvinit=178.18,						# quantit? d?eau dans le compartiment herbe  en d?but de simulation
		format_date="%d/%m/%Y"    # format des dates dans le fichier m?t?o d'entr?e
		)

###############################
# FONCTION BH
walis.model.single<-function( param, meteo)
{

	###############################
	## FONCTION DE BILAN HYDRIQUE

	if(param$p!=0) param$pir<-param$p

	# DEFINITION PARAMETRE DU MODELE

	dat<-as.POSIXlt(strptime(meteo$Date,param$format_date))
	#
	# Nombre d'ann?e : "an" donne le nombre d'ann?es dans le fichier
  ans<-unique(dat$year)  # donne le vecteur des ann?es du fichier
  an<-length(ans)        # donne le nombre d'ann?e dans le fichier

	# jdeb donne les lignes de d?but de chaque ann?e
  jj<-as.POSIXlt(dat)$yday # vecteur des jours julien
  ll<-c(1:dim(meteo)[1]) # vecteur indice des lignes
  jdeb<-ll[jj==0]
  if (an>1 & jj[1]>1) jdeb=c(1,jdeb)
  jdeb[1]<-1  # au cas ou l'anne ne commence pas au 01/01
  jdeb[an+1]<-(dim(meteo)[1]+1)

	# Calcul des lignes correspondant aux dates du BH (avec cette m?thode, il y a un d?calage d'un jour les ann?es non bisextiles,
	#il faudrait rajouter les ann?es...)
	# la fonction as.POSIXlt()$yday donne le jour julien de la date
	leveejj		<-as.POSIXlt(as.Date(param$levee,"%d/%m"))$yday
	dbrjj		<-as.POSIXlt(as.Date(param$dbr,"%d/%m"))$yday
	arretTrjj	<-as.POSIXlt(as.Date(param$arretTr,"%d/%m"))$yday
	tontejj		<-as.POSIXlt(as.Date(param$dtonte,"%d/%m"))$yday
	Ldbr		<-c(1:an)
	Ltonte		<-c(1:sum(param$nbtonte[1:an]))

# Calcul des indices d?bourrement
# pour la premiere annee, si la date de debourrement est anterieure au premier jour du fichier
if ((dbrjj[1]-jj[1])<0)
{
dbrjj[1]<-jj[1] # for?age au premier jour
print ("Attention : date de dbr pour l'annee 1 forcee au 1er jour")
}
# au cas ou la date de debourrement est posterieure a la fin du fichier
for (i in 1:an)
{
if (max(jj[dat$year==ans[i]])-dbrjj[i]<0)   # si la date de dbr est posterieur a la fin du fichier
{
dbrjj[i]<-max(jj[dat$year==ans[i]])
print("Attention : date de dbr de la derniere annee forcee au dernier jour")
}
Ldbr[i]<-ll[dat$year==ans[i]&jj==dbrjj[i]]
}
# Calcul des indices levee de l'herbe
Llevee<-ll[jj==leveejj]
if (an>1 & jj[1]>leveejj) Llevee=c(1,Llevee)

# pour l'annee 1, il se peut que la date de lev?e soit ant?rieure au 1er jour de donn?es
# par exemple si le fichier ne d?marre pas au 01/01
	Llevee[1] <- leveejj[1]-strptime(meteo$Date[1],param$format_date)$yday
	if (Llevee[1]<0)
	{
		Llevee[1]<-1
		print("Attention : date de levee de l'herbe pour l'annee 1 forcee au premier jour")
	}

## pour l'arret de transpiration
# si le fichier meteo se termine avant la date d'arret
LarretTr<-c(1:an)
for (i in 1:an)
{
if (max(jj[dat$year==ans[i]])-arretTrjj<0)   # si la date d'arret Transpiration est posterieur a la fin du fichier
{
LarretTr[i]<-length(ll)
print("Attention : date d'arret de transpiration de la derniere annee forcee au dernier jour")
}
if (max(jj[dat$year==ans[i]])-arretTrjj>=0)
{
LarretTr[i]<-ll[dat$year==ans[i]&jj==arretTrjj]
}
}

# pour la premiere annee, si la date de tonte est anterieure au premier jour du fichier
for (i in 1:param$nbtonte[1])
{
if ((tontejj[i]-jj[1])<0)
{
tontejj[i]<-jj[1] # for?age au premier jour
print (paste("Attention : date de tonte n?",i," pour l'annee 1 forcee au 1er jour"))
}
}
i<-1
tt<-1
repeat
{
if (tt>an) break()
if (i>sum(param$nbtonte)) break()
if (max(jj[dat$year==ans[tt]])-tontejj[i]<0)
{
Ltonte[i]<-length(ll)
print(paste("Attention : forcage date de tonte n?",i," au dernier jour"))
}
if (max(jj[dat$year==ans[tt]])-tontejj[i]>0)
{
Ltonte[i]<-ll[dat$year==ans[tt]&jj==tontejj[i]]
}
i<-i+1
if (i>cumsum(param$nbtonte)[tt]) tt<-tt+1
}

	# Calcul des vecteurs somme de T?C
	somTb10	<-vector(mode="numeric",length = dim(meteo)[1])
	for (a in 1:an)
		somTb10<-(somTb10+cumsumb(meteo$Temp,debut=Ldbr[a], fin=(jdeb[a+1]-1)))

	#   Calcul de la Pluie efficace
	Peff<-vector(mode="numeric",length=dim(meteo)[1]) #creer un vecteur vide du meme nombre de ligne que meteo
	for (i in 1:dim(meteo)[1])
			ifelse (meteo$Pluie[i]>param$seuilpeff, Peff[i]<-meteo$Pluie[i],Peff[i]<-0) # si pluie >2mm, alors Peff = pluie, sinon =0

	# Calcul de la Peff pour l'enherbement et la vigne
	Peffh<-(Peff*param$p)
	Peffv<-(Peff*(1-param$p))

	#
	# Somme des pluies des 5 derniers jours
	P5j		<-vector(mode="numeric",length=dim(meteo)[1]) #vecteur vide
	P5j[1]	<-0
	for (i in 2:5)
	  P5j[i]	<-P5j[i-1] + meteo$Pluie[i-1]
	for (i in 6:dim(meteo)[1])
	  P5j[i]<-(meteo$Pluie[i-5]+meteo$Pluie[i-4]+meteo$Pluie[i-3]+meteo$Pluie[i-2]+meteo$Pluie[i-1])

	#
	# Calcul du ruissellement herbe (inter rang)
	Seuilrui<-vector(mode="numeric",length=dim(meteo)[1]) # vecteur vide
	Ruissh<-vector(mode="numeric",length=dim(meteo)[1])   #vecteur vide
	for (i in 1:dim(meteo)[1])  # attribution de la valeur de ruissellement en fonction de la pluie des 5 derniers jours
	{
		Seuilrui[i]<-SeuilR(P5j[i],param$CN_Ruiss2,35.6,53.3)
		Ruissh[i]<-Ruiss(meteo$Pluie[i],Seuilrui[i])*param$pir
		if (param$flagRuiss=="N") Ruissh[i]=0
	}

	# Calcul du seuil ruissellement vigne (rang)
	Seuilruiv<-vector(mode="numeric",length=dim(meteo)[1]) # vecteur vide
	Ruissv<-vector(mode="numeric",length=dim(meteo)[1]) #vecteur vide
	for (i in 1:dim(meteo)[1])  # attribution de la valeur de ruissellement en fonction de la pluie des 5 derniers jours
	{
		Seuilruiv[i]<-SeuilR(P5j[i],param$CN_Ruiss,12.7,28)
		Ruissv[i]<-Ruiss(meteo$Pluie[i],Seuilruiv[i])*(1-param$pir)
		if (param$flagRuiss=="N") Ruissv[i]=0
	}

	#
	# Calcul de la pluie efficace - le ruissellement inter-rang (herbe) et rang (vigne)
	Peffh_Ruiss<-(Peffh-Ruissh)
	Peffv_Ruiss<-(Peffv-Ruissv)

	# Part de l'ETP enherbement
	ETPh<-(meteo$ETP*param$p)

	#
	# Calcul de Temp base 0 ? partir de la lev?e de l'enherbement
	Tb0<-rep(0,dim(meteo)[1])
	for (a in 1:an)
		for (i in Llevee[a]:(jdeb[a+1]-1))
			ifelse(meteo$Temp[i]>0,Tb0[i]<-meteo$Temp[i],Tb0[i]<-0)

	# Calcul du kvigne estim?
	kv<-rep(0,dim(meteo)[1]) #vecteur vide
	for (a in 1:an)
		for (i in Ldbr[a]:LarretTr[a])
		{
			kv[i]<-param$kmax[a]
			if (somTb10[i]<param$ddkmax)#
				kv[i]<-(param$kmax[a]*(somTb10[i]/param$ddkmax))  # croissance lin?aire du Kv du dbr jusqu'? somTb10=ddkmax
			if (i>(LarretTr[a]-15) & i<(length(ll)-15))  #
				kv[i]<-(param$kmax[a]-param$kmax[a]*min(1,1-(LarretTr[a]-i)/15))      # decroissance lineaire ? partir de 15j avant l'arr?t de transpiration
		}

	#
	# Calcul de INN
	INN<-rep(0,dim(meteo)[1])
	INN<-INN+param$inn # ? ce stade de d?veloppement, la valeur de INN est fix? par d?faut ? 0.3

	#
	# Calcul de Es0
	Es0<-(meteo$ETP*(1-kv)*(1-param$p))
	#
	# CALCUL du groupe evaporation du sol
	b_evap	<-(0.5*param$b1_evap*param$b2_evap)

	BHSn	<-rep(0,dim(meteo)[1])
	ESn1	<-rep(0,dim(meteo)[1])
	SES0	<-rep(0,dim(meteo)[1])
	ESn2	<-rep(0,dim(meteo)[1])
	ESn		<-rep(0,dim(meteo)[1])

	BHSn[1]	<-(param$U*(1-param$p))
	ESn1[1]	<-Es0[1]
	ESn[1]	<-(ESn1[1]+ESn2[1])
	j<-1
	repeat
	{
		j<-(j+1)
		if (j>dim(meteo)[1]) break()
		ESn1[j]<-(min(Es0[j],BHSn[j-1]))
		if (ESn1[j]<Es0[j]) SES0[j]<-(Es0[j]-ESn1[j]+SES0[j-1]) else SES0[j]<-0
		ESn2[j]	<-(max(0,(2*b_evap*SES0[j]+b_evap^2)^0.5-(2*b_evap*SES0[j-1]+b_evap^2)^0.5))
		ESn[j]	<-(ESn1[j]+ESn2[j])
		BHSn[j]	<-(min(param$U*(1-param$p),max(0,(BHSn[j-1]+meteo$Pluie[j]*(1-param$p)-ESn[j]))))
	}

	# Allocations
	crherbe<-vector(mode="numeric",length=dim(meteo)[1])
	STb0<-vector(mode="numeric",length=dim(meteo)[1])
	seneherbe<-vector(mode="numeric",length=dim(meteo)[1])
	LAIsen<-vector(mode="numeric",length=dim(meteo)[1])
	KLAI<-vector(mode="numeric",length=dim(meteo)[1])
	LAI<-vector(mode="numeric",length=dim(meteo)[1])
	Kh<-vector(mode="numeric",length=dim(meteo)[1])
	Ktransp<-vector(mode="numeric",length=dim(meteo)[1])
	ETRh<-vector(mode="numeric",length=dim(meteo)[1])
	ASWh<-vector(mode="numeric",length=dim(meteo)[1])
	FTSWh<-vector(mode="numeric",length=dim(meteo)[1])
	Dh<-vector(mode="numeric",length=dim(meteo)[1])
	Shv<-vector(mode="numeric",length=dim(meteo)[1])
	Tv<-vector(mode="numeric",length=dim(meteo)[1])
	Dv<-vector(mode="numeric",length=dim(meteo)[1])
	ASWv<-vector(mode="numeric",length=dim(meteo)[1])
	FTSWv<-vector(mode="numeric",length=dim(meteo)[1])
	ASWtot<-vector(mode="numeric",length=dim(meteo)[1])
	FTSWtot<-vector(mode="numeric",length=dim(meteo)[1])

	#######################
	# INITIALISATIONS
	LAI[1]<-param$LAIinit
	STb0[1]<-Tb0[1]
	LAIsen[1]<-param$LAIinit
	ASWv[1]<-param$ASWvinit
	ASWh[1]<-param$ASWhinit
	FTSWh[1]<-param$ASWhinit/param$TTSWh
	TTSWtot<-(param$TTSWh+param$TTSWv)
	FTSWv[1]<-param$ASWvinit/param$TTSWv
	ASWtot[1]<-(ASWv[1]+ASWh[1])
	FTSWtot[1]<-(ASWtot[1]/TTSWtot)
	Shv[1]<-min(1,FTSWtot[1]/param$FTSWvregulTR) # Effet Stress hydrique sur vigne
	KLAI[1]<-(min(1,max((FTSWh[1]/(param$FTSWhregulLAI-0.1)-0.1/param$FTSWhregulLAI),0)))
	Ktransp[1]<-min(1,FTSWh[1]/param$FTSWhregultr)  # Effet stress hydrique sur la transpiration
	Kh[1]<-0.5
	ETRh[1]<-(ETPh[1]*(1-kv[1])*Kh[1]*Ktransp[1])
	j<-1
	a<-1
	if (param$Tonte=="O") param$LAItonte<-100 # cette valeur d?sactive LAItonte si les dates de tontes sont actives
	tont<-1 # compteur de date de tonte

	#######################
	# BOUCLE JOURNALIERE
	repeat
	{

		j<-j+1
		if (j>dim(meteo)[1]) break()

		# Calcul de la s?nescence folaire de l'herbe
		crherbe[j]	<-(param$herblairate*1.71*0.001*min(18,Tb0[j])^2*KLAI[j-1]*INN[j-1])
		STb0[j]		<-STb0[j-1]+Tb0[j]
		if (STb0[j-1]>param$LLSmin | LAI[j-1]==param$LAIres) LAIsen[j]<-LAI[j-1] else LAIsen[j]<-LAIsen[j-1]
		if (STb0[j-1]>param$LLSmin) STb0[j]<-0
		seneherbe[j]<-(LAIsen[j]*max(0,Tb0[j]/param$LLSmin))

		#gestion de la dynamique du LAI incluant les eventuelles tontes
		if (LAI[j-1]>param$LAItonte)
			LAI[j]<-param$LAIres
		else
			LAI[j]<-max(0,LAI[j-1]+crherbe[j]-seneherbe[j])
		if (j==Ltonte[tont] & param$Tonte=="O")
		{
			LAI[j]<-param$LAIres
			STb0[j]<-0
			tont<-(tont+1)
		}
		if (tont>sum(param$nbtonte))
			tont<-sum(param$nbtonte)

		Kh[j]	<-(0.95*(1-exp(-0.6*LAI[j])))
		ETRh[j]	<-(ETPh[j]*(1-kv[j])*Kh[j]*Ktransp[j-1])
		Shv[j]	<-min(1,FTSWtot[j-1]/param$FTSWvregulTR) # Effet Stress hydrique sur vigne
		if (j<LarretTr[a]) Tv[j]<-(kv[j]*meteo$ETP[j]*Shv[j])
		ASWh[j]<-max(0.000001,min(param$TTSWh,ASWh[j-1]+Peffh_Ruiss[j]-ETRh[j]-(ASWh[j-1]/ASWtot[j-1])*Tv[j]))
		FTSWh[j]<-(ASWh[j]/param$TTSWh)
		Ktransp[j]	<-min(1,max(FTSWh[j]/param$FTSWhregultr,0))  # Effet stress hydrique sur la transpiration
		KLAI[j]		<-(min(1,max((FTSWh[j]/(param$FTSWhregulLAI-0.1)-0.1/param$FTSWhregulLAI-0.1),0))) # Effet stress hydrique sur LAI
		Dh[j]		<-max(0,ASWh[j-1]+Peffh_Ruiss[j]-param$TTSWh)
		Dv[j]		<-max(0,ASWv[j-1]+Peffv_Ruiss[j]-param$TTSWv)
		ASWv[j]		<-max(0,min(param$TTSWv,ASWv[j-1]+Peffv_Ruiss[j]-(ASWv[j-1]/ASWtot[j-1])*Tv[j]-ESn[j]+Dh[j]))
		if (param$irri=="O") ASWv[j]<-ASWv[j]+meteo$IR[j] # s'il  a de l'irrigation, on la rajoute directement ? l'ASWv
		FTSWv[j]<-(ASWv[j]/param$TTSWv)
		ASWtot[j]<-(ASWv[j]+ASWh[j])
		FTSWtot[j]<-(ASWtot[j]/TTSWtot)
		if (param$reinit=="O" & j==(jdeb[a+1]-1)) ASWv[j]<-param$TTSWv
		if (param$reinit=="O" & j==(jdeb[a+1]-1)) ASWh[j]<-param$TTSWh
		if (j==(jdeb[a+1]-1)) a<-(a+1)
	}
	# FIN DE LA BOUCLE SUR LES JOURS DE SIMULATION

	#
	#BHr<-data.frame(meteo,Peff,
	BHr<-list(meteo,Peff, Kh,ETRh,crherbe,seneherbe,KLAI,Tb0,LAI,kv,Tv,Shv,BHSn,Es0,ESn1,ESn2,SES0,ESn,ETPh,Dh,Dv,Ruissv,Ruissh,ASWv,ASWh,ASWtot=ASWtot,FTSWh,FTSWv,FTSWtot,Peffh_Ruiss,Peffv_Ruiss,P5j)
	names(BHr)<-c("meteo","Peff", "Kh","ETRh","crherbe","seneherbe","KLAI","Tb0","LAI","kv","Tv","Shv","BHSn","Es0","ESn1","ESn2","SES0","ESn","ETPh","Dh","Dv","Ruissv","Ruissh","ASWv","ASWh","ASWtot","FTSWh","FTSWv","FTSWtot","Peffh_Ruiss","Peffv_Ruiss","P5j")
  return(BHr)
} # FIN de la fonction Bilan hydrique
#

#######################################################
# application du mod?le sur des matrices de param?tres

walis.model <- function(param, clim_data)
return(apply(param,walis.model.single,clim_data))

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


## Calculate timeseries stats, moving across timeseries to detect changepoint in experiment 2
## Launch model

library(doParallel)
library(foreach)
library(iterators)
library(dplyr)
library(zoo)

source("summary_functions.R")

registerDoParallel(cores=4)

calc_stats=function(wd,run,count_dead=TRUE){
  print(run)
  data_frame=read.csv(paste0(wd,run,"/sim_list.csv"))

  FD_frame=data.frame(ID=0,year=0,SPLIT_YEAR = 0,FD_RealSeries=0,FD_CensusSeries=0,FD_T_500=0,FD_T_250=0,FD_T_100=0,FD_T_50=0,FD_T_25=0,FD_T_10=0,FD_R_500=0,FD_R_250=0,FD_R_100=0,FD_R_50=0,FD_R_25=0,FD_R_10=0)
  AB_frame=data.frame(ID=0,year=0,SPLIT_YEAR = 0,AB_RealSeries=0,AB_CensusSeries=0,AB_T_500=0,AB_T_250=0,AB_T_100=0,AB_T_50=0,AB_T_25=0,AB_T_10=0,AB_R_500=0,AB_R_250=0,AB_R_100=0,AB_R_50=0,AB_R_25=0,AB_R_10=0)

  for(idx in 1:dim(data_frame)[1]){
    print(paste0("__",idx))
    print(idx)

    aa=load(paste0(wd,run,"/fire_record_",idx,".Rdata"),env=environment())
    this_tree=read.csv(paste0(wd,run,"/tree_frame_",idx,".csv"))

    if(!count_dead){
      this_tree=subset(this_tree,STATUS==0)
    }

    ## Real count of fires per decade.

    field_size=dim(this_fire)[1] * dim(this_fire)[2]
    fc=apply(this_fire,MARGIN=3,FUN=sum)
    fc=fc>0
    g=rollapply(fc,10,sum)

    ###
    FD_RealSeries=g
    FD_CensusSeries=rollapply(f_tree_tsyear(this_tree,this_fire)$scars>0,10,sum)
    ###

    # Shuffle this_tree so the ordered trees have a random subset within them, or else all the dead ones will be at the bottom
    this_tree$shuffler=sample(dim(this_tree)[1])

    ## Calculate a summary of the number of scars per tree, for filtering
    this_tree=group_by(this_tree,ID)

    scar_count=summarise(this_tree,count=length(YBP),MFI=f_tree_MFIhelper(YBP),shuffler=first(shuffler))
    scar_count=arrange(scar_count,desc(count),shuffler)
    scar_count=as.data.frame(scar_count)
    scar_count=subset(scar_count,is.finite(scar_count$MFI))

    this_tree=as.data.frame(this_tree)

    ## Targeted subsets
    FD_T_500 = rollapply(f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:500,]$ID),this_fire)$scars>0,10,sum)
    FD_T_250 = rollapply(f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:250,]$ID),this_fire)$scars>0,10,sum)
    FD_T_100 = rollapply(f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:100,]$ID),this_fire)$scars>0,10,sum)
    FD_T_50 = rollapply(f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:50,]$ID),this_fire)$scars>0,10,sum)
    FD_T_25 = rollapply(f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:25,]$ID),this_fire)$scars>0,10,sum)
    FD_T_10 = rollapply(f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:10,]$ID),this_fire)$scars>0,10,sum)

    ## Random subsets
    FD_R_500 = rollapply(f_tree_tsyear(this_tree[sample(dim(this_tree)[1],500),],this_fire)$scars>0,10,sum)
    FD_R_250 = rollapply(f_tree_tsyear(this_tree[sample(dim(this_tree)[1],250),],this_fire)$scars>0,10,sum)
    FD_R_100 = rollapply(f_tree_tsyear(this_tree[sample(dim(this_tree)[1],100),],this_fire)$scars>0,10,sum)
    FD_R_50 = rollapply(f_tree_tsyear(this_tree[sample(dim(this_tree)[1],50),],this_fire)$scars>0,10,sum)
    FD_R_25 = rollapply(f_tree_tsyear(this_tree[sample(dim(this_tree)[1],25),],this_fire)$scars>0,10,sum)
    FD_R_10 = rollapply(f_tree_tsyear(this_tree[sample(dim(this_tree)[1],10),],this_fire)$scars>0,10,sum)

    ################### Now area burnt

    field_size=dim(this_fire)[1] * dim(this_fire)[2]
    fc=apply(this_fire,MARGIN=3,FUN=sum)
    g=fc/field_size

    ###
    AB_RealSeries=g
    AB_CensusSeries=f_tree_tsyear(this_tree,this_fire)$perc
    ###

    AB_T_500 = f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:500,]$ID),this_fire)$perc
    AB_T_250 = f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:250,]$ID),this_fire)$perc
    AB_T_100 = f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:100,]$ID),this_fire)$perc
    AB_T_50 = f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:50,]$ID),this_fire)$perc
    AB_T_25 = f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:25,]$ID),this_fire)$perc
    AB_T_10 = f_tree_tsyear(subset(this_tree,this_tree$ID %in% scar_count[1:10,]$ID),this_fire)$perc

    ## Random subsets
    AB_R_500 = f_tree_tsyear(this_tree[sample(dim(this_tree)[1],500),],this_fire)$perc
    AB_R_250 = f_tree_tsyear(this_tree[sample(dim(this_tree)[1],250),],this_fire)$perc
    AB_R_100 = f_tree_tsyear(this_tree[sample(dim(this_tree)[1],100),],this_fire)$perc
    AB_R_50 = f_tree_tsyear(this_tree[sample(dim(this_tree)[1],50),],this_fire)$perc
    AB_R_25 = f_tree_tsyear(this_tree[sample(dim(this_tree)[1],25),],this_fire)$perc
    AB_R_10 = f_tree_tsyear(this_tree[sample(dim(this_tree)[1],10),],this_fire)$perc

    ## bind it

    t_FD=data.frame(ID=rep(idx,length(FD_RealSeries)),year=seq_along(FD_RealSeries),SPLIT_YEAR=rep(data_frame$SPLIT_YEAR[idx],length(FD_RealSeries)),FD_RealSeries,FD_CensusSeries,FD_T_500,FD_T_250,FD_T_100,FD_T_50,FD_T_25,FD_T_10,FD_R_500,FD_R_250,FD_R_100,FD_R_50,FD_R_25,FD_R_10)
    t_AB=data.frame(ID=rep(idx,length(AB_RealSeries)),year=seq_along(AB_RealSeries),SPLIT_YEAR=rep(data_frame$SPLIT_YEAR[idx],length(AB_RealSeries)),AB_RealSeries,AB_CensusSeries,AB_T_500,AB_T_250,AB_T_100,AB_T_50,AB_T_25,AB_T_10,AB_R_500,AB_R_250,AB_R_100,AB_R_50,AB_R_25,AB_R_10)

    FD_frame=rbind(FD_frame,t_FD)
    AB_frame=rbind(AB_frame,t_AB)
  }

  FD_frame=subset(FD_frame,ID>0)
  AB_frame=subset(AB_frame,ID>0)

  write.csv(FD_frame,paste0(wd,run,"/FD_timeseries_",count_dead,".csv"))
  write.csv(AB_frame,paste0(wd,run,"/AB_timeseries_",count_dead,".csv"))
}

# Do the narrow/wide
td_vec=c("e2_range_narrow","e2_range_wide")
foreach(i=iter(td_vec),.packages=c("dplyr","zoo")) %dopar% calc_stats(working_dir,i)

#for(i in td_vec){
#  print(i)
#  calc_stats(working_dir,i)
#}


#  James Rekow

aggBaseCaseDOCCreatorSameCohort = function(M = 40, N = 20, iStrength = 1, univ = 1, intIx = NULL,
                                           sigmaMax = 0.1, thresholdMult = 10 ^ (-2), maxSteps = 10 ^ 4,
                                           tStep = 10 ^ (-2), intTime = 1, interSmplMult = 0.01,
                                           lambda = NULL, numDOC = 10){

  #  ARGS: numDOC - number of DOCs from which the aggregate points should be assembled
  #
  #  RETURNS: aggDOCDF - an aggregate DOC comprised of points from numDOC number of cohorts
  #                      with streamlined interaction steps (e.g. there is a completely connected
  #                      subset of interacting samples and a constellation of non-interacting samples
  #                      that don't interact at all). Each point also has a replicate ID associated with
  #                      it that tracks which replicate it was from, and the number of interacting
  #                      samples (0, 1, or 2) corresponding to it (e.g. if two interacting samples
  #                      are compared to create a DOC point this number would be 2)

  source("DOCProcedure.r")
  source("cohortCreator.r")
  source("eulerIntegrate.r")
  source("intraCohortInteraction_optimizedBaseCase.r")

  #  set default value of lambda
  if(is.null(lambda)){

    lambda = -0.5 * M * log(0.5)

  } #  end if

  #  let half of the samples be interacting samples
  numI = floor(M / 2)

  #  if intIx is not specified, randomly select half of the samples to interact
  if(is.null(intIx)){

    numI = floor(M / 2)
    intIx = sample(1:M, numI)

  } #  end if

  #  create a numerical vector with 1's in positions with the indices of interacting elements
  #  and 0's elsewhere
  intSmpls = rep(0, M)
  intSmpls[intIx] = 1

  #  create a matrix whose columns are each unique pair of sample indices
  pairMat = combn(M, 2)

  #  function to count the number of interacting samples in a vector of sample indices
  intCounter = function(ixVec) sum(intSmpls[ixVec])

  #  numerical vector of the number of samples in each sample pair that were interacting samples
  intCount = apply(pairMat, 2, intCounter)

  #  used to determine if the system is near equilibrium
  threshold = {thresholdMult * tStep} ^ 2

  #  define integrator function to apply eulerIntegrate with desired parameter vals
  integrator = function(smpl){
    return(eulerIntegrate(smpl, threshold = threshold, maxSteps = maxSteps, tStep = tStep))
  } #  end integrator function

  #  create cohort
  chrt = cohortCreator(M = M, N = N, iStrength = iStrength, univ = univ, sigmaMax = sigmaMax)

  #  integrate samples in the cohort and store the abundance vectors in a list
  abdList = lapply(chrt, integrator)

  produceDOCDF = function(n){

    #  simulate intra-cohort interaction if lambda > 0
    if(lambda > 0){

      #  update the abundances of each sample in the cohort
      for(i in 1:M){
        chrt[[i]][[1]] = abdList[[i]]
      } #  end for

      #  simulate intra-cohort interactions
      intAbdList = intraCohortInteraction_optimizedBaseCase(intIx = intIx, chrt = chrt, M = M, N = N,
                                                            lambda = lambda, threshold = threshold,
                                                            maxSteps = maxSteps, tStep = tStep,
                                                            intTime = intTime,
                                                            interSmplMult = interSmplMult)

    } #  end if

    #  create DOC
    doc = DOCProcedure(intAbdList)

    #  store data in a data frame
    DOCDF = data.frame(replicateID = n, intCount = intCount, over = doc$x, diss = doc$y)

    return(DOCDF)

  } #  end produceDOC function

  #  create a list of replicate data frames
  DOCDFList = lapply(as.list(1:numDOC), produceDOCDF)

  #  aggregate data from the replicates
  aggDOCDF = Reduce(rbind, DOCDFList)

  #  make the intCount variable a factor (mostly for plotting purposes)
  aggDOCDF$intCount = as.factor(aggDOCDF$intCount)

  return(aggDOCDF)

} #  end aggBaseCaseDOCCreatorSameCohort function


# Script for phylogeny dating

# 1. Ne estimation ################################################################################################
data <- read.csv("mutation_rate.txt", sep =" ", header=FALSE)

average=mean(data[,2])
average
ne= 0.00247 /(4*mu)

# 2. Dating phylogeny ################################################################################################
library(RColorBrewer)
library(dplyr)
library(ape)
library(phytools)

gt_m = 11
# Distances
d_Pongo_abelii <- 0.0162551430672998
d_Homo_sapiens <- 0.00577676246248343
d_Pan_troglodytes <- 0.00612226407385174
d_h_c <- 0.00928793113723326
d_ape <- 0.0111854267754341
d_Macaca_mulatta <-0.00260875810745442
d_Macaca_f <- 0.0022282726931979
d_macaca_macaca <-0.00464525362885664
d_baboon <- 0.00686281100087727
d_maca_bab <- 0.00399650084545229
d_Chlorocebus_sabaeus <- 0.0111626595169656
d_m_g <- 0.0246717581129659

# Using only the new estimated on the branches in question
mu_rhesus= ((4.8399 + 1.8364 *12+ 4.6497+ 0.3042 *10)*(1-0.10887096774193548)/(2*2351302179*(1-0.04020232294960846)))
mu_m = (mu_rhesus/11)*1000000
mu_rhesus_min= ((25.158457+5.065827)*(1-0.10887096774193548)/(2*2351302179*(1-0.04020232294960846)))
CI_min= (mu_rhesus_min/11)*1000000
mu_rhesus_max= ((28.59583+10.317069)*(1-0.10887096774193548)/(2*2351302179*(1-0.04020232294960846)))
CI_max= (mu_rhesus_max/11)*1000000

# Macaca-macaca
t_m = (d_Macaca_mulatta)/(mu_m)
t_m_min = (d_Macaca_mulatta)/(CI_min)
t_m_max = (d_Macaca_mulatta)/(CI_max)
# Macaca-baboon
t_m_b = (d_Macaca_mulatta+d_macaca_macaca)/(mu_m)
t_m_b_min = (d_Macaca_mulatta+d_macaca_macaca)/(CI_min)
t_m_b_max = (d_Macaca_mulatta+d_macaca_macaca)/(CI_max)
# Macaca-green
t_m_g = (d_Macaca_mulatta+d_macaca_macaca+d_maca_bab)/(mu_m)
t_m_g_min = (d_Macaca_mulatta+d_macaca_macaca+d_maca_bab)/(CI_min)
t_m_g_max = (d_Macaca_mulatta+d_macaca_macaca+d_maca_bab)/(CI_max)

# Macaca with great apes
t_m_a = (d_Macaca_mulatta+d_macaca_macaca+d_maca_bab+d_m_g)/(mu_m)
t_m_a_min = (d_Macaca_mulatta+d_macaca_macaca+d_maca_bab+d_m_g)/(CI_min)
t_m_a_max = (d_Macaca_mulatta+d_macaca_macaca+d_maca_bab+d_m_g)/(CI_max)

##
# Babon rate:
mu_b = 0.549e-9*1000000
d_baboon/mu_b
# Green rate:
mu_g = 1.11e-9*1000000
d_Chlorocebus_sabaeus/mu_g
# Homo:
mu_h= 0.43e-9*1000000
(d_ape+d_h_c+d_Homo_sapiens)/mu_h
# Chimp
mu_c= 0.64e-9*1000000
(d_ape+d_h_c+d_Pan_troglodytes)/mu_c

# Model
mu_nwm=2.7e-9*1000000
(d_Macaca_mulatta+d_macaca_macaca)/mu_m
(d_maca_bab+d_m_g)/mu_g
d_maca_bab/mu_g
d_m_g/mu_nwm

####
tree_t_new_reg<-read.tree("tree_timed_rhesus_estimate_last_reg.nwk")
tree_t_topo<-read.tree("tree_timed_rhesus_estimate_topo_reg.nwk")
tree_t_sp<-read.tree("tree_timed_rhesus_estimate_sp_reg.nwk")

CI= rbind(c(t_m_a_min,t_m_a_max),
          c(t_m_g_min,t_m_g_max),
          c(t_m_b_min,t_m_b_max),
          c(t_m_min,t_m_max))

# speciation
minus_m=(2*79874*11)/1000000
minus_cat=(2*355000*11)/1000000

sp_t_m = t_m -minus_m
sp_t_m_a =t_m_a-minus_cat

#
png("phylo_diff_sp_n_reg_last.png", width = 1200, height = 750)
par(xaxt="n",yaxt="n",mar=c(5.1,6.1,2.1,2), mgp=c(5, 1.5, 0))
plotTree.errorbars(tree_t_new_reg, CI, fsize=3, ftype="off", lwd=10, bar.width=0, cex=2.5, xlab="",ylab="", at=seq(0,45,by=5))
#
polygon(c(sp_t_m,sp_t_m,t_m,t_m), c(1,2,2,1), col = "gray80", border="gray80")
polygon(c(sp_t_m_a,sp_t_m_a,t_m_a,t_m_a), c(3.13,5,5,3.13), col = "gray80", border="gray80")
#
axis(1, at=seq(0,55,by=5), cex.axis=2)
#
abline(v=60, lty=2, lwd=4, col="gray65")
abline(v=55, lty=2, lwd=4, col="gray65")
abline(v=50, lty=2, lwd=4, col="gray65")
abline(v=45, lty=2, lwd=4, col="gray65")
abline(v=40, lty=2, lwd=4, col="gray65")
abline(v=35, lty=2, lwd=4, col="gray65")
abline(v=30, lty=2, lwd=4, col="gray65")
abline(v=25, lty=2, lwd=4, col="gray65")
abline(v=20, lty=2, lwd=4, col="gray65")
abline(v=15, lty=2, lwd=4, col="gray65")
abline(v=10, lty=2, lwd=4, col="gray65")
abline(v=5, lty=2, lwd=4, col="gray65")
abline(v=0, lty=2, lwd=4, col="gray65")
#
lines(c(50.09,50.09),c(5,3.15), lwd=10, col="gray52")
lines(c(2.45,2.45),c(1,2), lwd=10, col="gray52")
points(c(50.09),c(4.06), lwd=15,pch=20, col="navy")
points(c(2.45),c(1.5), lwd=15,pch=20, col="navy")
par(new=TRUE)
par(xaxt="n",yaxt="n",mar=c(5.1,5.1,2.1,2), mgp=c(5, 1.5, 0))
## ftype= "reg" "i" "b"
plotTree.errorbars(tree_t_new_reg, CI, fsize=3, ftype="i", lwd=10, bar.width=20, cex=2.5, xlab="",ylab="", at=seq(0,45,by=5),bar.col="darkgreen")
##plotTree.errorbars(tree_t_sp, CI, fsize=3, ftype="i", lwd=10, bar.width=20, cex=2.5, xlab="",ylab="", at=seq(0,45,by=5),bar.col="darkblue")
##CI_s=rbind(cbind(50.09,50.09),c(18.13,18.13),c(11.69,11.69),c(2.45,2.45))
##plotTree.errorbars(tree_t_sp, CI_s, fsize=3, ftype="i", lwd=10,bar.width=20, cex=2.5, xlab="",ylab="", at=seq(0,45,by=5),bar.col="darkblue")
#
par(xaxt="s",yaxt="s",font.lab=4)
axis(1, at=seq(0,60,by=5), cex.axis=2)
#
text(c(10,19.5,30,58.2), c(1.35,2.1,2.98,3.915),labels = c("Macaca", "Papionini", "Cercopithecidae", "Catarrhini"), font=1, cex=2.3)
text(c(10,58.2), c(1.2,3.765),labels = c(expression("(N"[e]*" = 79,874)"), expression("(N"[e]*" = 355,000)")), font=2, cex=1.6)
text(c(-0.1,-2), c(1.62,1.48),labels = c(expression("T"[d]*"=4.20"),expression("T"[s]*"=2.45")), col=c("darkgreen","navy"), font=2, cex=1.8)
text(c(6.5), c(2.4),labels = c(expression("T"[d]*"=11.69")), col=c("darkgreen"), font=2, cex=1.8)
text(c(13), c(3.28),labels = c(expression("T"[d]*"=18.13")), col=c("darkgreen"), font=2, cex=1.8)
text(c(52.5,45.5), c(4.17,3.9),labels = c(expression("T"[d]*"=57.90"),expression("T"[s]*"=50.09")), col=c("darkgreen","navy"), font=2, cex=1.8)
#
# add fossils:
points(c(22,22,33.5), c(3.12,5,4.05), pch=4, lwd=5, col="red")
text(c(28,22,33.5), c(3.22,5.1,4.15),labels = c("Victoriapithecus", "Proconsul", "Aegyptopithecus"), , col=c("red"), font=3, cex=1.8)
dev.off()

# 3. compare estimate with literature ######################################################################################################################
div_me <- c(4.20,11.69,18.13,57.90)
div_lit_nucl <- c(3.53, 8.13, 11.5, 31.6)
div_lit_mito <- c(3.44, 12.17, 14.09, 32.12)

png("estimation_dif_met.png", width = 1300, height = 850)
par(mar=c(9,15,4,2), mgp=c(3, 3, 0))
plot(div_lit_mito, div_me, type='o', pch=19, lwd=4, xlim=c(0,60), ylim=c(0,60), xlab="", ylab="",
     cex=3, cex.lab=2.5, cex.axis=2.5, xaxt="n", yaxt="n", lty=1)
lines(div_lit_nucl, div_me, type='o', pch=19, lwd=4, xlab="", ylab="", cex=3, cex.lab=2.5, cex.axis=2.5, xaxt="n", yaxt="n", lty=1, col="gray60")
abline(0,1, lwd=2, lty=1, col="black")
points(div_lit_mito, div_me, pch=21, lwd=3, cex=4, cex.lab=2.5, cex.axis=2.5, col=1, bg=c("aquamarine4", "firebrick1", "dodgerblue4", "darkgoldenrod2"))
points(div_lit_nucl, div_me, pch=21, lwd=3, cex=4, cex.lab=2.5, cex.axis=2.5, col="gray60", bg=c("aquamarine4", "firebrick1", "dodgerblue4", "darkgoldenrod2"))
text(c(7.5, 18, 6.5, 38),c(1, 11.5, 26.5, 56), labels=c("Macaca", "Papionini", "Cercopithecidae","Catarrhini"),
     font=c(4,2,2,2), cex=3, col=c("aquamarine4", "firebrick1", "dodgerblue4", "darkgoldenrod2"))
axis(1, cex.axis=4)
axis(2, cex.axis=4, las=2)
mtext("Time (in Mya) from the molecular clock", 1, line=7, cex=4)
mtext("Time (in Mya) from our estimate", 2, line=9, cex=4)
legend("topleft", c(expression("T"[divergence]*" compare to mitochondrial data"), expression("T"[divergence]*" compare to nuclear data")), col=c("black", "gray60"), lty=c(1,1), lwd=3, cex=2, bty = "n")
dev.off()


library (gsubfn)
setwd('/src/r')
source('Melting.r')
source('Refreezing.r')
source('Snowaccumulation.r')
source('Snowdensity.r')
source('Snowdepth.r')
source('Snowdepthtrans.r')
source('Snowdry.r')
source('Snowmelt.r')
source('Snowwet.r')
source('Tavg.r')
source('Tempmax.r')
source('Tempmin.r')
source('Preciprec.r')

model_snow <- function (jul = 0,
         Tmf = 0.0,
         SWrf = 0.0,
         tsmax = 0.0,
         precip = 0.0,
         DKmax = 0.0,
         trmax = 0.0,
         tmax = 0.0,
         ps_t1 = 0.0,
         Sdepth_t1 = 0.0,
         Sdry_t1 = 0.0,
         Swet_t1 = 0.0,
         rho = 100.0,
         Kmin = 0.0,
         Pns = 100.0,
         tmaxseuil = 0.0,
         tminseuil = 0.0,
         tmin = 0.0,
         prof = 0.0,
         E = 0.0){
    #'- Name: Snow -Version: 1.0, -Time step: 1
    #'- Description:
    #'            * Title: Snow model
    #'            * Author: STICS
    #'            * Reference: Snow paper
    #'            * Institution: STICS
    #'            * Abstract: Snow
    #'- inputs:
    #'            * name: jul
    #'                          ** description : current day of year for the calculation
    #'                          ** inputtype : variable
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : INT
    #'                          ** default : 0
    #'                          ** min : 0
    #'                          ** max : 366
    #'                          ** unit : d
    #'                          ** uri :
    #'            * name: Tmf
    #'                          ** description : threshold temperature for snow melting
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: SWrf
    #'                          ** description : degree-day temperature index for refreezing
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : mmW/degC/d
    #'                          ** uri :
    #'            * name: tsmax
    #'                          ** description : maximum daily air temperature (tmax) below which all precipitation is assumed to be snow
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 1000
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: precip
    #'                          ** description : current precipitation
    #'                          ** inputtype : variable
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: DKmax
    #'                          ** description : difference between the maximum and the minimum melting rates
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : mmW/degC/d
    #'                          ** uri :
    #'            * name: trmax
    #'                          ** description : tmax above which all precipitation is assumed to be rain
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: tmax
    #'                          ** description : current maximum air temperature
    #'                          ** inputtype : variable
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: ps_t1
    #'                          ** description : density of snow cover in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 100.0
    #'                          ** unit : kg/m**3
    #'                          ** uri :
    #'            * name: Sdepth_t1
    #'                          ** description : snow cover depth Calculation in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : m
    #'                          ** uri :
    #'            * name: Sdry_t1
    #'                          ** description : water in solid state in the snow cover in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: Swet_t1
    #'                          ** description : water in liquid state in the snow cover in previous day
    #'                          ** inputtype : variable
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 100.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: rho
    #'                          ** description : The density of the new snow fixed by the user
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 100
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : kg/m**3
    #'                          ** uri :
    #'            * name: Kmin
    #'                          ** description : minimum melting rate on 21 December
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : mmW/degC/d
    #'                          ** uri :
    #'            * name: Pns
    #'                          ** description : density of the new snow
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 100.0
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : cm/m
    #'                          ** uri :
    #'            * name: tmaxseuil
    #'                          ** description : maximum temperature when snow cover is higher than prof
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: tminseuil
    #'                          ** description : minimum temperature when snow cover is higher than prof
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 5000.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: tmin
    #'                          ** description : current minimum air temperature
    #'                          ** inputtype : variable
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 100.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: prof
    #'                          ** description : snow cover threshold for snow insulation
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min : 0.0
    #'                          ** max : 1000
    #'                          ** unit : cm
    #'                          ** uri :
    #'            * name: E
    #'                          ** description : snow compaction parameter
    #'                          ** inputtype : parameter
    #'                          ** parametercategory : constant
    #'                          ** datatype : DOUBLE
    #'                          ** default : 0.0
    #'                          ** min :
    #'                          ** max :
    #'                          ** unit : mm/mm/d
    #'                          ** uri :
    #'- outputs:
    #'            * name: M
    #'                          ** description : snow in the process of melting
    #'                          ** variablecategory : rate
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW/d
    #'                          ** uri :
    #'            * name: tminrec
    #'                          ** description : recalculated minimum temperature
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: Sdepth
    #'                          ** description : snow cover depth Calculation
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : m
    #'                          ** uri :
    #'            * name: Sdry
    #'                          ** description : water in solid state in the snow cover
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: Snowaccu
    #'                          ** description : snowfall accumulation
    #'                          ** variablecategory : rate
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW/d
    #'                          ** uri :
    #'            * name: ps
    #'                          ** description : density of snow cover
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : kg/m**3
    #'                          ** uri :
    #'            * name: Swet
    #'                          ** description : water in liquid state in the snow cover
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: tavg
    #'                          ** description : mean temperature
    #'                          ** variablecategory : auxiliary
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: Mrf
    #'                          ** description : liquid water in the snow cover in the process of refreezing
    #'                          ** variablecategory : rate
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW/d
    #'                          ** uri :
    #'            * name: tmaxrec
    #'                          ** description : recalculated maximum temperature
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : degC
    #'                          ** uri :
    #'            * name: preciprec
    #'                          ** description : recalculated precipitation
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : mmW
    #'                          ** uri :
    #'            * name: Snowmelt
    #'                          ** description : Snow melt
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : m
    #'                          ** uri :
    #'            * name: Sdepth_cm
    #'                          ** description : snow cover depth in cm
    #'                          ** variablecategory : state
    #'                          ** datatype : DOUBLE
    #'                          ** min : 0.0
    #'                          ** max : 500.0
    #'                          ** unit : cm
    #'                          ** uri :
    Snowaccu <- model_snowaccumulation(tsmax, tmax, trmax, precip)
    ps <- model_snowdensity(ps_t1, Sdepth_t1, Sdry_t1, Swet_t1)
    tavg <- model_tavg(tmin, tmax)
    M <- model_melting(jul, Tmf, DKmax, Kmin, tavg)
    Mrf <- model_refreezing(tavg, Tmf, SWrf)
    Snowmelt <- model_snowmelt(ps, M)
    Sdry <- model_snowdry(Sdry_t1, Snowaccu, Mrf, M)
    Sdepth <- model_snowdepth(Snowmelt, Sdepth_t1, Snowaccu, E, rho)
    Swet <- model_snowwet(Swet_t1, precip, Snowaccu, Mrf, M, Sdry)
    Sdepth_cm <- model_snowdepthtrans(Sdepth, Pns)
    preciprec <- model_preciprec(Sdry_t1, Sdry, Swet, Swet_t1, Sdepth_t1, Sdepth, Mrf, precip, Snowaccu, rho)
    tminrec <- model_tempmin(Sdepth_cm, prof, tmin, tminseuil, tmaxseuil)
    tmaxrec <- model_tempmax(Sdepth_cm, prof, tmax, tminseuil, tmaxseuil)
    return (list ("M" = M,"tminrec" = tminrec,"Sdepth" = Sdepth,"Sdry" = Sdry,"Snowaccu" = Snowaccu,"ps" = ps,"Swet" = Swet,"tavg" = tavg,"Mrf" = Mrf,"tmaxrec" = tmaxrec,"preciprec" = preciprec,"Snowmelt" = Snowmelt,"Sdepth_cm" = Sdepth_cm))
}