Revision be0ef101
Added by Adam Wilson about 11 years ago
climate/procedures/MOD35_L2_process_alltests.r | ||
---|---|---|
1 |
################################################################################### |
|
2 |
### R code to aquire and process MOD35_L2 cloud data from the MODIS platform |
|
3 |
|
|
4 |
|
|
5 |
# Redirect all warnings to stderr() |
|
6 |
#options(warn = -1) |
|
7 |
#write("2) write() to stderr", stderr()) |
|
8 |
#write("2) write() to stdout", stdout()) |
|
9 |
#warning("2) warning()") |
|
10 |
|
|
11 |
|
|
12 |
## import commandline arguments |
|
13 |
library(getopt) |
|
14 |
## load libraries |
|
15 |
require(reshape) |
|
16 |
require(geosphere) |
|
17 |
require(raster) |
|
18 |
require(rgdal) |
|
19 |
require(spgrass6) |
|
20 |
require(RSQLite) |
|
21 |
|
|
22 |
## get options |
|
23 |
opta <- getopt(matrix(c( |
|
24 |
'date', 'd', 1, 'character', |
|
25 |
'tile', 't', 1, 'character', |
|
26 |
'verbose','v',1,'logical', |
|
27 |
'profile','p',0,'logical', |
|
28 |
'help', 'h', 0, 'logical' |
|
29 |
), ncol=4, byrow=TRUE)) |
|
30 |
if ( !is.null(opta$help) ) |
|
31 |
{ |
|
32 |
prg <- commandArgs()[1]; |
|
33 |
cat(paste("Usage: ", prg, " --date | -d <file> :: The date to process\n", sep="")); |
|
34 |
q(status=1); |
|
35 |
} |
|
36 |
|
|
37 |
testing=F |
|
38 |
platform="pleiades" |
|
39 |
|
|
40 |
## record profiling information if requested |
|
41 |
if(opta$profile) Rprof("/nobackupp1/awilso10/mod35/log/profile.out") |
|
42 |
|
|
43 |
## default date and tile to play with (will be overwritten below when running in batch) |
|
44 |
if(testing){ |
|
45 |
date="20090129" |
|
46 |
tile="h11v08" |
|
47 |
tile="h17v00" |
|
48 |
tile="h12v04" |
|
49 |
verbose=T |
|
50 |
} |
|
51 |
|
|
52 |
## now update using options if given |
|
53 |
if(!testing){ |
|
54 |
date=opta$date |
|
55 |
tile=opta$tile |
|
56 |
verbose=opta$verbose #print out extensive information for debugging? |
|
57 |
} |
|
58 |
|
|
59 |
## get year and doy from date |
|
60 |
year=format(as.Date(date,"%Y%m%d"),"%Y") |
|
61 |
doy=format(as.Date(date,"%Y%m%d"),"%j") |
|
62 |
|
|
63 |
if(platform=="pleiades"){ |
|
64 |
## location of MOD35 files |
|
65 |
datadir=paste("/nobackupp4/datapool/modis/MOD35_L2.006/",year,"/",doy,"/",sep="") |
|
66 |
## path to some executables |
|
67 |
ncopath="/nasa/sles11/nco/4.0.8/gcc/mpt/bin/" |
|
68 |
swtifpath="/nobackupp1/awilso10/software/heg/bin/swtif_2.12" |
|
69 |
# swtifpath="/nobackupp4/pvotava/software/heg/2.12/bin/swtif" |
|
70 |
## path to swath database |
|
71 |
db="/nobackupp4/pvotava/DB/export/swath_geo.sql.sqlite3.db" |
|
72 |
## specify working directory |
|
73 |
outdir=paste("/nobackupp1/awilso10/mod35/daily/",tile,"/",sep="") #directory for separate daily files |
|
74 |
basedir="/nobackupp1/awilso10/mod35/" #directory to hold files temporarily before transferring to lou |
|
75 |
setwd(tempdir()) |
|
76 |
## grass database |
|
77 |
gisBase="/u/armichae/pr/grass-6.4.2/" |
|
78 |
## path to MOD11A1 file for this tile to align grid/extent |
|
79 |
gridfile=list.files("/nobackupp1/awilso10/mod35/MODTILES/",pattern=tile,full=T)[1] |
|
80 |
td=raster(gridfile) |
|
81 |
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 " |
|
82 |
} |
|
83 |
|
|
84 |
if(platform=="litoria"){ #if running on local server, use different paths |
|
85 |
## specify working directory |
|
86 |
setwd("~/acrobates/adamw/projects/interp") |
|
87 |
outdir=paste("daily/",tile,"/",sep="") #directory for separate daily files |
|
88 |
basedir=outdir |
|
89 |
gisBase="/usr/lib/grass64" |
|
90 |
## location of MOD06 files |
|
91 |
datadir="~/acrobates/adamw/projects/interp/data/modis/mod35" |
|
92 |
## path to some executables |
|
93 |
ncopath="" |
|
94 |
swtifpath="sudo MRTDATADIR=\"/usr/local/heg/data\" PGSHOME=/usr/local/heg/TOOLKIT_MTD PWD=/home/adamw /usr/local/heg/bin/swtif" |
|
95 |
## path to swath database |
|
96 |
db="~/acrobates/adamw/projects/interp/data/modis/mod06/swath_geo.sql.sqlite3.db" |
|
97 |
## get grid file |
|
98 |
td=raster(paste("~/acrobates/adamw/projects/interp/data/modis/mod06/summary/MOD06_",tile,".nc",sep=""),varname="CER") |
|
99 |
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 " |
|
100 |
} |
|
101 |
|
|
102 |
|
|
103 |
### print some status messages |
|
104 |
if(verbose) writeLines(paste("STATUS: Beginning ",tile,date)) |
|
105 |
|
|
106 |
## load tile information and get bounding box |
|
107 |
load(file="/nobackupp1/awilso10/mod35/modlandTiles.Rdata") |
|
108 |
tile_bb=tb[tb$tile==tile,] ## identify tile of interest |
|
109 |
|
|
110 |
## get bounds of swath to keep and feed into grass when generating tile |
|
111 |
## expand a little (0.5 deg) to ensure that there is no clipping of pixels on the edges |
|
112 |
## tile will later be aligned with MODLAND tile so the extra will eventually be trimmed |
|
113 |
upleft=paste(min(90,tile_bb$lat_max+0.5),max(-180,tile_bb$lon_min-0.5)) #northwest corner |
|
114 |
lowright=paste(max(-90,tile_bb$lat_min-0.5),min(180,tile_bb$lon_max+0.5)) #southeast corner |
|
115 |
|
|
116 |
## vector of variables expected to be in final netcdf file. If these are not present, the file will be deleted at the end. |
|
117 |
finalvars=c("CMday","CMnight") |
|
118 |
|
|
119 |
|
|
120 |
##################################################### |
|
121 |
##find swaths in region from sqlite database for the specified date/tile |
|
122 |
if(verbose) print("Accessing swath ID's from database") |
|
123 |
con=dbConnect("SQLite", dbname = db) |
|
124 |
fs=dbGetQuery(con,paste("SELECT * from swath_geo6 |
|
125 |
WHERE east>=",tile_bb$lon_min," AND |
|
126 |
west<=",tile_bb$lon_max," AND |
|
127 |
north>=",tile_bb$lat_min," AND |
|
128 |
south<=",tile_bb$lat_max," AND |
|
129 |
year==",format(as.Date(date,"%Y%m%d"),"%Y")," AND |
|
130 |
day==",as.numeric(format(as.Date(date,"%Y%m%d"),"%j")) |
|
131 |
)) |
|
132 |
con=dbDisconnect(con) |
|
133 |
fs$id=substr(fs$id,7,19) |
|
134 |
## find the swaths on disk (using datadir) |
|
135 |
swaths=list.files(datadir,pattern=paste(fs$id,collapse="|"),recursive=T,full=T) |
|
136 |
|
|
137 |
### print some status messages |
|
138 |
if(verbose) writeLines(paste("STATUS:swaths tile:",tile,"date:",date,"swathIDs:",nrow(fs)," swathsOnDisk:",length(swaths))) |
|
139 |
|
|
140 |
|
|
141 |
## define function that grids swaths |
|
142 |
swtif<-function(file,var){ |
|
143 |
outfile=paste(tempdir(),"/",var$varid,"_",basename(file),sep="") #gridded path |
|
144 |
## First write the parameter file (careful, heg is very finicky!) |
|
145 |
hdr=paste("NUM_RUNS = 1") |
|
146 |
grp=paste(" |
|
147 |
BEGIN |
|
148 |
INPUT_FILENAME=",file," |
|
149 |
OBJECT_NAME=mod35 |
|
150 |
FIELD_NAME=",var$variable,"| |
|
151 |
BAND_NUMBER = ",var$band," |
|
152 |
OUTPUT_PIXEL_SIZE_X=926.6 |
|
153 |
OUTPUT_PIXEL_SIZE_Y=926.6 |
|
154 |
# MODIS 1km Resolution |
|
155 |
SPATIAL_SUBSET_UL_CORNER = ( ",upleft," ) |
|
156 |
SPATIAL_SUBSET_LR_CORNER = ( ",lowright," ) |
|
157 |
RESAMPLING_TYPE =",var$method," |
|
158 |
OUTPUT_PROJECTION_TYPE = SIN |
|
159 |
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 ) |
|
160 |
# projection parameters from http://landweb.nascom.nasa.gov/cgi-bin/QA_WWW/newPage.cgi?fileName=sn_gctp |
|
161 |
ELLIPSOID_CODE = WGS84 |
|
162 |
OUTPUT_TYPE = HDFEOS |
|
163 |
OUTPUT_FILENAME = ",outfile," |
|
164 |
END |
|
165 |
",sep="") |
|
166 |
## write it to a file |
|
167 |
cat(c(hdr,grp) , file=paste(tempdir(),"/",basename(file),"_MODparms.txt",sep="")) |
|
168 |
## now run the swath2grid tool |
|
169 |
## write the gridded file |
|
170 |
system(paste(swtifpath," -p ",tempdir(),"/",basename(file),"_MODparms.txt -d -tmpLatLondir ",tempdir(),sep=""),intern=F,ignore.stderr=F) |
|
171 |
print(paste("Finished processing variable",var$variable,"from ",basename(file),"to",outfile)) |
|
172 |
} |
|
173 |
|
|
174 |
## vars to grid |
|
175 |
vars=as.data.frame(matrix(c( |
|
176 |
"Cloud_Mask", "CM", "NN", 1, |
|
177 |
"Cloud_Mask", "CM2", "NN", 2, |
|
178 |
"Cloud_Mask", "CM3", "NN", 3, |
|
179 |
"Cloud_Mask", "CM4", "NN", 4, |
|
180 |
"Quality_Assurance", "QA", "NN", 1, |
|
181 |
"Quality_Assurance", "QA2", "NN", 2, |
|
182 |
"Quality_Assurance", "QA3", "NN", 3, |
|
183 |
"Quality_Assurance", "QA4", "NN", 4, |
|
184 |
"Solar_Zenith", "SolZen", "NN", 1, |
|
185 |
"Sensor_Zenith", "SenZen", "CUBIC", 1 |
|
186 |
), |
|
187 |
byrow=T,ncol=4,dimnames=list(1:10,c("variable","varid","method","band"))),stringsAsFactors=F) |
|
188 |
|
|
189 |
|
|
190 |
############################################################################ |
|
191 |
############################################################################ |
|
192 |
### Use the HEG tool to grid all available swath data for this date-tile |
|
193 |
for(file in swaths){ |
|
194 |
print(paste("Starting file",basename(file))) |
|
195 |
## run swtif for each band |
|
196 |
lapply(1:nrow(vars),function(i) swtif(file,vars[i,])) |
|
197 |
} #end looping over swaths |
|
198 |
|
|
199 |
|
|
200 |
############################################################################# |
|
201 |
## check for zero dimension in HDFs |
|
202 |
## occasionlly swtif will output a hdf with a resolution of 0. Not sure why, but drop them here. |
|
203 |
CMcheck=list.files(pattern="CM_.*hdf$") #list of files to check |
|
204 |
CM_0=do.call(c,lapply(CMcheck, function(f) any(res(raster(f))==0))) |
|
205 |
keep=sub("CM_","",CMcheck[!CM_0]) |
|
206 |
if(length(keep)<length(CMcheck)){writeLines(paste("Warning (Resolution of zero): ",paste(sub("CM_","",CMcheck)[!sub("CM_","",CMcheck)%in%keep],collapse=",")," from ",tile," for ",date))} |
|
207 |
outfiles=list.files(tempdir(),full=T,pattern=paste(keep,"$",sep="",collapse="|")) |
|
208 |
if(length(outfiles)==0) { |
|
209 |
print(paste("######################################## No gridded files for region exist for tile",tile," on date",date)) |
|
210 |
q("no",status=0) |
|
211 |
} |
|
212 |
|
|
213 |
plot=F |
|
214 |
if(plot){ |
|
215 |
i=1 |
|
216 |
system(paste("gdalinfo ",outfiles[19])) |
|
217 |
d=lapply(outfiles,function(r) raster(r)) |
|
218 |
summary(d[[6]]) |
|
219 |
} |
|
220 |
#system(paste("scp ",outfiles[1]," adamw@acrobates.eeb.yale.edu:/data/personal/adamw/projects/interp/tmp/",sep="")) |
|
221 |
|
|
222 |
##################################################### |
|
223 |
## Process the gridded files to align exactly with MODLAND tile and produce a daily summary of multiple swaths |
|
224 |
|
|
225 |
## function to convert binary to decimal to assist in identifying correct values |
|
226 |
## this is helpful when defining QA handling below, but isn't used in processing |
|
227 |
## b2d=function(x) sum(x * 2^(rev(seq_along(x)) - 1)) #http://tolstoy.newcastle.edu.au/R/e2/help/07/02/10596.html |
|
228 |
## for example: |
|
229 |
## b2d(c(T,T)) |
|
230 |
|
|
231 |
## set Grass to overwrite |
|
232 |
Sys.setenv(GRASS_OVERWRITE=1) |
|
233 |
Sys.setenv(DEBUG=1) |
|
234 |
Sys.setenv(GRASS_GUI="txt") |
|
235 |
|
|
236 |
### Extract various SDSs from a single gridded HDF file and use QA data to throw out 'bad' observations |
|
237 |
## make temporary working directory |
|
238 |
tf=paste(tempdir(),"/grass", Sys.getpid(),"/", sep="") #temporar |
|
239 |
if(!file.exists(tf)) dir.create(tf) |
|
240 |
## create output directory if needed |
|
241 |
## Identify output file |
|
242 |
ncfile=paste(outdir,"MOD35_alltests_",tile,"_",date,".nc",sep="") #this is the 'final' daily output file |
|
243 |
if(!file.exists(dirname(ncfile))) dir.create(dirname(ncfile),recursive=T) |
|
244 |
|
|
245 |
## set up temporary grass instance for this PID |
|
246 |
if(verbose) print(paste("Set up temporary grass session in",tf)) |
|
247 |
initGRASS(gisBase=gisBase,gisDbase=tf,SG=as(td,"SpatialGridDataFrame"),override=T,location="mod35",mapset="PERMANENT",home=tf,pid=Sys.getpid()) |
|
248 |
system(paste("g.proj -c proj4=\"",projection(td),"\"",sep=""),ignore.stdout=T,ignore.stderr=T) |
|
249 |
|
|
250 |
## Define region by importing one MOD11A1 raster. |
|
251 |
print("Import one MOD11A1 raster to define grid") |
|
252 |
if(platform=="pleiades") { |
|
253 |
execGRASS("r.in.gdal",input=td@file@name,output="modisgrid",flags=c("quiet","overwrite","o")) |
|
254 |
system("g.region rast=modisgrid save=roi --overwrite",ignore.stdout=F,ignore.stderr=F) |
|
255 |
} |
|
256 |
|
|
257 |
if(platform=="litoria"){ |
|
258 |
execGRASS("r.in.gdal",input=paste("NETCDF:\"/home/adamw/acrobates/adamw/projects/interp/data/modis/mod06/summary/MOD06_",tile,".nc\":CER",sep=""), |
|
259 |
output="modisgrid",flags=c("overwrite","o")) |
|
260 |
system("g.region rast=modisgrid.1 save=roi --overwrite",ignore.stdout=F,ignore.stderr=F) |
|
261 |
} |
|
262 |
|
|
263 |
## Identify which files to process |
|
264 |
tfs=unique(sub("^.*[_]","MOD35_",basename(outfiles))) |
|
265 |
#tfs=list.files(tempdir(),pattern="temp.*hdf") |
|
266 |
nfs=length(tfs) |
|
267 |
if(verbose) print(paste(nfs,"swaths available for processing")) |
|
268 |
|
|
269 |
## single test matrix - links tests with their applied status |
|
270 |
flags=as.data.frame(matrix(c( |
|
271 |
"non_cloud_obstruction", "CM2", 0, "QA2", 0, |
|
272 |
"thin_cirrus_solar", "CM2", 1, "QA2", 1, |
|
273 |
"shadow", "CM2", 2, "QA2", 2, |
|
274 |
"thin_cirrus_ir", "CM2", 3, "QA2", 3, |
|
275 |
"cloud_adjacency_ir", "CM2", 4, "QA2", 4, |
|
276 |
"ir_threshold", "CM2", 5, "QA2", 5, |
|
277 |
"high_cloud_co2", "CM2", 6, "QA2", 6, |
|
278 |
"high_cloud_67", "CM2", 7, "QA2", 7, |
|
279 |
"high_cloud_138", "CM3", 0, "QA3", 0, |
|
280 |
"high_cloud_37_12", "CM3", 1, "QA3", 1, |
|
281 |
"cloud_ir_difference", "CM3", 2, "QA3", 2, |
|
282 |
"cloud_37_11", "CM3", 3, "QA3", 3, |
|
283 |
"cloud_visible", "CM3", 4, "QA3", 4, |
|
284 |
"cloud_visible_ratio", "CM3", 5, "QA3", 5, |
|
285 |
"cloud_ndvi", "CM3", 6, "QA3", 6, |
|
286 |
"cloud_night_73_11", "CM3", 7, "QA3", 7 |
|
287 |
), |
|
288 |
byrow=T,ncol=5,dimnames=list(1:16,c("variable","CMband","CMbit","QAband","QAbit"))),stringsAsFactors=F) |
|
289 |
|
|
290 |
|
|
291 |
## loop through scenes and process QA flags |
|
292 |
for(i in 1:nfs){ |
|
293 |
bfile=tfs[i] |
|
294 |
## Read in the data from the HDFs |
|
295 |
## Cloud Mask |
|
296 |
GDALinfo(paste("CM_",bfile,sep=""),returnStats=F,silent=T) |
|
297 |
execGRASS("r.in.gdal",input=paste("CM_",bfile,sep=""), |
|
298 |
output=paste("CM1_",i,sep=""),flags=c("overwrite","o")) ; print("") |
|
299 |
## QA ## extract first bit to keep only "useful" values of cloud mask |
|
300 |
execGRASS("r.in.gdal",input=paste("QA_",bfile,sep=""), |
|
301 |
output=paste("QA_",i,sep=""),flags=c("overwrite","o")) ; print("") |
|
302 |
## for all CMs and QAs in flags table, import them |
|
303 |
for(c in c(unique(flags$CMband),unique(flags$QAband))) |
|
304 |
execGRASS("r.in.gdal",input=paste(c,"_",bfile,sep=""), |
|
305 |
output=paste(c,"_",i,sep=""),flags=c("overwrite","o")) ; print("") |
|
306 |
## Sensor Zenith ## extract first bit to keep only "low angle" observations |
|
307 |
execGRASS("r.in.gdal",input=paste("SenZen_",bfile,sep=""), |
|
308 |
output=paste("SZ_",i,sep=""),flags=c("overwrite","o")) ; print("") |
|
309 |
## Solar Zenith ## extract first bit to keep only "low angle" observations |
|
310 |
execGRASS("r.in.gdal",input=paste("SolZen_",bfile,sep=""), |
|
311 |
output=paste("SoZ_",i,sep=""),flags=c("overwrite","o")) ; print("") |
|
312 |
## produce the summaries |
|
313 |
system(paste("r.mapcalc <<EOF |
|
314 |
CM_fill_",i," = if(isnull(CM1_",i,"),1,0) |
|
315 |
QA_useful_",i," = if((QA_",i," / 2^0) % 2==1,1,0) |
|
316 |
SZ_low_",i," = if(SZ_",i,"<6000,1,0) |
|
317 |
SoZ_low_",i," = if(SoZ_",i,"<8500,1,0) |
|
318 |
CM_dayflag_",i," = if((CM1_",i," / 2^3) % 2==1,1,0) |
|
319 |
CM_cloud_",i," = if((CM1_",i," / 2^0) % 2==1,(CM1_",i," / 2^1) % 2^2,null()) |
|
320 |
SZday_",i," = if(CM_dayflag_",i,"==1,SZ_",i,",null()) |
|
321 |
SZnight_",i," = if(CM_dayflag_",i,"==0,SZ_",i,",null()) |
|
322 |
CMday_",i," = if(SoZ_low_",i,"==1&SZ_low_",i,"==1&QA_useful_",i,"==1&CM_dayflag_",i,"==1,CM_cloud_",i,",null()) |
|
323 |
CMnight_",i," = if(SZ_low_",i,"==1&QA_useful_",i,"==1&CM_dayflag_",i,"==0,CM_cloud_",i,",null()) |
|
324 |
EOF",sep="")) |
|
325 |
## produce test by test summaries |
|
326 |
for(n in 1:nrow(flags)) |
|
327 |
system(paste("r.mapcalc '", |
|
328 |
flags$variable[n],"_",i,"=if((",flags$QAband[n],"_",i," / 2^", |
|
329 |
flags$QAbit[n],") % 2==1&SZ_low_",i,"==1&QA_useful_",i,"==1,(",flags$CMband[n],"_",i," / 2^",flags$CMbit[n],") % 2,null())'",sep="")) |
|
330 |
|
|
331 |
|
|
332 |
drawplot=F |
|
333 |
if(drawplot){ |
|
334 |
d2=stack(lapply(paste( |
|
335 |
c("QA_useful","CM1","CM_cloud","SZ",flags$variable), |
|
336 |
"_",i,sep=""),function(x) raster(readRAST6(x)))) |
|
337 |
|
|
338 |
|
|
339 |
plot(d2,add=F) |
|
340 |
} |
|
341 |
|
|
342 |
|
|
343 |
} #end loop through sub daily files |
|
344 |
|
|
345 |
## select lowest view angle |
|
346 |
## use r.series to find minimum |
|
347 |
system(paste("r.series input=",paste("SZnight_",1:nfs,sep="",collapse=",")," output=SZnight_min method=min_raster",sep="")) |
|
348 |
system(paste("r.series input=",paste("SZday_",1:nfs,sep="",collapse=",")," output=SZday_min method=min_raster",sep="")) |
|
349 |
## select cloud observation with lowest sensor zenith for day and night |
|
350 |
system( |
|
351 |
paste("r.mapcalc <<EOF |
|
352 |
CMday_daily=",paste(paste("if((SZday_min+1)==",1:nfs,",CMday_",1:nfs,",",sep="",collapse=" "),"null()",paste(rep(")",times=nfs),sep="",collapse=""))," |
|
353 |
CMnight_daily=",paste(paste("if((SZnight_min+1)==",1:nfs,",CMnight_",1:nfs,",",sep="",collapse=" "),"null()",paste(rep(")",times=nfs),sep="",collapse="")))) |
|
354 |
|
|
355 |
## test-by-test summaries |
|
356 |
for(n in 1:nrow(flags)) |
|
357 |
system( |
|
358 |
paste("r.mapcalc <<EOF |
|
359 |
",flags$variable[n],"_daily=", |
|
360 |
paste(paste("if((SZday_min+1)==",1:nfs,", ",flags$variable[n],"_",1:nfs,",",sep="",collapse=" "),"null()",paste(rep(")",times=nfs),sep="",collapse="")),sep="")) |
|
361 |
|
|
362 |
execGRASS("r.null",map="CMday_daily",setnull="255") ; print("") |
|
363 |
execGRASS("r.null",map="CMnight_daily",setnull="255") ; print("") |
|
364 |
|
|
365 |
if(plot){ |
|
366 |
ps=1:nfs |
|
367 |
ps=c(10,11,13,14) |
|
368 |
sz1=brick(lapply(ps,function(i) raster(readRAST6(paste("SZday_",i,sep=""))))) |
|
369 |
d=brick(lapply(ps,function(i) raster(readRAST6(paste("CMday_",i,sep=""))))) |
|
370 |
d2=brick(list(raster(readRAST6("SZday_min")),raster(readRAST6("SZnight_min")),raster(readRAST6("CMday_daily")),raster(readRAST6("CMnight_daily")))) |
|
371 |
d3=stack(lapply(c("SZday_min","CMday_daily",paste(flags$variable, |
|
372 |
"_daily",sep="")),function(x) raster(readRAST6(x)))) |
|
373 |
|
|
374 |
library(rasterVis) |
|
375 |
levelplot(sz1,col.regions=rainbow(100),at=seq(min(sz1@data@min),max(sz1@data@max),len=100)) |
|
376 |
levelplot(d) |
|
377 |
levelplot(d2) |
|
378 |
plot(d3) |
|
379 |
} |
|
380 |
|
|
381 |
|
|
382 |
### Write the files to a netcdf file |
|
383 |
## create image group to facilitate export as multiband netcdf |
|
384 |
ebands=c("CMday_daily","CMnight_daily",paste(flags$variable,"_daily",sep="")) |
|
385 |
execGRASS("i.group",group="mod35",input=ebands,flags=c("quiet")) ; print("") |
|
386 |
|
|
387 |
if(file.exists(ncfile)) file.remove(ncfile) #if it exists already, delete it |
|
388 |
execGRASS("r.out.gdal",input="mod35",output=ncfile,type="Byte",nodata=255,flags=c("verbose"), |
|
389 |
# createopt=c("FORMAT=NC4","ZLEVEL=5","COMPRESS=DEFLATE","WRITE_GDAL_TAGS=YES","WRITE_LONLAT=NO"),format="netCDF") #for compressed netcdf |
|
390 |
createopt=c("FORMAT=NC","WRITE_GDAL_TAGS=YES","WRITE_LONLAT=NO"),format="netCDF") |
|
391 |
|
|
392 |
system(paste(ncopath,"ncecat -O -u time ",ncfile," ",ncfile,sep="")) |
|
393 |
## create temporary nc file with time information to append to MOD06 data |
|
394 |
cat(paste(" |
|
395 |
netcdf time { |
|
396 |
dimensions: |
|
397 |
time = 1 ; |
|
398 |
variables: |
|
399 |
int time(time) ; |
|
400 |
time:units = \"days since 2000-01-01 00:00:00\" ; |
|
401 |
time:calendar = \"gregorian\"; |
|
402 |
time:long_name = \"time of observation\"; |
|
403 |
data: |
|
404 |
time=",as.integer(as.Date(date,"%Y%m%d")-as.Date("2000-01-01")),"; |
|
405 |
}"),file=paste(tempdir(),"/time.cdl",sep="")) |
|
406 |
system(paste("ncgen -o ",tempdir(),"/time.nc ",tempdir(),"/time.cdl",sep="")) |
|
407 |
system(paste(ncopath,"ncks -A ",tempdir(),"/time.nc ",ncfile,sep="")) |
|
408 |
## add other attributes |
|
409 |
## need to delete _FillValue becuase r.out.gdal incorrectly calls zero values missing if there are no other missing values in the raster. |
|
410 |
## so need to delete then re-add. If you just change the value, ncatted will change the values in the raster in addition to the attribute. |
|
411 |
system(paste(ncopath,"ncrename -v ",paste("Band",1:length(ebands),",",sub("_daily","",ebands),sep="",collapse=" -v ")," ",ncfile,sep="")) |
|
412 |
|
|
413 |
system(paste(ncopath,"ncatted ", |
|
414 |
" -a units,CMday,o,c,\"Cloud Flag (0-3)\" ", |
|
415 |
" -a missing_value,CMday,o,b,255 ", |
|
416 |
" -a _FillValue,CMday,d,, ", |
|
417 |
" -a valid_range,CMday,o,b,\"0,3\" ", |
|
418 |
" -a long_name,CMday,o,c,\"Cloud Flag from day pixels\" ", |
|
419 |
" -a units,CMnight,o,c,\"Cloud Flag (0-3)\" ", |
|
420 |
" -a missing_value,CMnight,o,b,255 ", |
|
421 |
" -a _FillValue,CMnight,d,, ", |
|
422 |
" -a valid_range,CMnight,o,b,\"0,3\" ", |
|
423 |
" -a long_name,CMnight,o,c,\"Cloud Flag from night pixels\" ", |
|
424 |
ncfile,sep="")) |
|
425 |
## add the fillvalue attribute back (without changing the actual values) |
|
426 |
system(paste(ncopath,"ncatted -a _FillValue,CMday,o,b,255 ",ncfile,sep="")) |
|
427 |
system(paste(ncopath,"ncatted -a _FillValue,CMnight,o,b,255 ",ncfile,sep="")) |
|
428 |
|
|
429 |
for(p in 1:nrow(flags)){ |
|
430 |
system(paste(ncopath,"ncatted ", |
|
431 |
" -a units,",flags$variable[p],",o,c,\"Cloud Flag (0-1)\" ", |
|
432 |
" -a missing_value,",flags$variable[p],",o,b,255 ", |
|
433 |
" -a _FillValue,",flags$variable[p],",d,, ", |
|
434 |
" -a valid_range,",flags$variable[p],",o,b,\"0,1\" ", |
|
435 |
" -a long_name,",flags$variable[p],",o,c,",flags$variable[p]," ", |
|
436 |
ncfile,sep="")) |
|
437 |
## add the fillvalue attribute back (without changing the actual values) |
|
438 |
system(paste(ncopath,"ncatted -a _FillValue,",flags$variable[p],",o,b,255 ",ncfile,sep="")) |
|
439 |
system(paste(ncopath,"ncatted -a _FillValue,",flags$variable[p],",o,b,255 ",ncfile,sep="")) |
|
440 |
} |
|
441 |
|
|
442 |
## Confirm that the file has the correct attributes, otherwise delete it |
|
443 |
ntime=as.numeric(system(paste("cdo -s ntime ",ncfile),intern=T)) |
|
444 |
## confirm it has all 'final variables as specified above" |
|
445 |
fvar=all(finalvars%in%strsplit(system(paste("cdo -s showvar ",ncfile),intern=T)," ")[[1]]) |
|
446 |
|
|
447 |
if(ntime!=1|!fvar) { |
|
448 |
print(paste("FILE ERROR: tile ",tile," and date ",date," was not outputted correctly, deleting... ")) |
|
449 |
file.remove(ncfile) |
|
450 |
} |
|
451 |
############ copy files to lou |
|
452 |
#if(platform=="pleiades"){ |
|
453 |
# archivedir=paste("MOD35/",outdir,"/",sep="") #directory to create on lou |
|
454 |
# system(paste("ssh -q bridge2 \"ssh -q lou mkdir -p ",archivedir,"\"",sep="")) |
|
455 |
# system(paste("ssh -q bridge2 \"scp -q ",ncfile," lou:",archivedir,"\"",sep="")) |
|
456 |
# file.remove(ncfile) |
|
457 |
# file.remove(paste(ncfile,".aux.xml",sep="")) |
|
458 |
#} |
|
459 |
|
|
460 |
|
|
461 |
### delete the temporary files |
|
462 |
# unlink_.gislock() |
|
463 |
# system(paste("rm -frR ",tempdir(),sep="")) |
|
464 |
|
|
465 |
|
|
466 |
### print some status messages |
|
467 |
if(verbose) writeLines(paste("STATUS:end tile:",tile,"date:",date,"swathIDs:",nrow(fs)," swathsOnDisk:",length(swaths),"fileExists:",file.exists(ncfile))) |
|
468 |
|
|
469 |
## turn off the profiler |
|
470 |
if(opta$profile) Rprof(NULL) |
|
471 |
|
|
472 |
|
|
473 |
## quit |
|
474 |
q("no",status=0) |
Also available in: Unified diff
Added script to extract each separate cloud test from MOD35. This is done to explore which tests are leading to coastal artefacts in the summarized data