diff --git a/Figure_1.r b/Figure_1.r index 268d9df..aeb4a54 100644 --- a/Figure_1.r +++ b/Figure_1.r @@ -54,7 +54,7 @@ precip[is.na(gcc_loc)] = NA fcover = read.table("./output/modelrun_01_fCover.txt") # limit model output to the range of the Gcc data # don't include spin-up -fcover[is.na(gcc_loc)] = NA +fcover[is.na(gcc_loc)] = NA # scaling factor to be calculated from MAP and the # optimized slope parameter @@ -62,7 +62,7 @@ MAP = read.table("./output/MAP.txt") scaling_factor = (1 * MAP[1,]) / (MAP[1,] + slope) # padding to accomodate he inset scatter plot -offset = 2095 +offset = 2095 leg = c('a','b','c','d','e','f') phenocam_site_letter = c('g','c','j','m','f','d') @@ -77,24 +77,24 @@ k=0 for (i in site_order){ k=k+1 - + # read data from original input file input_data = read.table(sites_data[i],skip=12) - + # get modis data if available lat_long = scan(sites_data[i],what=character(),nmax=9) lat = as.numeric(lat_long[6]) long = as.numeric(lat_long[9]) - + # construct dates string input_dates = as.Date(paste(input_data[,1],input_data[,2],sep="-"),format="%Y-%j") - + # calculate spinput length spinup_length = input_dates[min(which(!is.na(gcc[,i]) == TRUE),na.rm=TRUE)] - + # length of the time series ts_length = length(input_dates) - + # plot container plot(input_dates,gcc[1:ts_length,i], bty='n', @@ -105,15 +105,15 @@ for (i in site_order){ ylim=c(0,1.3), xlim=c(as.numeric(input_dates[ts_length-offset]),as.numeric(input_dates[ts_length])) ) - + # format dates axis locs <- tapply(X=input_dates, FUN=min, INDEX=format(input_dates, '%Y%m')) at = input_dates %in% locs - at = at & format(input_dates, '%m') %in% c('01', '07') - + at = at & format(input_dates, '%m') %in% c('01', '07') + # call a new plot par(new=TRUE) - + # plot the precipitation plot(input_dates,precip[1:ts_length,i], bty='n', @@ -127,10 +127,10 @@ for (i in site_order){ ylim=c(0,150) ) axis(4,cex.axis=1.2,tck=0.03,las=2,col='deepskyblue',col.axis='deepskyblue',at=c(0,70,140),lwd=1.5) - + # call a new plot to plot GCC/fcover par(new=TRUE) - + # plot gcc plot(input_dates,gcc[1:ts_length,i] * scaling_factor[1,i], bty='n', @@ -145,7 +145,7 @@ for (i in site_order){ cex.lab=1.5, xlim=c(as.numeric(input_dates[ts_length-offset]),as.numeric(input_dates[ts_length])) ) - + # add fcover lines(input_dates,gcc[1:ts_length,i] * scaling_factor[1,i], bty='n', @@ -157,7 +157,7 @@ for (i in site_order){ lwd=2.3, cex.lab=1.3, xlim=c(as.numeric(input_dates[ts_length-offset]),as.numeric(input_dates[ts_length]))) - + # add fcover lines(input_dates,fcover[1:ts_length,i], ylim=c(0,1), @@ -165,9 +165,9 @@ for (i in site_order){ cex=0.2, lwd=2.3, col='red') - + legend('topright',legend=leg[k],bty='n',cex=2.5) - + # find location based upon name loc = which(metadata$site == sites[i]) @@ -176,18 +176,18 @@ for (i in site_order){ bty='n', cex=1.5, bg='white') - + # add nice axis if(i == 6){ axis(side=1, at=seq(as.Date("2010/1/1"), as.Date("2015/1/1"), by = "year"),labels=F,tck=0.03,cex.axis=1.2,lwd=1.5) axis(side=1, at=seq(as.Date("2010/6/30"), as.Date("2015/6/30"), by = "year"),labels=2010:2015,tck=F,cex.axis=1.2,lwd=1.5) } else { axis(side=1, at=seq(as.Date("2010/1/1"), as.Date("2015/1/1"), by = "year"),labels=F,tck=0.03,cex=1.5,lwd=1.5) - } + } - axis(2,at=c(0,0.5,1),cex.axis=1.2,tck=0.03,las=2,lwd=1.5) + axis(2,at=c(0,0.5,1),cex.axis=1.2,tck=0.03,las=2,lwd=1.5) mtext("Precip. (mm)",4,3,cex=1,col='deepskyblue') - + } # legend @@ -204,7 +204,7 @@ bottom= rev(bottom[2:7]) for (j in site_order){ df = na.omit(cbind(gcc[,j] * scaling_factor[1,j],fcover[,j])) - + k = k + 1 par(fig=c(0.1,0.40,bottom[k],top[k]), new = TRUE) plot(df, @@ -218,14 +218,14 @@ for (j in site_order){ xlim=c(0,0.95), ylim=c(0,0.95) ) - + R = cor(df)[1,2] - + rect(0,0,0.8,0.8,col = "white",border=0) points(df, pch=20, col='grey50') - + # labels lines(c(0,0.8),c(0,0.8),lty=2) legend(-0.15,0.9,legend=paste("R = ",round(R,2),sep=''),bty='n',cex=1.3) @@ -233,6 +233,6 @@ for (j in site_order){ axis(2,at=c(0,0.4,0.8),tck=0.03,labels=c(0,'',0.8),cex.axis=1.3,lwd=1.5) mtext('Observed',1,2,cex=0.9) mtext('Predicted',2,2,cex=0.9) - + } dev.off() diff --git a/Figure_4.r b/Figure_4.r new file mode 100644 index 0000000..c236edd --- /dev/null +++ b/Figure_4.r @@ -0,0 +1,127 @@ +require(zoo) +graphics.off() + +error.bar <- function(x, y, upper, lower=upper, length=0.05,...){ + if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper)) + stop("vectors must be same length") + arrows(x,y+upper, x, y, angle=90, code=3, length=length, ...) +} + +# compile code +system('gfortran -ffree-form -ffree-line-length-200 -g func.f90 inc.f90 phenograss.f90 sann.f90 main.f90 -o phenograss', wait = T) + +# run the code for the konza site, using site specific meteorological drivers +system('./a.out ./parameters/konza.txt r',wait = T) + +# local weather +drivers = read.table("data/drivers/konza_grass.csv") +drivers_year = drivers[,1] +precip = drivers[,7] + +# read konza yearly productivity measurements +df_bio = read.table('data/ancillary/konza_total_annual_biomass.csv',sep=',',header=T) +df_bio[is.na(df_bio)] = 0 + +# use florence soil: The Florence series consists of deep, well drained, moderately slowly permeable soils on uplands. +df_bio = df_bio[c(df_bio$SOILTYPE=="fl"),] + +# extract the dates on which the measurements are made as well as the DOY and the year +dates_bio = as.Date(paste(df_bio$RECYEAR,df_bio$RECMONTH,df_bio$RECDAY,sep='-'),"%Y-%m-%d") +doy = as.numeric(format(dates_bio,"%j")) +year = as.numeric(format(dates_bio,"%Y")) + +# make the variables human readable +grass = as.numeric(as.matrix(df_bio$LVGRASS)) +forbs = as.numeric(as.matrix(df_bio$FORBS)) +death_cur = as.numeric(as.matrix(df_bio$CUYRDEAD)) +woody = as.numeric(as.matrix(df_bio$WOODY)) + +death_prev = as.numeric(as.matrix(df_bio$PRYRDEAD)) +death_prev = as.numeric(c(death_prev[-1],NA)) + +# we will consider all biomass of perennial nature (death from this season or alive) +biomass = grass + forbs + death_cur +biomass = biomass * 10 # values are in g / 0.1 m2 + +# read in the modelled results +model= unlist(read.table('output/modelrun_01_fCover.txt')) + +# read in the input data to extract the dates vector +dates =as.Date(paste(drivers[,1],drivers[,2],sep='-'),"%Y-%j") + +bio_year = format(dates_bio,"%Y") +year = as.numeric(format(dates[order(dates)],"%Y")) +doy_drivers = as.numeric(format(dates[order(dates)],"%j")) +year_drivers = as.numeric(format(dates[order(dates)],"%Y")) +bio_doy = as.numeric( format(dates_bio,"%j")) + +growth = model +growth_increase = c(diff(growth),NA) +growth_increase[which(growth_increase < 0) ] = NA + +annual_model = by(growth,INDICES = list(year),function(x,...)sum(x[1:260],na.rm=T)) + +sums = by(biomass,INDICES=list(bio_year),FUN=mean,na.rm=T) +sds = by(biomass,INDICES=list(bio_year),FUN=sd,na.rm=T) + +model_names = names(annual_model) +bio_names = names(sums) + +pdf("output/Figure4.pdf",21,10) +par(mfrow=c(1,2),mar=c(5,5,3,1),tck=0.03,lwd=2.5,cex=2.5) +dd = cbind(sums,sds,annual_model[which(model_names %in% bio_names)]) + +plot(dd[,3],dd[,1], + xlab='Annual intergral of fCover', + col='olivedrab4', + ylab=expression("Biomass (g m" ^-2 *" yr" ^-1*")"), + pch=19, + bty='n', + xlim=c(60,120), + ylim=c(125,700), + yaxt='n', + xaxt='n', + xaxs='i', + yaxs='i') +axis(2,at=c(125,250,500),tck=0.03,lwd=2) +axis(1,tck=0.03,lwd=2) + +# omit first 10 years as spinup +fit = lm(dd[,1]~dd[,3]) +print(cor(dd[,3],dd[,1])) +print(summary(fit)) +abline(fit,lty=2,col='grey') +coef = round(fit$coefficients,2) + +text(65,550,expression("R" ^2 * "= 0.54; p < 0.001"),pos=4) +text(65,490,paste("y = ",coef[1]," + ",coef[2],"x",sep=""),pos=4) +legend('topright',legend="a",bty='n',cex=2) + +## +par(mar=c(5,1,3,5)) +p <- barplot(t(dd[,1]),ylim=c(125,700),xpd=FALSE,col='wheat', + xlab="Year", + ylab="", + border=NA, + yaxt='n') +axis(2,at=c(125,250,500),tck=0.03,labels=FALSE,lwd=2) +#mtext(expression("Biomass (g m" ^-2 *" yr" ^-1*")"),2,3,adj=0.2) + +error.bar(p,dd[,1],dd[,2],col='wheat3') + +par(new=TRUE) +lines(p,-28.97+dd[,3]*4.25,type='b', + xaxt='n', + yaxt='n', + col='olivedrab4', + lwd=3, + xlab='', + ylab='', + lty=2, + cex=0.8, + pch=19) +axis(4,at=c(125,250,500),labels=round(c(125,250,500)/4.25),tck=0.03,lwd=2) +mtext("Annual integral of fCover",4,3,cex=2.5) +legend('topright',legend="b",bty='n',cex=2) + +graphics.off()