1
|
############################
|
2
|
#### Extract MOD35 C6 processing path
|
3
|
|
4
|
setwd("~/acrobates/adamw/projects/interp/data/modis/mod35")
|
5
|
library(multicore)
|
6
|
library(raster)
|
7
|
library(spgrass6)
|
8
|
library(rgeos)
|
9
|
##download 3 days of modis swath data:
|
10
|
|
11
|
url="ftp://ladsweb.nascom.nasa.gov/allData/51/MOD35_L2/2012/"
|
12
|
dir.create("swath")
|
13
|
|
14
|
system(paste("wget -S --recursive --no-parent --no-directories -N -P swath --accept \"hdf\" --accept \"002|003|004\" ",url))
|
15
|
|
16
|
|
17
|
### make global raster that aligns with MODLAND tiles
|
18
|
## get MODLAND tile to serve as base
|
19
|
#system("wget http://e4ftl01.cr.usgs.gov/MOLT/MOD13A3.005/2000.02.01/MOD13A3.A2000032.h00v08.005.2006271174446.hdf")
|
20
|
#t=raster(paste("HDF4_EOS:EOS_GRID:\"",getwd(),"/MOD13A3.A2000032.h00v08.005.2006271174446.hdf\":MOD_Grid_monthly_1km_VI:1 km monthly NDVI",sep=""))
|
21
|
t=raster(paste("../MOD17/MOD17A3_Science_NPP_mean_00_12.tif",sep=""))
|
22
|
projection(t)
|
23
|
|
24
|
## make global extent
|
25
|
pmodis="+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs"
|
26
|
|
27
|
glb=t
|
28
|
#values(glb)=NA
|
29
|
glb=extend(glb,extent(-180,180,-90,90))
|
30
|
|
31
|
#glb=raster(glb,crs="+proj=longlat +datum=WGS84",nrows=42500,ncols=85000)
|
32
|
#extent(glb)=alignExtent(projectRaster(glb,crs=projection(t),over=T),t)
|
33
|
#res(glb)=c(926.6254,926.6264)
|
34
|
#projection(glb)=pmodis
|
35
|
|
36
|
## confirm extent
|
37
|
#projectExtent(glb,crs="+proj=longlat +datum=WGS84")
|
38
|
|
39
|
|
40
|
#### Grid and mosaic the swath data
|
41
|
|
42
|
stitch="sudo MRTDATADIR=\"/usr/local/heg/data\" PGSHOME=/usr/local/heg/TOOLKIT_MTD PWD=/home/adamw /usr/local/heg/bin/swtif"
|
43
|
|
44
|
files=paste(getwd(),"/",list.files("swath",pattern="hdf$",full=T),sep="")
|
45
|
|
46
|
## vars to process
|
47
|
vars=as.data.frame(matrix(c(
|
48
|
"Cloud_Mask", "CM",
|
49
|
"Sensor_Azimuth", "ZA",
|
50
|
"Sensor_Zenith", "SZ"),
|
51
|
byrow=T,ncol=2,dimnames=list(1:3,c("variable","varid"))),stringsAsFactors=F)
|
52
|
|
53
|
## global bounding box
|
54
|
gbb=cbind(c(-180,-180,180,180,-180),c(-85,85,85,-85,-85))
|
55
|
gpp = SpatialPolygons(list(Polygons(list(Polygon(gbb)),1)))
|
56
|
proj4string(gpp)=projection(glb)
|
57
|
|
58
|
|
59
|
getpath<- function(file){
|
60
|
setwd(tempdir())
|
61
|
bfile=sub(".hdf","",basename(file))
|
62
|
tempfile_path=paste(tempdir(),"/path_",basename(file),sep="") #gridded path
|
63
|
tempfile_sz=paste(tempdir(),"/sz_",basename(file),sep="") # gridded sensor zenith
|
64
|
tempfile2_path=paste(tempdir(),"/",bfile,".tif",sep="") #gridded/masked/processed path
|
65
|
outfile=paste("~/acrobates/adamw/projects/interp/data/modis/mod35/gridded/",bfile,".tif",sep="") #final file
|
66
|
if(file.exists(outfile)) return(c(file,0))
|
67
|
## get bounding coordinates
|
68
|
glat=as.numeric(do.call(c,strsplit(sub("GRINGPOINTLATITUDE=","",system(paste("gdalinfo ",file," | grep GRINGPOINTLATITUDE"),intern=T)),split=",")))
|
69
|
glon=as.numeric(do.call(c,strsplit(sub("GRINGPOINTLONGITUDE=","",system(paste("gdalinfo ",file," | grep GRINGPOINTLONGITUDE"),intern=T)),split=",")))
|
70
|
bb=cbind(c(glon,glon[1]),c(glat,glat[1]))
|
71
|
pp = SpatialPolygons(list(Polygons(list(Polygon(bb)),1)))
|
72
|
proj4string(pp)=projection(glb)
|
73
|
ppc=gIntersection(pp,gpp)
|
74
|
ppc=gBuffer(ppc,width=0.3) #buffer a little to remove gaps between images
|
75
|
## First write the parameter file (careful, heg is very finicky!)
|
76
|
hdr=paste("NUM_RUNS = ",length(vars$varid),"|MULTI_BAND_HDFEOS:",length(vars$varid),sep="")
|
77
|
grp=paste("
|
78
|
BEGIN
|
79
|
INPUT_FILENAME=",file,"
|
80
|
OBJECT_NAME=mod35
|
81
|
FIELD_NAME=",vars$variable,"|
|
82
|
BAND_NUMBER = ",1:length(vars$varid),"
|
83
|
OUTPUT_PIXEL_SIZE_X=0.008333333
|
84
|
OUTPUT_PIXEL_SIZE_Y=0.008333333
|
85
|
SPATIAL_SUBSET_UL_CORNER = ( ",bbox(ppc)[2,2]," ",bbox(ppc)[1,1]," )
|
86
|
SPATIAL_SUBSET_LR_CORNER = ( ",bbox(ppc)[2,1]," ",bbox(ppc)[1,2]," )
|
87
|
OUTPUT_OBJECT_NAME = mod35|
|
88
|
RESAMPLING_TYPE =NN
|
89
|
OUTPUT_PROJECTION_TYPE = GEO
|
90
|
OUTPUT_PROJECTION_PARAMETERS = ( 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
|
91
|
# OUTPUT_PROJECTION_PARAMETERS = ( 6371007.181 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
|
92
|
# projection parameters from http://landweb.nascom.nasa.gov/cgi-bin/QA_WWW/newPage.cgi?fileName=sn_gctp
|
93
|
ELLIPSOID_CODE = WGS84
|
94
|
OUTPUT_TYPE = HDFEOS
|
95
|
OUTPUT_FILENAME= ",tempfile_path,"
|
96
|
END
|
97
|
|
98
|
",sep="")
|
99
|
|
100
|
## if any remnants from previous runs remain, delete them
|
101
|
if(length(list.files(tempdir(),pattern=bfile)>0))
|
102
|
file.remove(list.files(tempdir(),pattern=bfile,full=T))
|
103
|
## write it to a file
|
104
|
cat( c(hdr,grp) , file=paste(tempdir(),"/",basename(file),"_MODparms.txt",sep=""))
|
105
|
## now run the swath2grid tool
|
106
|
## write the gridded file
|
107
|
print(paste("Starting",file))
|
108
|
system(paste("(",stitch," -p ",tempdir(),"/",basename(file),"_MODparms.txt -d)",sep=""),intern=F)#,ignore.stderr=F)
|
109
|
############## Now run the 5km summary
|
110
|
## First write the parameter file (careful, heg is very finicky!)
|
111
|
hdr=paste("NUM_RUNS = ",nrow(vars[-1,]),"|MULTI_BAND_HDFEOS:",nrow(vars[-1,]),sep="")
|
112
|
grp=paste("
|
113
|
BEGIN
|
114
|
INPUT_FILENAME=",file,"
|
115
|
OBJECT_NAME=mod35
|
116
|
FIELD_NAME=",vars$variable[-1],"|
|
117
|
BAND_NUMBER = ",1,"
|
118
|
OUTPUT_PIXEL_SIZE_X=0.008333333
|
119
|
#0.0416666
|
120
|
OUTPUT_PIXEL_SIZE_Y=0.008333333
|
121
|
#0.0416666
|
122
|
SPATIAL_SUBSET_UL_CORNER = ( ",bbox(ppc)[2,2]," ",bbox(ppc)[1,1]," )
|
123
|
SPATIAL_SUBSET_LR_CORNER = ( ",bbox(ppc)[2,1]," ",bbox(ppc)[1,2]," )
|
124
|
#OUTPUT_OBJECT_NAME = mod35|
|
125
|
RESAMPLING_TYPE =NN
|
126
|
OUTPUT_PROJECTION_TYPE = GEO
|
127
|
OUTPUT_PROJECTION_PARAMETERS = ( 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
|
128
|
#OUTPUT_PROJECTION_PARAMETERS = ( 6371007.181 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 )
|
129
|
# projection parameters from http://landweb.nascom.nasa.gov/cgi-bin/QA_WWW/newPage.cgi?fileName=sn_gctp
|
130
|
ELLIPSOID_CODE = WGS84
|
131
|
OUTPUT_TYPE = HDFEOS
|
132
|
OUTPUT_FILENAME= ",tempfile_sz,"
|
133
|
END
|
134
|
|
135
|
",sep="")
|
136
|
|
137
|
## write it to a file
|
138
|
cat( c(hdr,grp) , file=paste(tempdir(),"/",basename(file),"_MODparms_angle.txt",sep=""))
|
139
|
|
140
|
## now run the swath2grid tool
|
141
|
## write the gridded file
|
142
|
print(paste("Starting",file))
|
143
|
system(paste("(",stitch," -p ",tempdir(),"/",basename(file),"_MODparms_angle.txt -d)",sep=""),intern=F,ignore.stderr=F)
|
144
|
####### import to R for processing
|
145
|
if(!file.exists(tempfile_path)) {
|
146
|
file.remove(list.files(tempdir(),pattern=bfile,full=T))
|
147
|
return(c(file,0))
|
148
|
}
|
149
|
## convert to land path
|
150
|
d=raster(paste("HDF4_EOS:EOS_GRID:\"",tempfile_path,"\":mod35:Cloud_Mask_0",sep=""))
|
151
|
sz=raster(paste("HDF4_EOS:EOS_GRID:\"",tempfile_sz,"\":mod35:Sensor_Zenith",sep=""))
|
152
|
NAvalue(sz)=0
|
153
|
## resample sensor angles to 1km grid and mask paths with angles >=30
|
154
|
# sz2=resample(sz,d,method="ngb",file=sub("hdf","tif",tempfile_sz),overwrite=T)
|
155
|
getlc=function(x,y) {ifelse(y==0|y>40,NA,((x%/%2^6) %% 2^2))}
|
156
|
path= overlay(d,sz,fun=getlc,filename=tempfile2_path,options=c("COMPRESS=LZW", "LEVEL=9","PREDICTOR=2"),datatype="INT1U",overwrite=T)
|
157
|
### warp them to align all pixels
|
158
|
system(paste("gdalwarp -overwrite -srcnodata 255 -dstnodata 255 -tap -tr 0.008333333 0.008333333 -co COMPRESS=LZW -co ZLEVEL=9 -co PREDICTOR=2 -s_srs \"",projection(t),"\" ",tempfile2_path," ",outfile,sep=""))
|
159
|
## delete temporary files
|
160
|
file.remove(list.files(tempdir(),pattern=bfile,full=T))
|
161
|
return(c(file,1))
|
162
|
}
|
163
|
|
164
|
|
165
|
## establish sudo priveleges to run swtif
|
166
|
system("sudo ls"); mclapply(files,getpath,mc.cores=10)
|
167
|
|
168
|
## check gdal can read all of them
|
169
|
gfiles=list.files("gridded",pattern="tif$",full=T)
|
170
|
length(gfiles)
|
171
|
|
172
|
check=do.call(rbind,mclapply(gfiles,function(file){
|
173
|
gd=system(paste("gdalinfo ",file,sep=""),intern=T)
|
174
|
if(any(grepl("Corner",gd))) return(1)
|
175
|
else return(0)
|
176
|
}))
|
177
|
|
178
|
table(check)
|
179
|
|
180
|
file.remove(gfiles[check==0])
|
181
|
|
182
|
## use new gdal
|
183
|
system(paste("/usr/local/gdal-1.10.0/bin/gdalwarp -wm 900 -overwrite -co COMPRESS=LZW -co PREDICTOR=2 -multi -r mode gridded/*.tif MOD35_path_gdalwarp.tif"))
|
184
|
|
185
|
|
186
|
# origin(raster(gfiles[5]))
|
187
|
|
188
|
## try with pktools
|
189
|
## global
|
190
|
system(paste("pkmosaic -co COMPRESS=LZW -co PREDICTOR=2 ",paste("-i",list.files("gridded",full=T,pattern="tif$"),collapse=" ")," -o MOD35_path_pkmosaic_max.tif -m 2 -v -t 255 -t 0 &"))
|
191
|
#bb="-ulx -180 -uly 90 -lrx 180 -lry -90"
|
192
|
#bb="-ulx -180 -uly 90 -lrx 170 -lry 80"
|
193
|
bb="-ulx -72 -uly 11 -lrx -59 -lry -1"
|
194
|
|
195
|
|
196
|
#expand.grid(x=seq(-180,170,by=10),y=seq(-90,80))
|
197
|
gf2= grep("2012009[.]03",gfiles,value=T)
|
198
|
system(paste("pkmosaic ",bb," -co COMPRESS=LZW -co PREDICTOR=2 ",paste("-i",gf2,collapse=" ")," -o h11v08_path_pkmosaic.tif -ot Byte -m 7 -v -t 255"))
|
199
|
|
200
|
# bounding box?
|
201
|
|
202
|
###########
|
203
|
### Use GRASS to import all the tifs and calculat the mode
|
204
|
## make temporary working directory
|
205
|
tf=paste(tempdir(),"/grass", Sys.getpid(),"/", sep="") #temporar
|
206
|
if(!file.exists(tf)) dir.create(tf)
|
207
|
|
208
|
## set up temporary grass instance for this PID
|
209
|
gisBase="/usr/lib/grass64"
|
210
|
print(paste("Set up temporary grass session in",tf))
|
211
|
initGRASS(gisBase=gisBase,gisDbase=tf,SG=as(glb,"SpatialGridDataFrame"),override=T,location="mod35",mapset="PERMANENT",home=tf,pid=Sys.getpid())
|
212
|
system(paste("g.proj -c proj4=\"",projection(glb),"\"",sep=""),ignore.stdout=T,ignore.stderr=T)
|
213
|
|
214
|
## read in NPP grid to serve as grid
|
215
|
execGRASS("r.in.gdal",input=t@file@name,output="grid")
|
216
|
system("g.region rast=grid n=90 s=-90 save=roi --overwrite",ignore.stdout=F,ignore.stderr=F)
|
217
|
|
218
|
## get files already imported - only important if more tifs were written after an initial import
|
219
|
imported=basename(gfiles)%in%system("g.mlist type=rast pattern=MOD*",intern=T)
|
220
|
table(imported)
|
221
|
|
222
|
## read in all tifs
|
223
|
for(f in gfiles[!imported]) execGRASS("r.in.gdal",input=f,output=basename(f),flags="o")
|
224
|
|
225
|
## calculate mode
|
226
|
execGRASS("r.series",input=paste(system("g.mlist type=rast pattern=MOD*",intern=T)[1:1000],sep="",collapse=","),output="MOD35_path",method="mode",range=c(1,5),flags=c("verbose","overwrite"))
|
227
|
## add colors
|
228
|
execGRASS("r.colors",map="MOD35_path",rules="MOD35_path_grasscolors.txt")
|
229
|
## write to disk
|
230
|
execGRASS("r.out.gdal",input="MOD35_path",output=paste(getwd(),"/MOD35_ProcessPath_C5.tif",sep=""),type="Byte",createopt="COMPRESS=LZW,LEVEL=9,PREDICTOR=2")
|
231
|
|
232
|
### delete the temporary files
|
233
|
unlink_.gislock()
|
234
|
system(paste("rm -frR ",tf,sep=""))
|
235
|
|
236
|
#########################
|
237
|
|
238
|
|
239
|
cols=c("blue","lightblue","tan","green")
|
240
|
|
241
|
|
242
|
### Merge them into a geotiff
|
243
|
system(paste("gdal_merge.py -v -n 255 -o MOD35_ProcessPath.tif -co \"COMPRESS=LZW\" -co \"PREDICTOR=2\" `ls -d -1 gridded/*.tif`",sep=""))
|
244
|
|
245
|
|
246
|
## connect to raster to extract land-cover bit
|
247
|
library(raster)
|
248
|
|
249
|
d=raster("CM.tif")
|
250
|
getlc=function(x) {(x/2^6) %% 2^2}
|
251
|
|
252
|
calc(d,fun=getlc,filename="CM_LC.tif")
|
253
|
|