## ## 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])