1 |
9a19743f
|
Adam M. Wilson
|
### Script to compile the monthly cloud data from earth engine into a netcdf file for further processing
|
2 |
|
|
|
3 |
|
|
setwd("~/acrobates/adamw/projects/cloud")
|
4 |
|
|
library(raster)
|
5 |
|
|
library(doMC)
|
6 |
41d291a6
|
Adam M. Wilson
|
library(multicore)
|
7 |
|
|
library(foreach)
|
8 |
|
|
#library(doMPI)
|
9 |
|
|
registerDoMC(10)
|
10 |
|
|
#beginCluster(4)
|
11 |
9a19743f
|
Adam M. Wilson
|
|
12 |
|
|
tempdir="tmp"
|
13 |
|
|
if(!file.exists(tempdir)) dir.create(tempdir)
|
14 |
|
|
|
15 |
f5ef0596
|
Adam M. Wilson
|
|
16 |
|
|
## Load list of tiles
|
17 |
|
|
tiles=read.table("tile_lat_long_10d.txt",header=T)
|
18 |
|
|
|
19 |
41d291a6
|
Adam M. Wilson
|
### Build Tiles
|
20 |
|
|
|
21 |
|
|
## bin sizes
|
22 |
|
|
ybin=30
|
23 |
|
|
xbin=30
|
24 |
|
|
|
25 |
|
|
tiles=expand.grid(ulx=seq(-180,180-xbin,by=xbin),uly=seq(90,-90+ybin,by=-ybin))
|
26 |
|
|
tiles$h=factor(tiles$ulx,labels=paste("h",sprintf("%02d",1:length(unique(tiles$ulx))),sep=""))
|
27 |
|
|
tiles$v=factor(tiles$uly,labels=paste("v",sprintf("%02d",1:length(unique(tiles$uly))),sep=""))
|
28 |
|
|
tiles$tile=paste(tiles$h,tiles$v,sep="")
|
29 |
|
|
tiles$urx=tiles$ulx+xbin
|
30 |
|
|
tiles$ury=tiles$uly
|
31 |
|
|
tiles$lrx=tiles$ulx+xbin
|
32 |
|
|
tiles$lry=tiles$uly-ybin
|
33 |
|
|
tiles$llx=tiles$ulx
|
34 |
|
|
tiles$lly=tiles$uly-ybin
|
35 |
|
|
tiles$cy=(tiles$uly+tiles$lry)/2
|
36 |
|
|
tiles$cx=(tiles$ulx+tiles$urx)/2
|
37 |
|
|
tiles=tiles[,c("tile","h","v","ulx","uly","urx","ury","lrx","lry","llx","lly","cx","cy")]
|
38 |
|
|
|
39 |
|
|
jobs=expand.grid(tile=tiles$tile,year=2000:2012,month=1:12)
|
40 |
|
|
jobs[,c("ulx","uly","urx","ury","lrx","lry","llx","lly")]=tiles[match(jobs$tile,tiles$tile),c("ulx","uly","urx","ury","lrx","lry","llx","lly")]
|
41 |
|
|
|
42 |
|
|
## drop Janurary 2000 from list (pre-modis)
|
43 |
|
|
jobs=jobs[!(jobs$year==2000&jobs$month==1),]
|
44 |
|
|
|
45 |
|
|
#jobs=jobs[jobs$month==1,]
|
46 |
f5ef0596
|
Adam M. Wilson
|
|
47 |
c8be7255
|
Adam M. Wilson
|
|
48 |
41d291a6
|
Adam M. Wilson
|
#jobs=jobs[jobs$month==7,]
|
49 |
f5ef0596
|
Adam M. Wilson
|
## Run the python downloading script
|
50 |
|
|
#system("~/acrobates/adamw/projects/environmental-layers/climate/procedures/ee.MOD09.py -projwin -159 20 -154.5 18.5 -year 2001 -month 6 -region test")
|
51 |
41d291a6
|
Adam M. Wilson
|
i=1
|
52 |
|
|
#testtiles=c("h02v07","h02v06","h02v08","h03v07","h03v06","h03v08")
|
53 |
|
|
#todo=which(jobs$tile%in%testtiles)
|
54 |
|
|
#todo=todo[1:3]
|
55 |
|
|
#todo=1
|
56 |
c8be7255
|
Adam M. Wilson
|
todo=1:nrow(jobs)
|
57 |
41d291a6
|
Adam M. Wilson
|
|
58 |
|
|
checkcomplete=T
|
59 |
|
|
if(checkcomplete&exists("df")){ #if desired (and "df" exists from below) drop complete date-tiles
|
60 |
|
|
todo=which(!paste(jobs$tile,jobs$year,jobs$month)%in%paste(df$region,df$year,df$month))
|
61 |
|
|
}
|
62 |
|
|
|
63 |
|
|
writeLines(paste("Tiling options will produce",nrow(tiles),"tiles and ",nrow(jobs),"tile-months. Current todo list is ",length(todo)))
|
64 |
|
|
|
65 |
|
|
foreach(i=todo) %dopar%{
|
66 |
|
|
system(paste("python ~/acrobates/adamw/projects/environmental-layers/climate/procedures/ee.MOD09.py -projwin ",
|
67 |
|
|
jobs$ulx[i]," ",jobs$uly[i]," ",jobs$urx[i]," ",jobs$ury[i]," ",jobs$lrx[i]," ",jobs$lry[i]," ",jobs$llx[i]," ",jobs$lly[i]," ",
|
68 |
|
|
" -year ",jobs$year[i]," -month ",jobs$month[i]," -region ",jobs$tile[i],sep=""))
|
69 |
|
|
}
|
70 |
f5ef0596
|
Adam M. Wilson
|
|
71 |
|
|
|
72 |
9a19743f
|
Adam M. Wilson
|
## Get list of available files
|
73 |
41d291a6
|
Adam M. Wilson
|
df=data.frame(path=list.files("/mnt/data2/projects/cloud/mod09",pattern="*.tif$",full=T,recur=T),stringsAsFactors=F)
|
74 |
f5ef0596
|
Adam M. Wilson
|
df[,c("region","year","month")]=do.call(rbind,strsplit(basename(df$path),"_|[.]"))[,c(1,2,3)]
|
75 |
9a19743f
|
Adam M. Wilson
|
df$date=as.Date(paste(df$year,"_",df$month,"_15",sep=""),"%Y_%m_%d")
|
76 |
|
|
|
77 |
41d291a6
|
Adam M. Wilson
|
## add stats to test for missing data
|
78 |
|
|
addstats=F
|
79 |
|
|
if(addstats){
|
80 |
|
|
df[,c("max","min","mean","sd")]=do.call(rbind.data.frame,mclapply(1:nrow(df),function(i) as.numeric(sub("^.*[=]","",grep("STATISTICS",system(paste("gdalinfo -stats",df$path[i]),inter=T),value=T)))))
|
81 |
|
|
table(df$sd==0)
|
82 |
|
|
}
|
83 |
|
|
|
84 |
f5ef0596
|
Adam M. Wilson
|
## subset to testtiles?
|
85 |
c8be7255
|
Adam M. Wilson
|
#df=df[df$region%in%testtiles,]
|
86 |
41d291a6
|
Adam M. Wilson
|
#df=df[df$month==1,]
|
87 |
f5ef0596
|
Adam M. Wilson
|
table(df$year,df$month)
|
88 |
d7dc526e
|
Adam M. Wilson
|
|
89 |
9a19743f
|
Adam M. Wilson
|
## drop some if not complete
|
90 |
41d291a6
|
Adam M. Wilson
|
df=df[df$month==1&df$year%in%c(2001:2002,2005),]
|
91 |
d7dc526e
|
Adam M. Wilson
|
rerun=T # set to true to recalculate all dates even if file already exists
|
92 |
9a19743f
|
Adam M. Wilson
|
|
93 |
|
|
## Loop over existing months to build composite netcdf files
|
94 |
|
|
foreach(date=unique(df$date)) %dopar% {
|
95 |
|
|
## get date
|
96 |
|
|
print(date)
|
97 |
|
|
## Define output and check if it already exists
|
98 |
41d291a6
|
Adam M. Wilson
|
tffile=paste(tempdir,"/mod09_",date,".tif",sep="")
|
99 |
9a19743f
|
Adam M. Wilson
|
ncfile=paste(tempdir,"/mod09_",date,".nc",sep="")
|
100 |
d7dc526e
|
Adam M. Wilson
|
if(!rerun&file.exists(ncfile)) next
|
101 |
9a19743f
|
Adam M. Wilson
|
## merge regions to a new netcdf file
|
102 |
41d291a6
|
Adam M. Wilson
|
# system(paste("gdal_merge.py -tap -init 5 -o ",ncfile," -n -32768.000 -of netCDF -ot Int16 ",paste(df$path[df$date==date],collapse=" ")))
|
103 |
|
|
system(paste("gdal_merge.py -o ",tffile," -init -32768 -n -32768.000 -ot Int16 ",paste(df$path[df$date==date],collapse=" ")))
|
104 |
|
|
system(paste("gdal_translate -of netCDF ",tffile," ",ncfile," -ot Int16 "))
|
105 |
|
|
file.remove(tffile)
|
106 |
9a19743f
|
Adam M. Wilson
|
system(paste("ncecat -O -u time ",ncfile," ",ncfile,sep=""))
|
107 |
|
|
## create temporary nc file with time information to append to MOD06 data
|
108 |
|
|
cat(paste("
|
109 |
|
|
netcdf time {
|
110 |
|
|
dimensions:
|
111 |
|
|
time = 1 ;
|
112 |
|
|
variables:
|
113 |
|
|
int time(time) ;
|
114 |
|
|
time:units = \"days since 2000-01-01 00:00:00\" ;
|
115 |
|
|
time:calendar = \"gregorian\";
|
116 |
|
|
time:long_name = \"time of observation\";
|
117 |
|
|
data:
|
118 |
|
|
time=",as.integer(date-as.Date("2000-01-01")),";
|
119 |
|
|
}"),file=paste(tempdir,"/",date,"_time.cdl",sep=""))
|
120 |
|
|
system(paste("ncgen -o ",tempdir,"/",date,"_time.nc ",tempdir,"/",date,"_time.cdl",sep=""))
|
121 |
|
|
system(paste("ncks -A ",tempdir,"/",date,"_time.nc ",ncfile,sep=""))
|
122 |
|
|
## add other attributes
|
123 |
|
|
system(paste("ncrename -v Band1,CF ",ncfile,sep=""))
|
124 |
|
|
system(paste("ncatted ",
|
125 |
f5ef0596
|
Adam M. Wilson
|
" -a units,CF,o,c,\"Proportion Days Cloudy\" ",
|
126 |
|
|
# " -a valid_range,CF,o,b,\"0,100\" ",
|
127 |
|
|
" -a scale_factor,CF,o,f,\"0.1\" ",
|
128 |
|
|
" -a long_name,CF,o,c,\"Proportion cloudy days (%)\" ",
|
129 |
|
|
ncfile,sep=""))
|
130 |
|
|
|
131 |
|
|
## add the fillvalue attribute back (without changing the actual values)
|
132 |
|
|
#system(paste("ncatted -a _FillValue,CF,o,b,-32768 ",ncfile,sep=""))
|
133 |
9a19743f
|
Adam M. Wilson
|
|
134 |
|
|
if(as.numeric(system(paste("cdo -s ntime ",ncfile),intern=T))<1) {
|
135 |
|
|
print(paste(ncfile," has no time, deleting"))
|
136 |
d7dc526e
|
Adam M. Wilson
|
file.remove(ncfile)
|
137 |
9a19743f
|
Adam M. Wilson
|
}
|
138 |
|
|
print(paste(basename(ncfile)," Finished"))
|
139 |
|
|
|
140 |
|
|
}
|
141 |
|
|
|
142 |
d7dc526e
|
Adam M. Wilson
|
|
143 |
|
|
|
144 |
|
|
|
145 |
|
|
|
146 |
9a19743f
|
Adam M. Wilson
|
### merge all the tiles to a single global composite
|
147 |
|
|
#system(paste("ncdump -h ",list.files(tempdir,pattern="mod09.*.nc$",full=T)[10]))
|
148 |
|
|
system(paste("cdo -O mergetime ",paste(list.files(tempdir,pattern="mod09.*.nc$",full=T),collapse=" ")," data/mod09.nc"))
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
### generate the monthly mean and sd
|
152 |
d86b0a4a
|
Adam M. Wilson
|
#system(paste("cdo -P 10 -O merge -ymonmean data/mod09.nc -chname,CF,CF_sd -ymonstd data/mod09.nc data/mod09_clim.nc"))
|
153 |
41d291a6
|
Adam M. Wilson
|
xosystem(paste("cdo -O -ymonmean data/mod09.nc data/mod09_clim_mean.nc"))
|
154 |
d86b0a4a
|
Adam M. Wilson
|
system(paste("cdo -O -chname,CF,CF_sd -ymonstd data/mod09.nc data/mod09_clim_sd.nc"))
|
155 |
d7dc526e
|
Adam M. Wilson
|
|
156 |
|
|
# Overall mean
|
157 |
d86b0a4a
|
Adam M. Wilson
|
system(paste("cdo -O -chname,CF,CF_annual -timmean data/mod09.nc data/mod09_clim_mac.nc"))
|
158 |
d7dc526e
|
Adam M. Wilson
|
|
159 |
|
|
### Long term summaries
|
160 |
|
|
seasconc <- function(x,return.Pc=T,return.thetat=F) {
|
161 |
|
|
#################################################################################################
|
162 |
|
|
## Precipitation Concentration function
|
163 |
|
|
## This function calculates Precipitation Concentration based on Markham's (1970) technique as described in Schulze (1997)
|
164 |
|
|
## South Africa Atlas of Agrohydology and Climatology - R E Schulze, M Maharaj, S D Lynch, B J Howe, and B Melvile-Thomson
|
165 |
|
|
## Pages 37-38
|
166 |
|
|
#################################################################################################
|
167 |
|
|
## x is a vector of precipitation quantities - the mean for each factor in "months" will be taken,
|
168 |
|
|
## so it does not matter if the data are daily or monthly, as long as the "months" factor correctly
|
169 |
|
|
## identifies them into 12 monthly bins, collapse indicates whether the data are already summarized as monthly means.
|
170 |
|
|
#################################################################################################
|
171 |
|
|
theta=seq(30,360,30)*(pi/180) # set up angles for each month & convert to radians
|
172 |
|
|
if(sum(is.na(x))==12) { return(cbind(Pc=NA,thetat=NA)) ; stop}
|
173 |
|
|
if(return.Pc) {
|
174 |
|
|
rt=sqrt(sum(x * cos(theta))^2 + sum(x * sin(theta))^2) # the magnitude of the summation
|
175 |
|
|
Pc=as.integer(round((rt/sum(x))*100))}
|
176 |
|
|
if(return.thetat){
|
177 |
|
|
s1=sum(x*sin(theta),na.rm=T); s2=sum(x*cos(theta),na.rm=T)
|
178 |
|
|
if(s1>=0 & s2>=0) {thetat=abs((180/pi)*(atan(sum(x*sin(theta),na.rm=T)/sum(x*cos(theta),na.rm=T))))}
|
179 |
|
|
if(s1>0 & s2<0) {thetat=180-abs((180/pi)*(atan(sum(x*sin(theta),na.rm=T)/sum(x*cos(theta),na.rm=T))))}
|
180 |
|
|
if(s1<0 & s2<0) {thetat=180+abs((180/pi)*(atan(sum(x*sin(theta),na.rm=T)/sum(x*cos(theta),na.rm=T))))}
|
181 |
|
|
if(s1<0 & s2>0) {thetat=360-abs((180/pi)*(atan(sum(x*sin(theta),na.rm=T)/sum(x*cos(theta),na.rm=T))))}
|
182 |
|
|
thetat=as.integer(round(thetat))
|
183 |
|
|
}
|
184 |
|
|
if(return.thetat&return.Pc) return(c(conc=Pc,theta=thetat))
|
185 |
|
|
if(return.Pc) return(Pc)
|
186 |
|
|
if(return.thetat) return(thetat)
|
187 |
|
|
}
|
188 |
|
|
|
189 |
|
|
|
190 |
|
|
## read in monthly dataset
|
191 |
d86b0a4a
|
Adam M. Wilson
|
mod09=brick("data/mod09_clim_mean.nc",varname="CF")
|
192 |
d7dc526e
|
Adam M. Wilson
|
plot(mod09[1])
|
193 |
9a19743f
|
Adam M. Wilson
|
|
194 |
d7dc526e
|
Adam M. Wilson
|
mod09_seas=calc(mod09,seasconc,return.Pc=T,return.thetat=F,overwrite=T,filename="data/mod09_seas.nc",NAflag=255,datatype="INT1U")
|
195 |
d86b0a4a
|
Adam M. Wilson
|
mod09_seas2=calc(mod09,seasconc,return.Pc=F,return.thetat=T,overwrite=T,filename="data/mod09_seas_theta.nc",datatype="INT1U")
|
196 |
9a19743f
|
Adam M. Wilson
|
|
197 |
d7dc526e
|
Adam M. Wilson
|
plot(mod09_seas)
|