1 |
f2b2e7d5
|
Adam M. Wilson
|
#! /bin/r
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
#system("ssh -X turaco")
|
5 |
|
|
#export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}/home/adamw/local/lib
|
6 |
|
|
#export KMP_DUPLICATE_LIB_OK=TRUE
|
7 |
|
|
#R
|
8 |
|
|
### Download and clean up GHCN data for CFR
|
9 |
|
|
#install.packages("ncdf4",lib="/home/adamw/rlib",configure.args="--with-nc-config=/home/adamw/local/bin/nc-config")
|
10 |
|
|
|
11 |
|
|
library(sp);library(rgdal);
|
12 |
|
|
library(reshape)
|
13 |
|
|
library(ncdf4)
|
14 |
|
|
library(geosphere)
|
15 |
|
|
library(rgeos)
|
16 |
|
|
library(multicore);library(RSQLite)
|
17 |
|
|
library(spBayes)
|
18 |
|
|
library(geoR) #for conventional kriging
|
19 |
|
|
library(raster)
|
20 |
|
|
## for review/analysis
|
21 |
|
|
library(coda)
|
22 |
|
|
library(lattice)
|
23 |
|
|
library(MBA)
|
24 |
|
|
|
25 |
|
|
### Load functions
|
26 |
|
|
#source("code/interpolationfunc.r")
|
27 |
|
|
|
28 |
|
|
X11.options(type="Xlib")
|
29 |
|
|
ncores=20 #number of threads to use
|
30 |
|
|
|
31 |
|
|
setwd("/home/adamw/acrobates/projects/interp")
|
32 |
|
|
|
33 |
|
|
### read in full dataset
|
34 |
|
|
load("data/ghcn/roi_ghcn.Rdata")
|
35 |
|
|
load("stroi.Rdata")
|
36 |
|
|
source("code/GHCN_functions.r")
|
37 |
|
|
|
38 |
|
|
## rescale units to C and mm
|
39 |
|
|
d$value=d$value/10.0
|
40 |
|
|
|
41 |
|
|
## add flag for Benoit's training stations to identify training/validation
|
42 |
|
|
stt=readOGR("data/ghcn/tempdata/ghcn_1507_s.shp","ghcn_1507_s")$STAT_ID
|
43 |
|
|
d$fit=d$id%in%stt
|
44 |
|
|
|
45 |
|
|
### read in and subset to Benoit's dates
|
46 |
|
|
dates=as.Date(as.character(
|
47 |
|
|
read.table("data/ghcn/tempdata/dates_interpolation_03052012.txt")$V1),"%Y%m%d")
|
48 |
|
|
|
49 |
|
|
##########################################################
|
50 |
|
|
#### load region of interest
|
51 |
|
|
roi=readOGR("data/boundaries/statesp020.shp","statesp020")
|
52 |
|
|
proj4string(roi)=CRS("+proj=longlat +datum=WGS84")
|
53 |
|
|
roi=roi[roi$STATE=="Oregon",]
|
54 |
|
|
roi=gUnionCascaded(roi) #dissolve any subparts of roi
|
55 |
|
|
|
56 |
|
|
## distance from ROI to buffer for border stations
|
57 |
|
|
dis=100 #km
|
58 |
|
|
## buffer roi (transform to azimuthal equidistant with centroid of roi, add 'dis' buffer, then transform back)
|
59 |
|
|
roic=centroid(roi)
|
60 |
|
|
|
61 |
|
|
roib=spTransform(
|
62 |
|
|
gBuffer(spTransform(roi,
|
63 |
|
|
CRS(paste("+proj=aeqd +lat_0=",roic[2]," +lon_0=",
|
64 |
|
|
roic[1]," +ellps=WGS84 +datum=WGS84 +units=m +no_defs ",sep=""))),
|
65 |
|
|
width=dis*1000),
|
66 |
|
|
CRS("+proj=longlat +datum=WGS84"))
|
67 |
|
|
|
68 |
|
|
### generate knots
|
69 |
|
|
knots=makegrid(roib,cellsize=0.5)
|
70 |
|
|
coordinates(knots)=c("x1","x2")
|
71 |
|
|
proj4string(knots)=proj4string(roi)
|
72 |
|
|
knots=knots[!is.na(overlay(knots,roi))]
|
73 |
|
|
|
74 |
|
|
|
75 |
|
|
###########################################################3
|
76 |
|
|
#### interpolation function
|
77 |
|
|
|
78 |
|
|
interp<-function(parms,niter=100,istart=60,ithin=1){
|
79 |
|
|
## load variables from parameter list
|
80 |
|
|
idate=as.Date(parms$date)
|
81 |
|
|
ivar=parms$variable
|
82 |
|
|
type=parms$type
|
83 |
|
|
model=parms$model
|
84 |
|
|
|
85 |
|
|
## subset single date from data
|
86 |
|
|
td=d[d$date==idate,]
|
87 |
|
|
td=data.frame(cast(td,id+fit~variable,value="value"))
|
88 |
|
|
td$elev=stroi$elev[match(td$id,stroi$id)]
|
89 |
|
|
td[c("lon","lat")]=stroi@data[match(td$id,stroi$id),c("lon","lat")]
|
90 |
|
|
td$intercept=1
|
91 |
|
|
|
92 |
|
|
## drop any points without coordinates
|
93 |
|
|
td=td[!is.na(td$lat)&!is.na(td$lon),]
|
94 |
|
|
|
95 |
|
|
###########################
|
96 |
|
|
## apply climate correction
|
97 |
|
|
if(type=="anom"){
|
98 |
|
|
cppt=brick("data/prism/prism_climate.nc",varname="ppt")
|
99 |
|
|
cppt=subset(cppt,subset=as.numeric(format(idate,"%m")))
|
100 |
|
|
cppt[cppt==-99.99]=NA
|
101 |
|
|
td$cppt=as.numeric(extract(cppt,td[,c("lon","lat")],method="bilinear"))
|
102 |
|
|
## Tmax
|
103 |
|
|
ctmax=brick("data/prism/prism_climate.nc",varname="tmax")
|
104 |
|
|
ctmax=subset(ctmax,subset=as.numeric(format(idate,"%m")))
|
105 |
|
|
ctmax[ctmax==-99.99]=NA
|
106 |
|
|
td$ctmax=as.numeric(extract(ctmax,td[,c("lon","lat")],method="bilinear"))
|
107 |
|
|
## Tmin
|
108 |
|
|
ctmin=brick("data/prism/prism_climate.nc",varname="tmin")
|
109 |
|
|
ctmin=subset(ctmin,subset=as.numeric(format(idate,"%m")))
|
110 |
|
|
ctmin[ctmin==-99.99]=NA
|
111 |
|
|
td$ctmin=as.numeric(extract(ctmin,td[,c("lon","lat")],method="bilinear"))
|
112 |
|
|
## Calculate anomalies
|
113 |
|
|
td$atmax=td$tmax-td$ctmax
|
114 |
|
|
td$atmin=td$tmin-td$ctmin
|
115 |
|
|
## Scale for precipitation (add 1 to climate to avoid dividing by 0, will be subtracted off later)
|
116 |
|
|
## Add 1 to final value to avoid transformation troubles (geoR will only transform if >0
|
117 |
|
|
td$appt=(td$ppt/(ifelse(td$cppt<0,0,td$cppt)+1))+1
|
118 |
|
|
}
|
119 |
|
|
|
120 |
|
|
### Add region flag to data
|
121 |
|
|
td$region=ifelse(!is.na(overlay(SpatialPoints(td[,c("lon","lat")]),roi)),"roi","roib")
|
122 |
|
|
td=td[!is.na(overlay(SpatialPoints(td[,c("lon","lat")]),roib)),]
|
123 |
|
|
|
124 |
|
|
#### Extract data for validation
|
125 |
|
|
fd=td[td$fit&td$region=="roi",] #fitting dataset
|
126 |
|
|
pd=td[!td$fit&td$region=="roi",] #training dataset
|
127 |
|
|
od=td[!td$fit&td$region!="roi",] #stations outside roi
|
128 |
|
|
|
129 |
|
|
|
130 |
|
|
### drop missing values
|
131 |
|
|
fd=fd[!is.na(fd[,as.character(ivar)]),] #&!is.na(fd$tmin)
|
132 |
|
|
|
133 |
|
|
### define the formula
|
134 |
|
|
if(type=="raw"&ivar=="tmax") f1=formula(tmax~intercept)
|
135 |
|
|
if(type=="anom"&ivar=="tmax"&model=="intercept") f1=formula(atmax~intercept)
|
136 |
|
|
if(type=="anom"&ivar=="tmax"&model=="full") f1=formula(atmax~lon+lat+elev)
|
137 |
|
|
|
138 |
|
|
### Run the model
|
139 |
|
|
t1=Sys.time()
|
140 |
|
|
m1=spLM(f1,data=fd,coords=as.matrix(fd[,c("lon","lat")]),
|
141 |
|
|
starting=list("phi"=2.5,"sigma.sq"=4, "tau.sq"=1),
|
142 |
|
|
sp.tuning=list("phi"=0.8, "sigma.sq"=0.1, "tau.sq"=0.2),
|
143 |
|
|
priors=list("phi.Unif"=c(0.1, 4), "sigma.sq.IG"=c(2, 1),
|
144 |
|
|
"tau.sq.IG"=c(2, 1)),
|
145 |
|
|
cov.model="exponential",
|
146 |
|
|
knots=coordinates(knots),
|
147 |
|
|
n.samples=niter, verbose=TRUE, n.report=1000)
|
148 |
|
|
t2=Sys.time()
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
#m1s=mcmc(m1$p.samples)
|
152 |
|
|
#summary(m1s)
|
153 |
|
|
#xyplot(m1s,scales=list(y=list(rot=0)),main="Posterior Samples of Model Parameters")
|
154 |
|
|
|
155 |
|
|
### Run the model
|
156 |
|
|
#q=3
|
157 |
|
|
#nltr=q*(q-1)/2+q
|
158 |
|
|
|
159 |
|
|
#m1=spMvLM(list(atmin~1,atmax~1),data=fd,coords=as.matrix(fd[,c("lon","lat")]),
|
160 |
|
|
# starting=list("phi"=0.6,"sigma.sq"=1, "tau.sq"=1),
|
161 |
|
|
# sp.tuning=list("phi"=0.01, "sigma.sq"=0.05, "tau.sq"=0.05),
|
162 |
|
|
# priors=list("phi.Unif"=c(0.1, 3), "sigma.sq.IG"=c(2, 1),
|
163 |
|
|
# "tau.sq.IG"=c(2, 1)),
|
164 |
|
|
# cov.model="exponential",
|
165 |
|
|
# knots=coordinates(knots),
|
166 |
|
|
# n.samples=100, verbose=TRUE, n.report=100)
|
167 |
|
|
|
168 |
|
|
#save to play with later
|
169 |
|
|
#save(m1,file="m1.Rdata")
|
170 |
|
|
|
171 |
|
|
|
172 |
|
|
#load("m1.Rdata")
|
173 |
|
|
|
174 |
|
|
##############################
|
175 |
|
|
#### make predictions
|
176 |
|
|
|
177 |
|
|
### Prediction grid
|
178 |
|
|
# pgrid=data.frame(coordinates(ctmax))
|
179 |
|
|
# ## crop to bbox
|
180 |
|
|
# pgrid=pgrid[pgrid$x>=bbox(roi)[1,1]&pgrid$x<=bbox(roi)[1,2]
|
181 |
|
|
# &pgrid$y<=bbox(roi)[2,2]&pgrid$y>=bbox(roi)[2,1],]
|
182 |
|
|
# ## Crop to ROI polygon?
|
183 |
|
|
# #pgrid=pgrid[!is.na(overlay(SpatialPoints(pgrid),roi)),]
|
184 |
|
|
# rownames(pgrid)=1:nrow(pgrid)
|
185 |
|
|
# ncluster=200
|
186 |
|
|
# pgrid$cluster=cut(as.numeric(rownames(pgrid)),ncluster,labels=1:ncluster)
|
187 |
|
|
# ## predict for the full grid
|
188 |
|
|
# m1pg=lapply(1:ncluster,function(i){
|
189 |
|
|
# print(paste("Starting cluster:",i))
|
190 |
|
|
# m1pg=spPredict(m1,pred.coords=pgrid[pgrid$cluster==i,c("x","y")],
|
191 |
|
|
# pred.covars=cbind(intercept=rep(1,nrow(pgrid[pgrid$cluster==i,]))),start=istart,thin=ithin)
|
192 |
|
|
# ## Generate summaries of y.pred
|
193 |
|
|
# ty=t(apply(m1pg$y.pred,1,function(i) c(mean=mean(i),sd=sd(i),quantile(i,c(0.025,0.5,0.975)))))
|
194 |
|
|
# colnames(ty)=paste("y.",c("mean","sd","Q2.5","Q50","Q97.5"),sep="")
|
195 |
|
|
# ## Generate summaries of w.pred
|
196 |
|
|
# tw=t(apply(m1pg$w.pred,1,function(i) c(mean=mean(i),sd=sd(i),quantile(i,c(0.025,0.5,0.975)))))
|
197 |
|
|
# colnames(tw)=paste("w.",c("mean","sd","Q2.5","Q50","Q97.5"),sep="")
|
198 |
|
|
# return(cbind(ty,tw))
|
199 |
|
|
# })
|
200 |
|
|
# m1pgs=do.call(rbind.data.frame,m1pg)
|
201 |
|
|
|
202 |
|
|
|
203 |
|
|
########### Predict only to validation locations
|
204 |
|
|
m1p=spPredict(m1,pred.coords=pd[,c("lon","lat")],pred.covars=model.matrix(lm(f1,data=pd)),start=istart,thin=ithin)#,
|
205 |
|
|
|
206 |
|
|
m1p.y=mcmc(t(m1p$y.pred),start=istart,thin=ithin)
|
207 |
|
|
m1p.w=mcmc(t(m1$sp.effects.knots),start=istart,thin=ithin)
|
208 |
|
|
m1p.ys=t(apply(m1p.y,2,quantile,c(0.025,0.5,0.975),na.rm=T))
|
209 |
|
|
m1p.ws=t(apply(m1p.w,2,quantile,c(0.025,0.5,0.975),na.rm=T))
|
210 |
|
|
|
211 |
|
|
### recover original scale if necessary
|
212 |
|
|
resp=as.character(attr(terms.formula(f1),"variables"))[2]
|
213 |
|
|
## if modeling anomalies, add the climate back on
|
214 |
|
|
if(type=="anom") {
|
215 |
|
|
pd2=cbind.data.frame(pd,aQ2.5=m1p.ys[,"2.5%"],aQ50=m1p.ys[,"50%"],aQ97.5=m1p.ys[,"97.5%"])
|
216 |
|
|
# FIXME! ctmax below needs to be made general for other variables!
|
217 |
|
|
pd2$Q2.5=pd2$ctmax+pd2$aQ2.5
|
218 |
|
|
pd2$Q50=pd2$ctmax+pd2$aQ50
|
219 |
|
|
pd2$Q97.5=pd2$ctmax+pd2$aQ97.5
|
220 |
|
|
}
|
221 |
|
|
## if modeling raw values, don't add the climate back on
|
222 |
|
|
if(type!="anom") {
|
223 |
|
|
pd2=cbind.data.frame(pd,Q2.5=m1p.ys[,"2.5%"],Q50=m1p.ys[,"50%"],Q97.5=m1p.ys[,"97.5%"])
|
224 |
|
|
}
|
225 |
|
|
|
226 |
|
|
|
227 |
|
|
### save model output
|
228 |
|
|
save(m1,m1p,pd2,file=paste("output/modeloutput_",
|
229 |
|
|
gsub("-","",idate),"_",ivar,"_",type,"_",model,".Rdata",sep=""))
|
230 |
|
|
|
231 |
|
|
|
232 |
|
|
|
233 |
|
|
####################################
|
234 |
|
|
#### Accuracy Assement
|
235 |
|
|
m1.dic=spDiag(m1,start=istart,thin=ithin);m1.dic
|
236 |
|
|
m1.accuracy=accuracy(pd2[,as.character(ivar)],pd2$Q50,ppt=ivar=="ppt")$summary
|
237 |
|
|
|
238 |
|
|
#### Write summary file
|
239 |
|
|
m1.summary=cbind.data.frame(date=idate,model=model,var=ivar,type=type,
|
240 |
|
|
formula=paste(terms(f1),collapse=" "),
|
241 |
|
|
t(m1.dic$DIC),t(m1.accuracy),n.iter=niter,runtime.hours=as.numeric(difftime(t1,t2,units="hours")))
|
242 |
|
|
write.csv(m1.summary,file=paste("output/modeloutput_summary_",gsub("-","",idate),"_",ivar,"_",type,".csv",sep=""))
|
243 |
|
|
|
244 |
|
|
##################################################
|
245 |
|
|
### some summary plots
|
246 |
|
|
pdf(width=11,height=8.5,file=paste("output/modeloutput_",gsub("-","",idate),"_",ivar,"_",type,".pdf",sep=""))
|
247 |
|
|
|
248 |
|
|
## Show knots and stations
|
249 |
|
|
plot(roib);axis(1);axis(2)
|
250 |
|
|
plot(roi,add=T)
|
251 |
|
|
#points(knots,pch=3,cex=.5)
|
252 |
|
|
points(unique(fd[,c('lon','lat')]),cex=.8,pch=16,col="red")
|
253 |
|
|
points(unique(pd[,c('lon','lat')]),cex=.5,pch=16,col="blue")
|
254 |
|
|
points(unique(od[,c('lon','lat')]),cex=.5,pch=16,col="black")
|
255 |
|
|
legend(-118,42,legend=c("Fitting","Validation","Border Stations"),pch=c(16,16,16),col=c("red","blue","black"),bg="white")
|
256 |
|
|
|
257 |
|
|
### Chain behavior
|
258 |
|
|
m1s=mcmc(m1$p.samples)
|
259 |
|
|
print(xyplot(m1s,scales=list(y=list(rot=0)),main="All Posterior Samples of Model Parameters"))
|
260 |
|
|
m1s=mcmc(m1$p.samples,start=istart,thin=ithin)
|
261 |
|
|
print(xyplot(m1s,scales=list(y=list(rot=0)),main="Post-burnin, thinned, Posterior Samples of Model Parameters"))
|
262 |
|
|
|
263 |
|
|
|
264 |
|
|
### Pred vs. obs plots
|
265 |
|
|
plot(pd2[,as.character(ivar)],pd2$Q50,pch=16,cex=.8,ylim=quantile(c(pd2$Q2.5,pd2$Q97.5),c(0.01,0.995)),xlim=quantile(c(pd2$Q2.5,pd2$Q97.5),c(0.01,0.995)))
|
266 |
|
|
segments(pd2[,as.character(ivar)],pd2$Q2.5,pd2[,as.character(ivar)],pd2$Q97.5,col="grey")
|
267 |
|
|
points(pd2[,as.character(ivar)],pd2$Q50,pch=16,cex=.8);abline(0,1,col="red") #xlim=c(0,10)
|
268 |
|
|
|
269 |
|
|
### Maps
|
270 |
|
|
par(mfrow=c(1,3))
|
271 |
|
|
## observed
|
272 |
|
|
obs.surf <- mba.surf(cbind(fd[,c("lon","lat")],fd$tmax), no.X=100, no.Y=100, extend=TRUE)$xyz.est
|
273 |
|
|
image(obs.surf, xaxs = "r", yaxs = "r", main="Observed response",asp=1)
|
274 |
|
|
points(fd[,c("lon","lat")])
|
275 |
|
|
plot(roi,add=T)
|
276 |
|
|
#contour(obs.surf, add=T)
|
277 |
|
|
plot(roi,add=T,border="darkgreen",lwd=3)
|
278 |
|
|
## spatial effects
|
279 |
|
|
w.pred.surf <-
|
280 |
|
|
mba.surf(cbind(coordinates(knots), m1p.ws[,3]), no.X=100, no.Y=100, extend=TRUE)$xyz.est
|
281 |
|
|
image(w.pred.surf, xaxs = "r", yaxs = "r", main="Spatial Effects",asp=1)
|
282 |
|
|
#points(pd[,c("lon","lat")], pch=1, cex=1)
|
283 |
|
|
points(knots, pch=3, cex=1)
|
284 |
|
|
#contour(w.pred.surf, add=T)
|
285 |
|
|
plot(roi,add=T,border="darkgreen",lwd=3)
|
286 |
|
|
legend(1.5,2.5, legend=c("Obs.", "Knots", "Pred."),
|
287 |
|
|
pch=c(1,3,19), bg="white")
|
288 |
|
|
## fitted
|
289 |
|
|
y.pred.surf <-
|
290 |
|
|
mba.surf(cbind(pd2[,c("lon","lat")], pd2$Q50), no.X=100, no.Y=100, extend=TRUE)$xyz.est
|
291 |
|
|
image(y.pred.surf, xaxs = "r", yaxs = "r", main="Predicted response",asp=1)
|
292 |
|
|
points(pd[,c("lon","lat")], pch=1, cex=1)
|
293 |
|
|
#points(knots, pch=3, cex=1)
|
294 |
|
|
#contour(y.pred.surf, add=T)
|
295 |
|
|
plot(roi,add=T,border="darkgreen",lwd=3)
|
296 |
|
|
legend(1.5,2.5, legend=c("Obs.", "Knots", "Pred."),
|
297 |
|
|
pch=c(1,3,19), bg="white")
|
298 |
|
|
|
299 |
|
|
dev.off()
|
300 |
|
|
|
301 |
|
|
### Return objects
|
302 |
|
|
return(m1.summary)
|
303 |
|
|
}
|
304 |
|
|
|
305 |
|
|
|
306 |
|
|
|
307 |
|
|
###########################################################
|
308 |
|
|
### define models to run
|
309 |
|
|
ms=expand.grid(variable="tmax",type=c("anom","raw"),date=dates,model=c("intercept","full"))
|
310 |
|
|
## drop some
|
311 |
|
|
ms[!ms$type=="raw"&ms$model=="intercept",]
|
312 |
|
|
|
313 |
|
|
|
314 |
|
|
msl=apply(ms,1,as.list)
|
315 |
|
|
|
316 |
|
|
|
317 |
|
|
### test it out
|
318 |
|
|
parms=msl[[9]]
|
319 |
|
|
interp(parms,niter=5000,istart=2000,ithin=3)
|
320 |
|
|
|
321 |
|
|
#mresults=lapply(msl[1:3],interp)
|
322 |
|
|
|
323 |
|
|
### run it!
|
324 |
|
|
mresults =mclapply(msl,interp,niter=1000,istart=500,ithin=1,mc.cores=1)
|
325 |
|
|
|
326 |
|
|
### drop any errors
|
327 |
|
|
mresults=mresults[!sapply(mresults,function(x) grepl("Error",x[[1]]))]
|
328 |
|
|
|
329 |
|
|
res=do.call(rbind.data.frame,mresults)
|
330 |
|
|
|
331 |
|
|
save(mresults,res,file="output/mresults.Rdata")
|
332 |
|
|
|
333 |
|
|
q("no")
|
334 |
|
|
|
335 |
|
|
|
336 |
|
|
|
337 |
|
|
|