https://github.com/MVCowley/in-silico-FSHD-muscle-fiber-tools
Raw File
Tip revision: 9f58e15ab2713f50f20132c52e3250d0aa949f37 authored by Matthew V. Cowley on 18 June 2023, 06:45:01 UTC
Update README.md
Tip revision: 9f58e15
server.r
# This file is part of a set of shiny applications for the analysis of in silico
# FSHD muscle fibres.
# Copyright © 2023 C. R. S. Banerji
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <https://www.gnu.org/licenses/>.

load("files_for_KM_plot_shiny_not_refined.rd")
library(shiny)
library("tidyverse")
library('deSolve')
library('survival')
library("survminer")
library('ggplot2')
server<-function(input,output,session){
  #########define reative values which update as the automaton evolves
  rvs<-reactiveValues(alive=array(c(0,0,0),dim=c(100*24,3)),D4n=array(c(0,0,0),dim=c(100*24,3)),
                      D4Tn=array(c(0,0,0),dim=c(100*24,3)),events_a=array(c(0,0,0),dim=c(20000,3)),
                      events_D4n=array(c(0,0,0),dim=c(20000,3)),events_D4Tn=array(c(0,0,0),dim=c(20000,3)),
                      reset=0)
  #########output dynamically updating plot of automaton at the top
  #########define the update observations
  observe({
    ############asign variables based on user input
    vD<-input$vD
    d0<-input$d0
    vT<-input$vT
    TD<-input$TD
    death_rate<-input$death_rate
    #define sc_model
    sc_model <- function (t, x, params) {
      ## state variables
      S <- x[1]
      E <- x[2]
      I <- x[3]
      R <- x[4]
      D <- x[5]
      ## parameters
      vD <- params["vD"]
      d0 <- params["d0"]
      vT <- params["vT"]
      TD <- params["TD"]
      death_rate <- params["death_rate"]
      N <- S+E+I+R
      ## now code the model equations
      dSdt <- d0*E - vD*S
      dEdt <- vD*S - (d0+TD*vT)*E
      dIdt <- TD*vT*E + vD*R - d0*I - death_rate*I
      dRdt <- d0*I - vD*R - death_rate*R
      dDdt <- death_rate*(I+R)
      ## combine results into a single vector
      dxdt <- c(dSdt,dEdt,dIdt,dRdt,dDdt)
      ## return result as a list
      list(dxdt)
    }
    ###############execute for true params
    parms <- c(d0=0.2464819,vD=0.002113848,vT=6.41248,death_rate=1/20.2,TD=1/13)
    times <- seq(from=0,to=24*100,by=1)
    xstart <- c(S=5133*(1+per_D_at_D3_sc_adj_trans),E=0,I=0,R=0,D=0)
    ######
    ode(
      func=sc_model,
      y=xstart,
      times=times,
      parms=parms
    ) %>%
      as.data.frame() -> out
    ######convert this to %alive at each time point
    5133*(1+per_D_at_D3_sc_adj_trans)->n_sc
    1-out$D/n_sc->per_alive_true
    ######now to %DUX4 naieve at each time point
    out$S/n_sc->per_D4n_true
    ######now to %target naieve at each time point
    (out$S+out$E)/n_sc->per_D4Tn_true
    ##################now run for a perturbed parameter
    if(d0==0.2464819 & vD==0.002113848 & vT==6.41248 & death_rate==1/20.2 & TD==1/13){out_pert<-out}else{parms <- c(d0=d0,vD=vD,vT=vT,death_rate=death_rate,TD=TD)
    ###############
    ode(
      func=sc_model,
      y=xstart,
      times=times,
      parms=parms
    ) %>%
      as.data.frame() -> out_pert}
    ############
    1-out_pert$D/n_sc->per_alive_p
    out_pert$S/n_sc->per_D4n_p
    (out_pert$S+out_pert$E)/n_sc->per_D4Tn_p
    data.frame(out$time,per_alive_true,per_alive_p)->rvs$alive
    data.frame(out$time,per_D4n_true,per_D4n_p)->rvs$D4n
    data.frame(out$time,per_D4Tn_true,per_D4Tn_p)->rvs$D4Tn
  })
  output$plot1<-renderPlot({
    rvs$alive->alive_comp
    names(alive_comp)<-c("time","True Parameters","Test Parameters")
    gather(alive_comp,variable,value,-time)->alive
    #######
    ggplot(alive,aes(x=time,y=value,color=variable))+
      geom_line(size=2)+
      theme_classic()+
      labs(x='time (hrs)',y='% cells alive')+
      ggtitle("Proportion of Cells Alive Single cell model")
  })
  #####automaton
  observe({
    if(rvs$reset==0){
      return(NULL)
    }
    ####start with automaton here
    ###define inputs for true model first
    d0=0.2464819
    vD=0.002113848
    vT=6.41248
    death_rate=1/20.2
    TD=1/13
    diffusion=0.0402
    n_iter<-input$n_iter
    mt_l<-input$mt_l
    mt_c<-input$mt_c
    ############define CA update rules based on the user input and SEIR model
    state_evolve<-function(state){
      if(state=="S"){
        if(rexp(1,vD)<1){state<-"E"}
        else{state="S"}
      }
      else
        if(state=="E"){
          if(rexp(1,TD*vT+d0)<1){
            if(rexp(1,TD*vT)<rexp(1,d0)){state="I"}else{state="S"}
          }
          else{state="E"}
        }
      else
        if(state=="I"){
          if(rexp(1,death_rate+d0)<1){
            if(rexp(1,death_rate)<rexp(1,d0)){state="D"}else{state="R"}
          }
          else{state="I"}
        }
      else
        if(state=="R"){
          if(rexp(1,death_rate+vD)<1){
            if(rexp(1,death_rate)<rexp(1,vD)){state="D"}else{state="E"}
          }
          else{state="R"}
        }
      return(state)
    }
    #############Diffusion interaction model on neighbours
    diffusion_function<-function(state){
      if(state=="S"){
        if(rexp(1,diffusion)<1){state<-"R"}
        else{state="S"}
      }
      if(state=="E"){
        if(rexp(1,diffusion)<1){state<-"I"}
        else{state="E"}
      }
      return(state)
    }
    ############
    ret3_f<-function(mt_l,mt_c){
      mat.or.vec(mt_l,mt_c)->y
      y[1:length(y)]<-c(1:length(y))
      m2<-cbind(NA,rbind(NA,y,NA),NA)
      addresses <- expand.grid(x = 1:nrow(y), y = 1:ncol(y))
      ret<-c()
      for(i in 1:-1)
        for(j in 1:-1)
          if(i!=0 || j !=0)
            ret<-rbind(ret,m2[addresses$x+i+1+nrow(m2)*(addresses$y+j)])
      y2<-cbind(y[,ncol(y)],y)
      y2<-cbind(y2,y[,1])
      m3<-cbind(NA,rbind(NA,y2,NA),NA)
      addresses2 <- expand.grid(x = 1:nrow(y2), y = 1:ncol(y2))
      ret2<-c()
      for(i in 1:-1)
        for(j in 1:-1)
          if(i!=0 || j !=0)
            ret2<-rbind(ret2,m3[addresses2$x+i+1+nrow(m3)*(addresses2$y+j)])
      ret2[,-c(1:nrow(y2),(1+(ncol(y2)-1)*nrow(y2)):(ncol(y2)*nrow(y2)))]->ret3
      return(ret3)
    }
    ret3<-ret3_f(mt_l,mt_c)
    ############
    ####initialise
    array("S",dim=c(mt_l,mt_c))->iter
    CA_D4Tn_true<-CA_D4n_true<-CA_survival_true<-array(c(0,0),dim=c(length(iter),2))
    ###########################loop iterate the remaining proportions
    for(i in 1:n_iter){
      ##run intracellular dynamic
      mapply(function(j){return(mapply(function(i){return(state_evolve(iter[i,j]))},1:mt_l))},1:mt_c)->iter
      ###run interaction update
      c(which(iter=="I"),which(iter=="R"))->temp
      if(length(temp)>0){
        for(k in 1:length(temp)){
          iter[as.vector(na.omit(ret3[,temp[k]]))]->tt
          mapply(function(i)return(diffusion_function(tt[i])),1:length(tt))->iter[as.vector(na.omit(ret3[,temp[k]]))]
        }
      }
      ######output survival data
      which(CA_survival_true[,1]==1)->u
      which(iter=="D")->v
      if(length(u>0)){match(u,v)->w;v[-w]->v}
      CA_survival_true[v,2]<-i
      CA_survival_true[v,1]<-1
      #######
      which(CA_D4n_true[,1]==1)->u
      which(iter!="S")->v
      if(length(u>0)){match(u,v)->w;v[-na.omit(w)]->v}
      CA_D4n_true[v,2]<-i
      CA_D4n_true[v,1]<-1
      # #######
      which(CA_D4Tn_true[,1]==1)->u
      which(iter!="S" & iter!="E")->v
      if(length(u>0)){match(u,v)->w;v[-na.omit(w)]->v}
      CA_D4Tn_true[v,2]<-i
      CA_D4Tn_true[v,1]<-1
    }
    ####now consider the perturbed params
    ############
    ############
    vD<-input$vD
    d0<-input$d0
    vT<-input$vT
    TD<-input$TD
    death_rate<-input$death_rate
    diffusion<-input$diffusion
    mt_l<-input$mt_l
    mt_c<-input$mt_c
    ############
    state_evolve<-function(state){
      if(state=="S"){
        if(rexp(1,vD)<1){state<-"E"}
        else{state="S"}
      }
      else
        if(state=="E"){
          if(rexp(1,TD*vT+d0)<1){
            if(rexp(1,TD*vT)<rexp(1,d0)){state="I"}else{state="S"}
          }
          else{state="E"}
        }
      else
        if(state=="I"){
          if(rexp(1,death_rate+d0)<1){
            if(rexp(1,death_rate)<rexp(1,d0)){state="D"}else{state="R"}
          }
          else{state="I"}
        }
      else
        if(state=="R"){
          if(rexp(1,death_rate+vD)<1){
            if(rexp(1,death_rate)<rexp(1,vD)){state="D"}else{state="E"}
          }
          else{state="R"}
        }
      return(state)
    }
    #############Diffusion interaction model on neighbours
    diffusion_function<-function(state){
      if(state=="S"){
        if(rexp(1,diffusion)<1){state<-"R"}
        else{state="S"}
      }
      if(state=="E"){
        if(rexp(1,diffusion)<1){state<-"I"}
        else{state="E"}
      }
      return(state)
    }
    ret3_f<-function(mt_l,mt_c){
      mat.or.vec(mt_l,mt_c)->y
      y[1:length(y)]<-c(1:length(y))
      m2<-cbind(NA,rbind(NA,y,NA),NA)
      addresses <- expand.grid(x = 1:nrow(y), y = 1:ncol(y))
      ret<-c()
      for(i in 1:-1)
        for(j in 1:-1)
          if(i!=0 || j !=0)
            ret<-rbind(ret,m2[addresses$x+i+1+nrow(m2)*(addresses$y+j)])
      y2<-cbind(y[,ncol(y)],y)
      y2<-cbind(y2,y[,1])
      m3<-cbind(NA,rbind(NA,y2,NA),NA)
      addresses2 <- expand.grid(x = 1:nrow(y2), y = 1:ncol(y2))
      ret2<-c()
      for(i in 1:-1)
        for(j in 1:-1)
          if(i!=0 || j !=0)
            ret2<-rbind(ret2,m3[addresses2$x+i+1+nrow(m3)*(addresses2$y+j)])
      ret2[,-c(1:nrow(y2),(1+(ncol(y2)-1)*nrow(y2)):(ncol(y2)*nrow(y2)))]->ret3
      return(ret3)
    }
    ret3<-ret3_f(mt_l,mt_c)
    ############
    ####initialise
    array("S",dim=c(mt_l,mt_c))->iter
    ############
    ######define matrices to keep track of the fate of cells
    CA_D4Tn_p<-CA_D4n_p<-CA_survival_p<-array(c(0,0),dim=c(length(iter),2))
    ###########################loop iterate the remaining proportions
    for(i in 1:n_iter){
      ##run intracellular dynamic
      mapply(function(j){return(mapply(function(i){return(state_evolve(iter[i,j]))},1:mt_l))},1:mt_c)->iter
      ###run interaction update
      c(which(iter=="I"),which(iter=="R"))->temp
      if(length(temp)>0){
        for(k in 1:length(temp)){
          iter[as.vector(na.omit(ret3[,temp[k]]))]->tt
          mapply(function(i)return(diffusion_function(tt[i])),1:length(tt))->iter[as.vector(na.omit(ret3[,temp[k]]))]
        }
      }
      ######plot automata
      which(CA_survival_p[,1]==1)->u
      which(iter=="D")->v
      if(length(u>0)){match(u,v)->w;v[-w]->v}
      CA_survival_p[v,2]<-i
      CA_survival_p[v,1]<-1
      #################
      which(CA_D4n_p[,1]==1)->u
      which(iter!="S")->v
      if(length(u>0)){match(u,v)->w;v[-na.omit(w)]->v}
      CA_D4n_p[v,2]<-i
      CA_D4n_p[v,1]<-1
      # #######
      which(CA_D4Tn_p[,1]==1)->u
      which(iter!="S" & iter!="E")->v
      if(length(u>0)){match(u,v)->w;v[-na.omit(w)]->v}
      CA_D4Tn_p[v,2]<-i
      CA_D4Tn_p[v,1]<-1
    }
    library('survival')
    library("survminer")
    ####################
    ####################
    #######
    c(rep("1",nrow(CA_survival_true)),rep("0",nrow(CA_survival_p)))->l
    rbind(CA_survival_true,CA_survival_p)->events
    data.frame(events)->events
    names(events)<-c("event","time")
    events$model<-l
    events->rvs$events_a
    ###############
    c(rep("1",nrow(CA_survival_true)),rep("0",nrow(CA_survival_p)))->l
    rbind(CA_D4n_true,CA_D4n_p)->events
    data.frame(events)->events
    names(events)<-c("event","time")
    events$model<-l
    events->rvs$events_D4n
    # ###################
    c(rep("1",nrow(CA_survival_true)),rep("0",nrow(CA_survival_p)))->l
    rbind(CA_D4Tn_true,CA_D4Tn_p)->events
    data.frame(events)->events
    names(events)<-c("event","time")
    events$model<-l
    events->rvs$events_D4Tn
  })
  
  observe({
    if(input$go>0){
      rvs$reset<<-1
    }
  })
  ###############
  output$plot4<-renderPlot({
    if(rvs$reset==0){
      return(NULL)
    }
    rvs$events_a->events
    survfit(Surv(time,event)~model,data=events)->fit
    #hist(events$time)
    ggsurvplot(fit,data=events,
               conf.int = TRUE,          # Add confidence interval
               pval = TRUE,              # Add p-value
               legend.labs =
                 c("Test Parameters", "True Parameters"),
               title="Proportion of Cells Alive Cell Automaton model")
  })
}
back to top