## ## Timing the spinal cord development with neural progenitor cells losing their proliferative capacity: a theoretical analysis. ## Manon Azais, Eric Agius, Stephane Blanco, Angie Molina, Fabienne Pituello, Jean-Marc Tregan, Anaïs Vallet and Jacques Gautrais1* ## Neural Development 2019 ## ## All data and codes are contained in this file. ## The code was executed using Terminal under MacOSX 10.11.6, R version 3.5.2 (2018-12-20) -- "Eggshell Igloo", with: ## [Code]$ R CMD BATCH --vanilla DataAndCode.R ## and produces all figures. ## rm(list=ls()) #### where to put figures RepOut="./" whatToDo = c("fig1","fig25","clones") ## ####################### data Saade ######################### Saade = list( MOD = data.frame( time = c(60,70,75,80,90), pp = c(82 ,37 ,7 ,0 ,0), pn = c(18 ,56 ,53 ,56 ,42), nn = c(0 ,7 ,40 ,44 ,58), IcPP = c(4,9,6,0,0)*1.96, IcPN = c(4,6,7,3,6)*1.96, IcNN = c(0,4,5,3,6)*1.96), PNWT = data.frame( time = c(50,60,72,84,96,108,120,132), P = c(12,27,75.4,70.8,39.8,20.5,11.7,9.4), N = c(0.0,0.0,31,87.7,156.2,190.6,212.3,215.2), PIC = c(3.5,6.4,11.1,8.8,10.5,7.0,4.1,3.5)*1.96, NIC = c(0.0,0.0,8.8,12.9,19.8,21.6,12.3,18.7)*1.96) ); ## Pituello Data (Ventral zone) Pituello24h = 60; Pituello48h = Pituello24h+24; PituelloMoD = (Pituello24h+Pituello48h)/2; Pituello = list( MODWT = data.frame( time = rep(PituelloMoD,3), MoD = c(29.3,58,12.7), IC = c(1.3,2,1.1)*1.96), PNWT = data.frame( time = c(Pituello24h,Pituello48h), P = c(83.5,38.4), N = c(16.5,61.6), PIC = c(1.1,1.5)*1.96, NIC = c(1.1,1.5)*1.96), MODGOF = data.frame( time = rep(PituelloMoD,3), MoD = c(6.9,52.3,40.7), IC = c(2.5,2.8,2.7)*1.96), PNGOF = data.frame( time = c(Pituello24h,Pituello48h), P = c(83.6,23.5), N = c(16.4,76.5), PIC = c(1.1,0.9)*1.96, NIC = c(1.1,0.9)*1.96), MODCDK = data.frame( time = rep(PituelloMoD,3), MoD = c(16.6,70.7,12.7), IC = c(1.2,1.4,1.1)*1.96), PNCDK = data.frame( time = c(Pituello24h,Pituello48h), P = c(92,34.1), N = c(8,65.9), PIC = c(1.1,2.5)*1.96, NIC = c(1.1,2.5)*1.96) ); ## ################## accessory functions ## open graphics windows ## should be adapted for execution under RStudio / Linux openGraphics = function(inwidth, inheight) { quartz(w=inwidth,h=inheight); } plotCI = function (x, y, uiw,col=par("col"), pch=1,cex=1,type='b',cex.lab=1,wdth=1, lwd=par("lwd"),add=TRUE) { ui = y + uiw; li = y - uiw; li = pmax(li,0); ## gap =1 ; smidge = par("fin")[1] * 0.01 ## arrows(x , li, x, pmax(y-gap,li), col=col, lwd=lwd, angle=90, length=smidge, code=1) ## arrows(x , ui, x, pmin(y+gap,ui), col=col, lwd=lwd, angle=90, length=smidge, code=1) if (length(col)==1) col = rep(col,length(x)) points(x, y, col = col, cex=cex, pch=pch) for (p in 1:length(x)) { lines(c(x[p],x[p]),c(li[p],ui[p]),col=col[p],lwd=lwd) lines(c(x[p]-wdth,x[p]+wdth),c(li[p],li[p]),col=col[p],lwd=lwd) lines(c(x[p]-wdth,x[p]+wdth),c(ui[p],ui[p]),col=col[p],lwd=lwd) } invisible(list(x = x, y = y)) } ################################################################################ ############################# ############################# ################################################################################ ### PN model, Figures 1-5 maxpp = 1;maxnn = 0.8; alphapp = function(t,tau) { return( (1 - tanh( (t-tau)/sigmapp) )*(maxpp/2)) } alphann = function(t,tau) { return( (1 + tanh( (t-tau)/sigmann) )*(maxnn/2) ) } alphapn = function(t,taupp,taunn) { return(1-alphann(t,taunn)-alphapp(t,taupp)) } ## MoDs WT ## fit tanh parameters from Saade data alphapptst = function(t,te,sigma) { return( 0.5 - tanh( (t-te)/sigma)*(maxpp/2)) } squareErrorPP = function(parms) { return(sum( (Saade$MOD$pp/100 - alphapptst(Saade$MOD$time,parms[1],parms[2]) )**2 )) } paramspp = optim(par=c(67,7), squareErrorPP, method="L-BFGS-B", lower=0) WTTauPP = paramspp$par[1] ; sigmapp = paramspp$par[2] ; cat("Params PP : ",WTTauPP," ",sigmapp,"\n"); alphanntst = function(t,te,sigma) { return( (1+tanh( (t-te)/sigma ) )*(maxnn/2) ) } squareErrorNN = function(parms) { return(sum( (Saade$MOD$nn/100 - alphanntst(Saade$MOD$time,parms[1],parms[2]) )**2 )) } paramsnn = optim(par=c(77,17), squareErrorNN, method="L-BFGS-B", lower=0) WTTauNN = paramsnn$par[1] ; sigmann = paramsnn$par[2] ; cat("Params NN : ",WTTauNN," ",sigmann,"\n"); squareErrorPP = sum((Saade$MOD$pp/100 - alphapp(Saade$MOD$time,WTTauPP) )**2); cat("sq error PP = ",squareErrorPP,"\n"); squareErrorNN = sum((Saade$MOD$nn/100 - alphann(Saade$MOD$time,WTTauNN) )**2); cat("sq error NN = ",squareErrorNN,"\n"); squareErrorPN = sum((Saade$MOD$pn/100 - alphapn(Saade$MOD$time,WTTauPP,WTTauNN) )**2); cat("sq error PN = ",squareErrorPN,"\n"); cat("======\n"); ## time parameters dt = 0.01; startAtOne = 44; eta=1/12; cat("Tc=",1/eta,", start = ",startAtOne,", maxnn=",maxnn,"\n"); ## Parameters GOFTauPP = WTTauPP -8 GOFTauNN = WTTauNN -8 CDKTauPP = WTTauPP -2 CDKTauNN = WTTauNN +4 LOFTauPP = WTTauPP +2.5 ; LOFTauNN = WTTauNN +7 ; ## compute time series PNTimeSeries = function(tauPP,tauNN) { temps = seq(startAtOne,140,dt); nit = length(temps) ## Variables gamma = rep(0,nit); P = rep(0,nit) ; N = rep(0,nit) ; P[1] = 1 ; N[1] = 0 ; gamma[1]=alphapp(temps[1],tauPP) - alphann(temps[1],tauNN) for(t in 2:nit) { gamma[t] = alphapp(temps[t-1],tauPP) - alphann(temps[t-1],tauNN); P[t] = P[t-1] + eta*dt*P[t-1]* gamma[t]; N[t] = N[t-1] + eta*dt*P[t-1]* (1.0-gamma[t]); } keeptmps = seq(1,length(temps),100) return (list(P=P[keeptmps],N=N[keeptmps],Gamma=gamma[keeptmps], Time=temps[keeptmps], PP=alphapp(temps,tauPP)[keeptmps], NN=alphann(temps,tauNN)[keeptmps])) } P.Analityque = function(t,start,taupp,taunn) { t0 = taupp - start ; t1 = taunn - start ; ts = t - start p1 = (cosh( (ts-t0)/sigmapp ) / cosh(-t0/sigmapp))^(sigmapp/2) * (cosh( (ts-t1)/sigmann ) / cosh(-t1/sigmann) )^((maxnn/2)*sigmann) p2 = (((1/2) - (maxnn/2) ) * ts) - log(p1) return(exp(eta * p2)) } gamma.analytique = function(t,taupp,taunn) { return( alphapp(t,taupp) - alphann(t,taunn) ) } if("fig1" %in% whatToDo) { WTdata = PNTimeSeries(WTTauPP,WTTauNN); GOFdata = PNTimeSeries(GOFTauPP,GOFTauNN); CDKdata = PNTimeSeries(CDKTauPP,CDKTauNN); cat("WT\n"); cat("Max progens: ",max(WTdata$P),"\n"); cat(" at time: ",WTdata$Time[which(abs(WTdata$P-max(WTdata$P))<0.0000001)][1],"\n"); cat("GoF\n"); cat("Max progens: ",max(GOFdata$P),"\n"); cat(" at time: ",GOFdata$Time[which(abs(GOFdata$P-max(GOFdata$P))<0.0000001)][1],"\n"); ## #### Figure 1 ##### openGraphics(inwidth=8,inheight=10); par(las=1, family="Helvetica", mar=c(5,5,4,1), mfrow=c(3,2), tcl=0.4); ## MOD fits plot(NA,type="n",xlab="",ylab="Mode of division",ylim=c(0,1),xlim=c(40,140),cex.lab=1.3) plotCI(Saade$MOD$time,Saade$MOD$pp/100,uiw=Saade$MOD$IcPP/100,type='b',pch=15,col='black',wdth=2) plotCI(Saade$MOD$time,Saade$MOD$pn/100,uiw=Saade$MOD$IcPN/100,type='b',pch=15,col='blue',wdth=2) plotCI(Saade$MOD$time,Saade$MOD$nn/100,uiw=Saade$MOD$IcNN/100,type='b',pch=15,col='red',wdth=2) plotCI(Pituello$MODWT$time,Pituello$MODWT$MoD/100,uiw=Pituello$MODWT$IC/100,col=c('black','blue','red'),pch=16,add=TRUE,cex=2,wdth=2) curve(alphapp(x,WTTauPP),40,140, ylim=c(0,1), col="black",add=TRUE,lwd=2); curve(alphann(x,WTTauNN),40,140,add=TRUE,col='red',lwd=2); curve(alphapn(x,WTTauPP,WTTauNN),40,140,add=TRUE,col='blue',lwd=2) legend(x=100,y=0.6,legend=c(expression(alpha[pp](t)),expression(alpha[pn](t)),expression(alpha[nn](t))),col=c("black","blue","red"),lwd=c(2,2,2),cex=1) text(30,1.2,"a - CTL",cex=2,xpd=NA, adj=0) ## Progenitors / neurons with Saade data plot(WTdata$Time,WTdata$P,type='l',ylim = c(0,250/12),xlim=c(40,140),xlab="",ylab="Number of cells",cex.lab=1.3,col='black',lwd=3) lines(WTdata$Time,WTdata$N,col='red',lwd=3) plotCI(Saade$PN$time,Saade$PN$P/12,uiw=Saade$PN$PIC/12,pch=15,col="black",add=TRUE); plotCI(Saade$PN$time,Saade$PN$N/12,uiw=Saade$PN$NIC/12,pch=15,col="red",add=TRUE); curve(P.Analityque(x,startAtOne,WTTauPP,WTTauNN),40,140,add=TRUE,col="green") legend(x=40,y=20,legend=c(expression(P(t)),expression(N(t))),col=c("black","red"),lwd=c(2,2),cex=1) indices = rep(NA,2); for (ind in 1:2) indices[ind] = which(abs(WTdata$Time-Pituello$PNWT$time[ind]) N,N only, i.e. with probability 1 anntst = function(t,te,sigma,maxann) { return( rep(1, length(t)) ) } timeSeries = function(from,to,dt,G0,tauPP, tauNN) { time = seq(from,to,dt); alphapps = alphapp(time,tauPP); alphanns = alphann(time,tauNN); Ps = P.Analityque(time,0,tauPP, tauNN); ## ggg and gan / numerical as the others paramsggg = optim(par=c(tauPP,sigmapp), fn=squareErrorggg, gr = NULL,time,alphapps,Ps, method="Nelder-Mead") cat("ggg : ",paramsggg$par[1],", ",paramsggg$par[2],"\n"); cat(" pp = ",tauPP,",",sigmapp,"\n"); ggg = gggtst(time,paramsggg$par[1],paramsggg$par[2]); ## ggg and gan / analytical from P, alphapp, eta numerator = alphapps * Ps * exp(eta*time); intdenom = head(c(0,cumsum(numerator*dt)),-1); ggganalytic = (numerator /(G0 + 2*eta*intdenom) ) gan = 1-ggganalytic; ## G(t) Gs = G0 * exp( head(c(0,cumsum((2*ggg - 1)*eta*dt)),-1) ); Gs2 = rep(NA,length(time)); Gs2[1]=1; for (i in 2:length(time)) Gs2[i]=Gs2[i-1] + (2*ggg[i-1] -1)*eta*Gs2[i-1]*dt ## ann, aan ann = anntst(time,paramsann$par[1],paramsann$par[2],maxann); aan = 1-ann ## A(t), N(t) As2 = rep(NA,length(time));Ns2 = rep(NA,length(time)); As2[1]=0; for (i in 2:length(time)) As2[i]=As2[i-1] + (gan[i-1]*Gs2[i-1] + (aan[i-1]-1)*As2[i-1])*eta*dt Ns2[1]=0; for (i in 2:length(time)) Ns2[i]=Ns2[i-1] + (gan[i-1]*Gs2[i-1] + (2*ann[i-1] + aan[i-1])*As2[i-1])*eta*dt NfromG = cumsum(gan*Gs2*eta*dt); NfromA = cumsum((2*ann + aan)*As2*eta*dt); return(list(Time=time, pp=alphapps,nn=alphanns,ggg=ggg,asym=gan,aan=aan,ann=ann,ggganalytic=ggganalytic, P=Ps,G=Gs, G2=Gs2,A2=As2,N=Ns2, Nfrom1 = NfromG, Nfrom2 = NfromA,taug=paramsggg$par[1],sigmag=paramsggg$par[2])) } ## compute them WTGANa = timeSeries(t0,tf,dt,G0,WTTauPP - startAtOne, WTTauNN - startAtOne) GOFGANa = timeSeries(t0,tf,dt,G0,GOFTauPP - startAtOne, GOFTauNN - startAtOne) CDKGANa = timeSeries(t0,tf,dt,G0,CDKTauPP - startAtOne, CDKTauNN - startAtOne) openGraphics(inwidth=10,inheight=10); par(las=1, family="Helvetica", mar=c(5,5,4,1), mfrow=c(3,3), tcl=0.4); colNfrom1 = "green"; colNfrom2 = "blue"; ## graphicScenario(WTGANa,GOFGANa,CDKGANa,WTPN,GOFPN,CDKPN, name=paste(RepOut,"FigureS2.pdf",sep=''),showNdetails=FALSE); WT = WTGANa; GOF = GOFGANa; CDK = CDKGANa; keeptps = seq(1,length(WT$Time),100); # to make graphics lighter ## WT MoD plot(WT$Time[keeptps]+startAtOne,1-WT$ggg[keeptps], type='l',ylim=c(0,1),xlim=c(40,140), xlab="",ylab='Mode of Division',lwd=3,cex.lab=1.3,col="green") lines(WT$Time[keeptps]+startAtOne,1-WT$aan[keeptps], lwd=3, col='blue'); legend(x=100,y=0.6,legend=c(expression(gamma[G](t)),expression(gamma[A](t))),col=c("green","blue"),lwd=c(2,2),cex=1) text(-15+startAtOne,1.2,"a - CTL",cex=2,xpd=NA, adj=0) ## WT Pops plot(WT$Time[keeptps]+startAtOne,WT$G2[keeptps],type='l',xlab="",ylab="Number of cells",ylim = c(0,250/12),xlim=c(40,140),col='green',lwd=3,cex.lab=1.3); lines(WT$Time[keeptps]+startAtOne,WT$A2[keeptps],col='blue',type='l',lwd=3) lines(WT$Time[keeptps]+startAtOne,WT$N[keeptps],col='red',type='l',lwd=3) lines(WT$Time[keeptps]+startAtOne,WT$G2[keeptps]+WT$A2[keeptps],lwd=3, col="black") legend(x=40,y=20,legend=c(expression(G(t)),expression(A(t)),expression(N(t)),expression(P(t))),col=c("green","blue","red","black"),lwd=c(2,2,2,2),cex=1) plotCI(Saade$PN$time,Saade$PN$P/12,uiw=Saade$PN$PIC/12,pch=15,cex=0.8,col="black",add=TRUE); plotCI(Saade$PN$time,Saade$PN$N/12,uiw=Saade$PN$NIC/12,pch=15,cex=0.8,col="red",add=TRUE); indices = rep(NA,2); for (ind in 1:2) indices[ind] = which(abs(WTPN$Time-Pituello$PNWT$time[ind])0) { for (g in 1:pop[1]) { if (runif(n=1) 0) { for (a in 1:pop[2]) { if (runif(n=1)0) { for (g in 1:pop[1]) { ru = runif(n=1) if (ru