|
1 |
###################################################################################
|
|
2 |
### R code to aquire and process MOD06_L2 cloud data from the MODIS platform
|
|
3 |
|
|
4 |
|
|
5 |
##First read in the arguments listed at the command line
|
|
6 |
args=(commandArgs(TRUE))
|
|
7 |
##args is now a list of character vectors
|
|
8 |
## First check to see if arguments are passed.
|
|
9 |
## if no args were given, print a warning and stop
|
|
10 |
if(length(args)==0) {stop("No parameters supplied, you must pass parameters")}
|
|
11 |
|
|
12 |
## Then cycle through each element of the list and evaluate the expressions.
|
|
13 |
eval(parse(text=args))
|
|
14 |
## now there is an i that corresponds to the row in the notdone object that will be processed.
|
|
15 |
|
|
16 |
## load libraries
|
|
17 |
require(sp)
|
|
18 |
require(rgdal)
|
|
19 |
require(reshape)
|
|
20 |
require(ncdf4)
|
|
21 |
require(geosphere)
|
|
22 |
require(raster)
|
|
23 |
require(spgrass6)
|
|
24 |
|
|
25 |
## specify some working directories
|
|
26 |
setwd("/nobackupp1/awilso10/mod06")
|
|
27 |
tempdir=tempdir() # to hold intermediate files
|
|
28 |
outdir="2_daily" # final daily product
|
|
29 |
|
|
30 |
### use MODIS tile as ROI instead
|
|
31 |
modt=readOGR("modgrid","modis_sinusoidal_grid_world",)
|
|
32 |
tiles=c("H11V8")
|
|
33 |
roi=modt[modt$HV%in%tiles,]
|
|
34 |
|
|
35 |
## Bounding box of region in lat/lon
|
|
36 |
roi_ll=spTransform(roi,CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"))
|
|
37 |
roi_bb=bbox(roi_ll)
|
|
38 |
|
|
39 |
## read in list of all files
|
|
40 |
load("allfiles.Rdata")
|
|
41 |
load("alldates.Rdata")
|
|
42 |
load("notdonedates.Rdata")
|
|
43 |
load("vars.Rdata")
|
|
44 |
|
|
45 |
date=notdonedates[i]
|
|
46 |
|
|
47 |
|
|
48 |
#### Function to generate hegtool parameter file for multi-band HDF-EOS file
|
|
49 |
swath2grid=function(file,vars,outdir,upleft,lowright){
|
|
50 |
print(paste("Starting file",basename(file)))
|
|
51 |
outfile=paste(outdir,"/",basename(file),sep="")
|
|
52 |
### First write the parameter file (careful, heg is very finicky!)
|
|
53 |
hdr=paste("NUM_RUNS = ",length(vars$varid),"|MULTI_BAND_HDFEOS:",length(vars$varid),sep="")
|
|
54 |
grp=paste("
|
|
55 |
BEGIN
|
|
56 |
INPUT_FILENAME=",file,"
|
|
57 |
OBJECT_NAME=mod06
|
|
58 |
FIELD_NAME=",vars$variable,"|
|
|
59 |
BAND_NUMBER = 1
|
|
60 |
OUTPUT_PIXEL_SIZE_X=1000
|
|
61 |
OUTPUT_PIXEL_SIZE_Y=1000
|
|
62 |
SPATIAL_SUBSET_UL_CORNER = ( ",upleft," )
|
|
63 |
SPATIAL_SUBSET_LR_CORNER = ( ",lowright," )
|
|
64 |
#RESAMPLING_TYPE =",ifelse(grepl("Flag|Mask|Quality",vars),"NN","CUBIC"),"
|
|
65 |
RESAMPLING_TYPE =NN
|
|
66 |
OUTPUT_PROJECTION_TYPE = SIN
|
|
67 |
#UTM_ZONE = 10
|
|
68 |
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 )
|
|
69 |
# projection parameters from http://landweb.nascom.nasa.gov/cgi-bin/QA_WWW/newPage.cgi?fileName=sn_gctp
|
|
70 |
ELLIPSOID_CODE = WGS84
|
|
71 |
OUTPUT_TYPE = HDFEOS
|
|
72 |
OUTPUT_FILENAME = ",outfile,"
|
|
73 |
END
|
|
74 |
|
|
75 |
",sep="")
|
|
76 |
|
|
77 |
## if any remnants from previous runs remain, delete them
|
|
78 |
if(length(list.files(tempdir(),pattern=basename(file)))>0)
|
|
79 |
file.remove(list.files(tempdir(),pattern=basename(file),full=T))
|
|
80 |
## write it to a file
|
|
81 |
cat(c(hdr,grp) , file=paste(tempdir(),"/",basename(file),"_MODparms.txt",sep=""))
|
|
82 |
## now run the swath2grid tool
|
|
83 |
## write the tiff file
|
|
84 |
log=system(paste("/nobackupp4/pvotava/software/heg/bin/swtif -p ",paste(tempdir(),"/",basename(file),"_MODparms.txt -d",sep=""),sep=""),intern=T)
|
|
85 |
print(paste("Finished ", file))
|
|
86 |
}
|
|
87 |
|
|
88 |
## fix out dir to tempdir
|
|
89 |
## then move on to grass processing...
|
|
90 |
|
|
91 |
#### Run the gridding procedure
|
|
92 |
lapply(fs$path[fs$dateid==date],function(file){
|
|
93 |
swath2grid(file,vars=vars,outdir=outdir,
|
|
94 |
upleft=paste(roi_bb[2,2],roi_bb[1,1]),
|
|
95 |
lowright=paste(roi_bb[2,1],roi_bb[1,2]))})
|
|
96 |
|
|
97 |
|
|
98 |
##############################################################
|
|
99 |
### Import to GRASS for processing
|
|
100 |
|
|
101 |
#fs$grass=paste(fs$month,fs$year,fs$file,sep="_")
|
|
102 |
td=readGDAL(paste("HDF4_EOS:EOS_GRID:\"",outdir,"/",fs$file[1],"\":mod06:Cloud_Mask_1km_0",sep=""))
|
|
103 |
#projection(td)="+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs +datum=WGS84 +ellps=WGS84 "
|
|
104 |
projection(td)="+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
|
|
105 |
|
|
106 |
## fucntion to convert binary to decimal to assist in identifying correct values
|
|
107 |
b2d=function(x) sum(x * 2^(rev(seq_along(x)) - 1)) #http://tolstoy.newcastle.edu.au/R/e2/help/07/02/10596.html
|
|
108 |
## for example:
|
|
109 |
b2d(c(T,T))
|
|
110 |
|
|
111 |
### create (or connect to) grass location
|
|
112 |
gisDbase="/media/data/grassdata"
|
|
113 |
gisLocation="oregon"
|
|
114 |
gisMapset="mod06"
|
|
115 |
## set Grass to overwrite
|
|
116 |
Sys.setenv(GRASS_OVERWRITE=1)
|
|
117 |
Sys.setenv(DEBUG=0)
|
|
118 |
|
|
119 |
## temporary objects to test function below
|
|
120 |
i=1
|
|
121 |
file=paste(outdir,"/",fs$file[1],sep="")
|
|
122 |
date=as.Date("2000-05-23")
|
|
123 |
|
|
124 |
|
|
125 |
### Function to extract various SDSs from a single gridded HDF file and use QA data to throw out 'bad' observations
|
|
126 |
loadcloud<-function(date,fs){
|
|
127 |
### set up unique grass session
|
|
128 |
tf=paste(tempdir(),"/grass", Sys.getpid(),"/", sep="")
|
|
129 |
|
|
130 |
## set up tempfile for this PID
|
|
131 |
initGRASS(gisBase="/usr/lib/grass64",gisDbase=tf,SG=td,override=T,location="mod06",mapset="PERMANENT",home=tf,pid=Sys.getpid())
|
|
132 |
# system(paste("g.proj -c proj4=\"+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +datum=WGS84 +units=m +no_defs\"",sep=""))
|
|
133 |
system(paste("g.proj -c proj4=\"+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m +no_defs\"",sep=""))
|
|
134 |
|
|
135 |
## Define region by importing one raster.
|
|
136 |
execGRASS("r.in.gdal",input=paste("HDF4_EOS:EOS_GRID:\"",outdir,"/",fs$file[1],"\":mod06:Cloud_Mask_1km_0",sep=""),
|
|
137 |
output="modisgrid",flags=c("quiet","overwrite","o"))
|
|
138 |
system("g.region rast=modisgrid save=roi --overwrite")
|
|
139 |
system("g.region roi")
|
|
140 |
system("g.region -p")
|
|
141 |
|
|
142 |
## Identify which files to process
|
|
143 |
tfs=fs$file[fs$date==date]
|
|
144 |
nfs=length(tfs)
|
|
145 |
|
|
146 |
### print some summary info
|
|
147 |
print(date)
|
|
148 |
## loop through scenes and process QA flags
|
|
149 |
for(i in 1:nfs){
|
|
150 |
file=paste(outdir,"/",tfs[i],sep="")
|
|
151 |
## Cloud Mask
|
|
152 |
execGRASS("r.in.gdal",input=paste("HDF4_EOS:EOS_GRID:\"",file,"\":mod06:Cloud_Mask_1km_0",sep=""),
|
|
153 |
output=paste("CM1_",i,sep=""),flags=c("overwrite","o")) ; print("")
|
|
154 |
## extract cloudy and 'confidently clear' pixels
|
|
155 |
system(paste("r.mapcalc <<EOF
|
|
156 |
CM_cloud_",i," = ((CM1_",i," / 2^0) % 2) == 1 && ((CM1_",i," / 2^1) % 2^2) == 0
|
|
157 |
CM_clear_",i," = ((CM1_",i," / 2^0) % 2) == 1 && ((CM1_",i," / 2^1) % 2^2) == 3
|
|
158 |
EOF",sep=""))
|
|
159 |
|
|
160 |
## QA
|
|
161 |
execGRASS("r.in.gdal",input=paste("HDF4_EOS:EOS_GRID:\"",file,"\":mod06:Quality_Assurance_1km_0",sep=""),
|
|
162 |
output=paste("QA_",i,sep=""),flags=c("overwrite","o")) ; print("")
|
|
163 |
## QA_CER
|
|
164 |
system(paste("r.mapcalc <<EOF
|
|
165 |
QA_COT_",i,"= ((QA_",i," / 2^0) % 2^1 )==1
|
|
166 |
QA_COT2_",i,"= ((QA_",i," / 2^1) % 2^2 )==3
|
|
167 |
QA_COT3_",i,"= ((QA_",i," / 2^3) % 2^2 )==0
|
|
168 |
QA_CER_",i,"= ((QA_",i," / 2^5) % 2^1 )==1
|
|
169 |
QA_CER2_",i,"= ((QA_",i," / 2^6) % 2^2 )==3
|
|
170 |
EOF",sep=""))
|
|
171 |
# QA_CWP_",i,"= ((QA_",i," / 2^8) % 2^1 )==1
|
|
172 |
# QA_CWP2_",i,"= ((QA_",i," / 2^9) % 2^2 )==3
|
|
173 |
|
|
174 |
## Optical Thickness
|
|
175 |
execGRASS("r.in.gdal",input=paste("HDF4_EOS:EOS_GRID:\"",file,"\":mod06:Cloud_Optical_Thickness",sep=""),
|
|
176 |
output=paste("COT_",i,sep=""),
|
|
177 |
title="cloud_effective_radius",
|
|
178 |
flags=c("overwrite","o")) ; print("")
|
|
179 |
execGRASS("r.null",map=paste("COT_",i,sep=""),setnull="-9999")
|
|
180 |
## keep only positive COT values where quality is 'useful' and 'very good' & scale to real units
|
|
181 |
system(paste("r.mapcalc \"COT_",i,"=if(QA_COT_",i,"&&QA_COT2_",i,"&&QA_COT3_",i,"&&COT_",i,">=0,COT_",i,"*0.009999999776482582,null())\"",sep=""))
|
|
182 |
## set COT to 0 in clear-sky pixels
|
|
183 |
system(paste("r.mapcalc \"COT2_",i,"=if(CM_clear_",i,"==0,COT_",i,",0)\"",sep=""))
|
|
184 |
|
|
185 |
## Effective radius ##
|
|
186 |
execGRASS("r.in.gdal",input=paste("HDF4_EOS:EOS_GRID:\"",file,"\":mod06:Cloud_Effective_Radius",sep=""),
|
|
187 |
output=paste("CER_",i,sep=""),
|
|
188 |
title="cloud_effective_radius",
|
|
189 |
flags=c("overwrite","o")) ; print("")
|
|
190 |
execGRASS("r.null",map=paste("CER_",i,sep=""),setnull="-9999")
|
|
191 |
## keep only positive CER values where quality is 'useful' and 'very good' & scale to real units
|
|
192 |
system(paste("r.mapcalc \"CER_",i,"=if(QA_CER_",i,"&&QA_CER2_",i,"&&CER_",i,">=0,CER_",i,"*0.009999999776482582,null())\"",sep=""))
|
|
193 |
## set CER to 0 in clear-sky pixels
|
|
194 |
system(paste("r.mapcalc \"CER2_",i,"=if(CM_clear_",i,"==0,CER_",i,",0)\"",sep=""))
|
|
195 |
|
|
196 |
## Cloud Water Path
|
|
197 |
# execGRASS("r.in.gdal",input=paste("HDF4_EOS:EOS_GRID:\"",file,"\":mod06:Cloud_Water_Path",sep=""),
|
|
198 |
# output=paste("CWP_",i,sep=""),title="cloud_water_path",
|
|
199 |
# flags=c("overwrite","o")) ; print("")
|
|
200 |
# execGRASS("r.null",map=paste("CWP_",i,sep=""),setnull="-9999")
|
|
201 |
## keep only positive CER values where quality is 'useful' and 'very good' & scale to real units
|
|
202 |
# system(paste("r.mapcalc \"CWP_",i,"=if(QA_CWP_",i,"&&QA_CWP2_",i,"&&CWP_",i,">=0,CWP_",i,"*0.009999999776482582,null())\"",sep=""))
|
|
203 |
## set CER to 0 in clear-sky pixels
|
|
204 |
# system(paste("r.mapcalc \"CWP2_",i,"=if(CM_clear_",i,"==0,CWP_",i,",0)\"",sep=""))
|
|
205 |
|
|
206 |
} #end loop through sub daily files
|
|
207 |
|
|
208 |
#### Now generate daily averages (or maximum in case of cloud flag)
|
|
209 |
|
|
210 |
system(paste("r.mapcalc <<EOF
|
|
211 |
COT_denom=",paste("!isnull(COT2_",1:nfs,")",sep="",collapse="+"),"
|
|
212 |
COT_numer=",paste("if(isnull(COT2_",1:nfs,"),0,COT2_",1:nfs,")",sep="",collapse="+"),"
|
|
213 |
COT_daily=COT_numer/COT_denom
|
|
214 |
CER_denom=",paste("!isnull(CER2_",1:nfs,")",sep="",collapse="+"),"
|
|
215 |
CER_numer=",paste("if(isnull(CER2_",1:nfs,"),0,CER2_",1:nfs,")",sep="",collapse="+"),"
|
|
216 |
CER_daily=CER_numer/CER_denom
|
|
217 |
CLD_daily=max(",paste("if(isnull(CM_cloud_",1:nfs,"),0,CM_cloud_",1:nfs,")",sep="",collapse=","),")
|
|
218 |
EOF",sep=""))
|
|
219 |
|
|
220 |
#### Write the files to a geotiff
|
|
221 |
execGRASS("r.out.gdal",input="CER_daily",output=paste(tifdir,"/CER_",format(date,"%Y%m%d"),".tif",sep=""),nodata=-999,flags=c("quiet"))
|
|
222 |
execGRASS("r.out.gdal",input="COT_daily",output=paste(tifdir,"/COT_",format(date,"%Y%m%d"),".tif",sep=""),nodata=-999,flags=c("quiet"))
|
|
223 |
execGRASS("r.out.gdal",input="CLD_daily",output=paste(tifdir,"/CLD_",format(date,"%Y%m%d"),".tif",sep=""),nodata=99,flags=c("quiet"))
|
|
224 |
|
|
225 |
### delete the temporary files
|
|
226 |
unlink_.gislock()
|
|
227 |
system("/usr/lib/grass64/etc/clean_temp")
|
|
228 |
system(paste("rm -R ",tf,sep=""))
|
|
229 |
### print update
|
|
230 |
print(paste(" ################################################################### Finished ",date,"
|
|
231 |
################################################################"))
|
|
232 |
}
|
|
233 |
|
|
234 |
|
|
235 |
###########################################
|
|
236 |
### Now run it
|
|
237 |
|
|
238 |
tdates=sort(unique(fs$date))
|
|
239 |
done=tdates%in%as.Date(substr(list.files(tifdir),5,12),"%Y%m%d")
|
|
240 |
table(done)
|
|
241 |
tdates=tdates[!done]
|
|
242 |
|
|
243 |
mclapply(tdates,function(date) loadcloud(date,fs=fs))
|
|
244 |
|
|
245 |
|
|
246 |
|
Started working with script to process MOD05 on NASA's Pleiades