Project

General

Profile

« Previous | Next » 

Revision e5cf164a

Added by Adam Wilson almost 11 years ago

udpated 2_bias to add aqua processing window correction

View differences:

climate/research/cloud/MOD09/2_bias.R
5 5
library(foreach)
6 6
library(RcppOctave)
7 7
library(rgdal)
8
registerDoMC(7)
8
registerDoMC(15)
9 9

  
10 10

  
11 11
# final output will be written to data directory here:
12
setwd("~/acrobates/adamw/projects/cloud")
12
setwd("/mnt/data/personal/adamw/projects/cloud")
13 13

  
14 14
# temporary files will be written here:
15 15
datadir="/mnt/data2/projects/cloud/"
16 16

  
17 17

  
18 18
## Specify path to VSNR souce code and add it to RcppOctave path
19
mpath="/home/adamw/acrobates/adamw/projects/environmental-layers/climate/research/cloud/MOD09/vsnr/"
19
mpath="/mnt/data/personal/adamw/projects/environmental-layers/climate/research/cloud/MOD09/vsnr/"
20 20
.O$addpath(mpath)
21 21

  
22 22

  
......
46 46
    d2=as.matrix(d)
47 47
    d2[is.na(d2)]=0
48 48
    ## Process with VSNR
49
    dt=.CallOctave("VSNR",d2,epsilon,p,as.matrix(gabor),alpha,maxit+1,prec,C1,argout ="u",verbose=T);
49
    dt=.CallOctave("VSNR",d2,epsilon,p,as.matrix(gabor),alpha,maxit+1,prec,C1,argout ="u",verbose=F);
50 50
    ## Create spatial objects from VSNR output
51 51
    dc=d
52 52
    values(dc)=as.numeric(t(dt$u))  # Make 'corrected' version of data
53 53
    ##  Set NA values in original data back to NA 
54 54
    dc[is.na(d)]=NA
55
    ## remove temp files
56
    rm(d2)
57
    ## return the corrected data
55 58
    return(dc)
56 59
}
57 60

  
......
76 79
    exts=expand.grid(xmin=xmins,ymin=ymins)
77 80
    exts$ymax=exts$ymin+size
78 81
    exts$xmax=exts$xmin+size
82
    exts$tile=1:nrow(exts)
79 83
    return(exts)
80 84
}
81 85

  
82
df2=list.files(paste(datadir,"/mcd09tif",sep=""),full=T,pattern="[0-9][.]tif$")
86

  
83 87
i=1
84 88
ti=7
85

  
86
### Build the tiles
89
### Build the tiles to process
87 90
exts=extf(xmin=-180,xmax=180,ymin=-30,ymax=30,size=60,overlap=0)
88 91

  
89 92
## add an extra tile to account for regions of reduced data availability for each sensor
90
modexts=c(xmin=130,xmax=180,ymin=-50,ymax=0)
91
mydexts=c(xmin=-170,xmax=-140,ymin=-30,ymax=55)
93
modexts=cbind.data.frame(sensor="MOD09",rbind.data.frame(
94
                             exts,
95
                             c(xmin=130,ymin=-50,ymax=-25,xmax=180,tile=nrow(exts)+1),
96
                             c(xmin=130,ymin=-25,ymax=0,xmax=180,tile=nrow(exts)+2)))
97
mydexts=cbind.data.frame(sensor="MYD09",rbind.data.frame(
98
                             exts,
99
                             c(xmin=-170,ymin=-30,ymax=0,xmax=-140,tile=nrow(exts)+1),
100
                             c(xmin=-170,ymin=0,ymax=55,xmax=-140,tile=nrow(exts)+2)))
92 101

  
102
allexts=rbind.data.frame(modexts,mydexts)
93 103

  
94
## loop over sensor-months to create full grid of corrected values
95
for( i in 1:nrow(df2))){
96
    file=df2[i]
97
    outfile=paste(datadir,"/mcd09ctif/",basename(file),sep="")
98
#    outfile2=paste("data/mcd09tif/",basename(file),sep="")
99
#    outfile2b=paste("data/mcd09tif/",sub("[.]tif","_sd.tif",basename(file)),sep="")
104
### assemble list of files to process
105
df2=data.frame(path=list.files(paste(datadir,"/mcd09tif",sep=""),full=T,pattern="[0-9][.]tif$"),stringsAsFactors=F)
106
df2[,c("sensor","month")]=do.call(rbind.data.frame,strsplit(basename(df2$path),"_|[.]"))[,c(1,2)]
107

  
108
## create a list of jobs to process
109
jobs=data.frame(allexts,month=rep(sprintf("%02d",1:12),each=nrow(allexts)))
110
jobs$path=df2$path[match(paste(jobs$sensor,jobs$month),paste(df2$sensor,df2$month))]
100 111

  
101
## set sensor-specific parameters
112

  
113
## loop over sensor-months to create full grid of corrected values
114
foreach( i=1:nrow(jobs)) %dopar% {
115
    file=jobs$path[i]
116
    toutfile=paste(datadir,"mcd09bias/", sub(".tif","",basename(file)),"_",jobs$tile[i],".tif",sep="")
117
    if(file.exists(toutfile)) {writeLines(paste(toutfile,"Exists, moving on"));next}
118
    writeLines(paste("Starting: ",toutfile," tile:",jobs$tile[i]," ( ",i," out of ",nrow(jobs),")"))
119
    ## set sensor-specific parameters
102 120
    ## add extra region for correction depending on which sensor is being processed
103 121
    ## set angle of orbital artefacts to be corrected
104
    sensor=ifelse(grepl("MOD",file),"MOD","MYD")
105
    if(sensor=="MOD") {
106
        exts=rbind(exts,modexts)
107
        scanangle=-15
108
    }
109
    if(sensor=="MYD") {
110
        exts=rbind(exts,mydexts)
111
        scanangle=15
112
    }
113

  
122
    sensor=jobs$sensor[i]
123
    if(sensor=="MOD09") scanangle=-15
124
    if(sensor=="MYD09") scanangle=15
114 125
    ## Process the tiles
115
    foreach(ti=1:nrow(exts)) %dopar% {
116
        textent=extent(exts$xmin[ti],exts$xmax[ti],exts$ymin[ti],exts$ymax[ti])
117
        ## extract the tile
118
        toutfile=paste("tmp/", sub(".tif","",basename(file)),"_",sprintf("%03d",ti),".tif",sep="")
119
        writeLines(paste("Starting: ",toutfile," tile:",ti," ( out of ",nrow(exts),")"))
120
        d=crop(raster(file),textent)
121
        ## acount for scale of data is 10000*CF
122
        d=d*.01
123
        ## skip null tiles - will only have this if tiles are quite small (<10 degrees)
124
        if(is.null(d@data@values)) return(NULL)
125
        ## make the gabor kernel
126
        ## this specifies the 'shape' of the noise we are trying to remove
127
        psi=fgabor(d,theta=scanangle,x=400,y=4) #3
128
#        psi=stack(lapply(scanangle,function(a) fgabor(d,theta=a,x=400,y=4))) #3
129

  
130
        ## run the correction function.  
131
        res=vsnr(d,gabor=psi,alpha=2,p=2,epsilon=1,prec=5e-6,maxit=50,C=1,full=F)
132
        ## write the file
133
        if(!is.null(outfile)) writeRaster(res*100,file=toutfile,overwrite=T,datatype='INT2S',options=c("COMPRESS=LZW", "PREDICTOR=2"),NAvalue=-32768)
134
        ## remove temporary files
135
        rmr(d);rmr(psi);rmr(res)
136
        print(paste("Finished Temporary File: ",toutfile))
137
    }
138
## create VRT of first band of the full image 
139
fvrt=sub("[.]tif","_cf.vrt",file)
140
system(paste("gdalbuildvrt -b 1 ",fvrt," ",file))
141
## mosaic the tiles with the original data (keeping the new data when available)
142
tfiles=paste(c(fvrt,list.files("tmp",pattern=paste(sub("[.]tif","",basename(outfile)),"_[0-9]*[.]tif",sep=""),full=T)),collapse=" ")
143
system(paste("gdal_merge.py -init -32768 -n -32768 -co COMPRESS=LZW -co PREDICTOR=2 -co BIGTIFF=yes  -o ",outfile," ",tfiles,sep="")) 
126
    textent=extent(jobs$xmin[i],jobs$xmax[i],jobs$ymin[i],jobs$ymax[i])
127
    ## extract the tile
128
    ## extract the data
129
    d=crop(raster(file),textent)
130
    ## acount for scale of data is 10000*CF, so convert to 0-100
131
    d2=d*.01
132
    ## skip null tiles - will only have this if tiles are quite small (<10 degrees)
133
    if(is.null(d2@data@values)) return(NULL)
134
    ## make the gabor kernel
135
    ## this specifies the 'shape' of the noise we are trying to remove
136
    psi=fgabor(d2,theta=scanangle,x=400,y=4) #3
137
    ## run the correction function.  
138
    res=vsnr(d2,gabor=psi,alpha=2,p=2,epsilon=1,prec=5e-6,maxit=50,C=1,full=F)
139
    res2=res*100
140
    ## write the file
141
    writeRaster(res2,file=toutfile,overwrite=T,datatype='INT2S',options=c("COMPRESS=LZW", "PREDICTOR=2"),NAvalue=-32768)
142
    ## remove temporary files
143
    rmr(d);rmr(d2);rmr(psi);rmr(res);rmr(res2)
144
    print(paste("Finished Temporary File: ",toutfile))
144 145
}
145 146

  
146 147

  
147
################################################################################
148
###  calculate monthly means of terra and aqua
149

  
150
# Create combined (MOD+MYD) uncorrected mean CF
151
    foreach(i=1:12) %dopar% {
152
        ## get files
153
        f=list.files(paste(datadir,"/mcd09ctif",sep=""),pattern=paste(".*[O|Y].*_",sprintf("%02d",i),"[.]tif$",sep=""),full=T)
154
        ## Define output and check if it already exists
155
        tmcd=paste(datadir,"/mcd09ctif/MCD09_",sprintf("%02d", i),".tif",sep="")
156
        ## check if output already exists
157
        ops=paste("-t_srs 'EPSG:4326' -multi -srcnodata -32768 -dstnodata -32768 -r bilinear -te -180 -90 180 90 -tr 0.008333333333333 -0.008333333333333",
158
            "-co BIGTIFF=YES  --config GDAL_CACHEMAX 500 -wm 500 -wo NUM_THREADS:10 -wo SOURCE_EXTRA=5")
159
        system(paste("gdalwarp -overwrite -r average -co COMPRESS=LZW -co ZLEVEL=9  ",ops," ",paste(f,collapse=" ")," ",tmcd))
160
        ## update metadata
161
        tags=c(paste("TIFFTAG_IMAGEDESCRIPTION='Monthly Cloud Frequency for 2000-2013 extracted from C5 MODIS MOD09GA and MYD09GA PGE11 internal cloud mask algorithm (embedded in state_1km bit 10).",
162
            "The daily cloud mask time series were summarized to mean cloud frequency (CF) by calculating the proportion of cloudy days. ",
163
            "Band Descriptions: 1) Mean Monthly Cloud Frequency 2) Four Times the Standard Deviation of Mean Monthly Cloud Frequency"'"),
164
            "TIFFTAG_DOCUMENTNAME='Collection 5 MCD09 Cloud Frequency'",
165
            paste("TIFFTAG_DATETIME='2013",sprintf("%02d", i),"15'",sep=""),
166
              "TIFFTAG_ARTIST='Adam M. Wilson (adam.wilson@yale.edu)'")
167
        system(paste("/usr/local/src/gdal-1.10.0/swig/python/scripts/gdal_edit.py ",tmcd," ",paste("-mo ",tags,sep="",collapse=" "),sep=""))
168
        writeLines(paste("Finished month",i))
169
    }
148

  
149
############################################
150
## now mosaic the tiles with the original image to keep only the corrected data (when available) and the uncorrected data where there is no tile.
151
## this relies on df2 created above
152

  
153
foreach( i=1:nrow(df2)) %dopar% {
154
    ifile=df2$path[i]
155
    outfile=paste(datadir,"/mcd09ctif/",df2$sensor[i],"_",df2$month[i],".tif",sep="")
156
    if(file.exists(outfile)) next
157
    ## create VRT of first band of the full image 
158
    fvrt=sub("[.]tif",".vrt",ifile)
159
    system(paste("gdalbuildvrt -b 1 ",fvrt," ",ifile))
160
    ## mosaic the tiles with the original data (keeping the new data when available)
161
    tfiles=paste(c(fvrt,list.files(paste(datadir,"/mcd09bias",sep=""),pattern=paste(sub("[.]tif","",basename(outfile)),"_[0-9]*[.]tif",sep=""),full=T)),collapse=" ")
162
    if(file.exists(outfile)) file.remove(outfile)
163
    system(paste("gdal_merge.py --config GDAL_CACHEMAX 10000 -init -32768 -n -32768 -co COMPRESS=LZW -co PREDICTOR=2 -co BIGTIFF=yes  -o ",outfile," ",tfiles,sep="")) 
164
    writeLines(paste("Finished ",outfile))
165
}
170 166

  
171 167

  
172 168

  
climate/research/cloud/MOD09/3_combine.R
4 4
datadir="/mnt/data2/projects/cloud/"
5 5

  
6 6
# Create combined (MOD+MYD) corrected mean CF
7
    foreach(i=1:12) %dopar% {
7
    foreach(i=1:2) %dopar% {
8 8

  
9 9
        f=list.files(paste(datadir,"/mcd09ctif",sep=""),pattern=paste(".*[O|Y].*_",sprintf("%02d",i),"[.]tif$",sep=""),full=T)
10 10
        ## Define output and check if it already exists
11
        tmcd=paste(datadir,"/mcd09ctif/MCD09_",sprintf("%02d", i),".tif",sep="")
11
        tmcd=paste(datadir,"/mcd09ctif/MCD09_",sprintf("%02d", i),"_uncompressed.tif",sep="")
12
        tmcd2=paste(datadir,"/mcd09ctif/MCD09_",sprintf("%02d", i),".tif",sep="")
12 13
        ## check if output already exists
13 14
        ops=paste("-t_srs 'EPSG:4326' -multi -srcnodata -32768 -dstnodata -32768 -r bilinear -te -180 -90 180 90 -tr 0.008333333333333 -0.008333333333333",
14 15
            "-co BIGTIFF=YES  --config GDAL_CACHEMAX 500 -wm 500 -wo NUM_THREADS:10 -wo SOURCE_EXTRA=5")
......
22 23
            paste("TIFFTAG_DATETIME='2013",sprintf("%02d", i),"15'",sep=""),
23 24
              "TIFFTAG_ARTIST='Adam M. Wilson (adam.wilson@yale.edu)'")
24 25
        system(paste("/usr/local/src/gdal-1.10.0/swig/python/scripts/gdal_edit.py ",tmcd," ",paste("-mo ",tags,sep="",collapse=" "),sep=""))
26
        # create final fixed image
27
        system(paste("gdal_translate  -a_nodata -32768 -co COMPRESS=LZW -co ZLEVEL=9 -co PREDICTOR=2 ",tmcd," ",tmcd2,sep=""))
25 28
        writeLines(paste("Finished month",i))
26 29
    }
27 30

  
......
29 32

  
30 33
#################################################################################
31 34
###### convert to 8-bit compressed file, add colors and other details
32
for( i in 1:12){
33
    f2=list.files(paste(datadir,"/mcd09ctif",sep=""),pattern=paste(".*MCD09_",sprintf("%02d",i),"[.]tif$",sep=""),full=T)
34
    
35
    outfile=paste(datadir,"/mcd09ctif/",basename(file),sep="")
36
    outfile2=paste("data/mcd09tif/MCD09_",sprintf("%02d",i),".tif",sep="")
37
    outfile2b=paste("data/mcd09tif/MCD09_",sprintf("%02d",i),"_sd.tif",sep="")
35
f2=list.files(paste(datadir,"/mcd09ctif",sep=""),pattern=paste(".*MCD09_[0-9].[.]tif$",sep=""),full=T)
36

  
37
for( i in 1:length(f2)){
38
    file=f2[i]
39
    outfilevrt=paste(datadir,"/mcd09ctif/",sub(".tif",".vrt",basename(file)),sep="")
40
    outfile=paste("data/mcd09tif/MCD09_",sprintf("%02d",i),".tif",sep="")
41
    outfilesd=paste("data/mcd09tif/MCD09_",sprintf("%02d",i),"_sd.tif",sep="")
42
    ## create VRT and edit the color table
43
    ## create the vrt to add a color table following https://trac.osgeo.org/gdal/wiki/FAQRaster#Howtocreateormodifyanimagecolortable
44
    system(paste("gdal_translate  -scale 0 10000 0 100 -of VRT ",file," ",outfilevrt))
45
    vrt=scan(outfilevrt,what="char")
46
    hd=c("<ColorInterp>Palette</ColorInterp>","<ColorTable>")
47
    ft="</ColorTable>"
48
    colR=colorRampPalette(c("#08306b","#0d57a1","#2878b8","#4997c9","#72b2d7","#a2cbe2","#c7dcef","#deebf7","#f7fbff"))
49
    cols=data.frame(t(col2rgb(colR(101))))
50
    ct=paste("<Entry c1=\"",cols$red,"\" c2=\"",cols$green,"\" c3=\"",cols$blue,"\" c4=\"255\"/>")
51
    cti=grep("ColorInterp",vrt)  # get index of current color table
52
    vrt2=c(vrt[1:(cti-1)],hd,ct,ft,vrt[(cti+1):length(vrt)])
53
    ## update missing data flag following http://lists.osgeo.org/pipermail/gdal-dev/2010-February/023541.html
54
    csi=grep("<ComplexSource>",vrt2)  # get index of current color table
55
    vrt2=c(vrt2[1:csi],"<NODATA>-327.68</NODATA>",vrt2[(csi+1):length(vrt2)])
56
    write.table(vrt2,file=outfilevrt,col.names=F,row.names=F,quote=F)
57

  
58
    #system(paste("gdal_translate  -of VRT -scale 0 10000 0 100  ",outfilevrt," ",outfilevrt2))
38 59
    
39 60
    ## convert to 8-bit compressed file
40
    ops="-stats -scale 0 10000 0 100 -ot Byte -a_nodata 255 -co COMPRESS=LZW -co PREDICTOR=2 -co BIGTIFF=yes"
61
    ## update vrt to correctly handle missing data
62
    #vrt3=scan(outfilevrt2,what="char")
63
    #csi=grep("<ComplexSource>",vrt3)  # get index of current color table
64
    #vrt3=c(vrt[1:csi],"<NODATA>-32768</NODATA>",vrt[(csi+1):length(vrt)])
65
    #write.table(vrt3,file=outfilevrt2,col.names=F,row.names=F,quote=F)
66

  
67
                                        #    system(paste("pkreclass  -i ",outfilevrt," ",paste("-mo ",tags,sep="",collapse=" ")," ",outfilevrt," ",outfile2))
41 68
    tags=c(paste("TIFFTAG_IMAGEDESCRIPTION='Monthly Cloud Frequency for 2000-2013 extracted from C5 MODIS M*D09GA PGE11 internal cloud mask algorithm (embedded in state_1km bit 10).",
42 69
        "The daily cloud mask time series were summarized to mean cloud frequency (CF) by calculating the proportion of cloudy days. ",
43 70
        "Band Descriptions: 1) Mean Monthly Cloud Frequency'"),
44 71
        "TIFFTAG_DOCUMENTNAME='Collection 5 Cloud Frequency'",
45 72
        paste("TIFFTAG_DATETIME='2014'",sep=""),
46 73
        "TIFFTAG_ARTIST='Adam M. Wilson (adam.wilson@yale.edu)'")
47
    system(paste("gdal_translate  ",ops," ",paste("-mo ",tags,sep="",collapse=" ")," ",outfile," ",outfile2))
74
    system(paste("gdal_translate -ot Byte  -co COMPRESS=LZW -co PREDICTOR=2 ",paste("-mo ",tags,sep="",collapse=" ")," ",outfilevrt," ",outfile))
75

  
48 76
    ## Convert SD to 8-bit
49
    system(paste("gdal_translate  -b 2 ",ops," ",paste("-mo ",tags,sep="",collapse=" ")," ",file," ",outfile2b))
77
    system(paste("gdal_translate -b 2 ",ops," ",paste("-mo ",tags,sep="",collapse=" ")," ",file," ",outfilesd))
50 78
}
51 79

  
52 80

  
climate/research/cloud/MOD09/ee/ee_compile.R
18 18

  
19 19

  
20 20
### Download files from google drive
21
## This only works if google-cli is installed and has already been authenticated 
21 22
download=T
22
if(download) system(paste("google docs get 2014* ",datadir,"/mcd09ee",sep=""))
23
if(download) system(paste("google docs get 2014*_g3_* ",datadir,"/mcd09ee",sep=""))
23 24

  
24 25

  
25 26
##  Get list of available files
......
95 96

  
96 97

  
97 98

  
98

  
99
#### stuff below here is old junk.....       
100
        
101
        ##  convert to netcdf, subset to mean/sd bands
102
        trans_ops=paste(" -co COMPRESS=DEFLATE -a_nodata 255 -stats -co FORMAT=NC4 -co ZLEVEL=9 -b 4 -b 2")
103
        system(paste("gdal_translate -of netCDF ",trans_ops," ",ttif2," ",ncfile))
104
        ## file.remove(temptffile)
105
        system(paste("ncecat -O -u time ",ncfile," ",ncfile,sep=""))
106
        ## create temporary nc file with time information to append to CF data
107
        cat(paste("
108
    netcdf time {
109
      dimensions:
110
        time = 1 ;
111
      variables:
112
        int time(time) ;
113
      time:units = \"days since 2000-01-01 ",ifelse(s=="MOD09","10:30:00","13:30:00"),"\" ;
114
      time:calendar = \"gregorian\";
115
      time:long_name = \"time of observation\"; 
116
    data:
117
      time=",as.integer(date-as.Date("2000-01-01")),";
118
    }"),file=paste(tempdir(),"/",date,"_time.cdl",sep=""))
119
        system(paste("ncgen -o ",tempdir(),"/",date,"_time.nc ",tempdir(),"/",date,"_time.cdl",sep=""))
120
        ## add time dimension to ncfile and compress (deflate)
121
        system(paste("ncks --fl_fmt=netcdf4 -L 9 -A ",tempdir(),"/",date,"_time.nc ",ncfile,sep=""))
122
        ## add other attributes
123
        system(paste("ncrename -v Band1,CF ",ncfile,sep=""))
124
        system(paste("ncrename -v Band2,CFsd ",ncfile,sep=""))
125
        ## build correction factor explanation
126
        system(paste("ncatted ",
127
                     ## CF Mean
128
                     " -a units,CF,o,c,\"%\" ",
129
                     " -a valid_range,CF,o,ub,\"0,100\" ",
130
                                        #               " -a scale_factor,CF,o,b,\"0.1\" ",
131
                     " -a _FillValue,CF,o,ub,\"255\" ",
132
                     " -a missing_value,CF,o,ub,\"255\" ",
133
                     " -a long_name,CF,o,c,\"Cloud Frequency (%)\" ",
134
                     " -a correction_factor_description,CF,o,c,\"To account for variable observation frequency, CF in each pixel was adjusted by the proportion of days with at least one MODIS observation\" ",
135
                     " -a correction_factor,CF,o,f,\"",round(modbeta1,4),"\" ",
136
                     " -a NETCDF_VARNAME,CF,o,c,\"Cloud Frequency (%)\" ",
137
                     ## CF Standard Deviation
138
                     " -a units,CFsd,o,c,\"SD\" ",
139
                     " -a valid_range,CFsd,o,ub,\"0,200\" ",
140
                     " -a scale_factor,CFsd,o,f,\"0.25\" ",
141
                     " -a _FillValue,CFsd,o,ub,\"255\" ",
142
                     " -a missing_value,CFsd,o,ub,\"255\" ",
143
                     " -a long_name,CFsd,o,c,\"Cloud Frequency (%) Intra-month (2000-2013) Standard Deviation\" ",
144
                     " -a NETCDF_VARNAME,CFsd,o,c,\"Cloud Frequency (%) Intra-month (2000-2013) Standard Deviation\" ",
145
                     ## global
146
                     " -a title,global,o,c,\"Cloud Climatology from MOD09 Cloud Mask\" ",
147
                     " -a institution,global,o,c,\"Jetz Lab, EEB, Yale University, New Haven, CT\" ",
148
                     " -a source,global,o,c,\"Derived from MOD09GA Daily Data\" ",
149
                     " -a comment,global,o,c,\"Developed by Adam M. Wilson (adam.wilson@yale.edu / http://adamwilson.us)\" ",
150
                     ncfile,sep=""))
151

  
152
        ## add the fillvalue attribute back (without changing the actual values)
153
                                        #system(paste("ncatted -a _FillValue,CF,o,b,-32768 ",ncfile,sep=""))
154
        
155
        if(as.numeric(system(paste("cdo -s ntime ",ncfile),intern=T))<1) {
156
            print(paste(ncfile," has no time, deleting"))
157
            file.remove(ncfile)
158
        }
159
        print(paste(basename(ncfile)," Finished"))
160
        
161
        
162
    }
163

  
164
if(ramdisk) {
165
    ## unmount the ram disk
166
    system(paste("sudo umount ",tmpfs)
167
}
168

  
169

  
170
### merge all the tiles to a single global composite
171
#system(paste("ncdump -h ",list.files(tempdir,pattern="mod09.*.nc$",full=T)[10]))
172
file.remove("tmp/mod09_2000-01-15.nc")
173
system(paste("cdo -O  mergetime -setrtomiss,-32768,-1 ",paste(list.files(tempdir,pattern="mod09.*.nc$",full=T),collapse=" ")," data/cloud_monthly.nc"))
174

  
175
#  Overall mean
176
system(paste("cdo -O  timmean data/cloud_monthly.nc  data/cloud_mean.nc"))
177

  
178
### generate the monthly mean and sd
179
#system(paste("cdo -P 10 -O merge -ymonmean data/mod09.nc -chname,CF,CF_sd -ymonstd data/mod09.nc data/mod09_clim.nc"))
180
system(paste("cdo  -f nc4c -O -ymonmean data/cloud_monthly.nc data/cloud_ymonmean.nc"))
181

  
182

  
183
## Seasonal Means
184
system(paste("cdo  -f nc4c -O -yseasmean data/cloud_monthly.nc data/cloud_yseasmean.nc"))
185
system(paste("cdo  -f nc4c -O -yseasstd data/cloud_monthly.nc data/cloud_yseasstd.nc"))
186

  
187
## standard deviations, had to break to limit memory usage
188
system(paste("cdo  -f nc4c -z zip -O -chname,CF,CF_sd -ymonstd -selmon,1,2,3,4,5,6 data/cloud_monthly.nc data/cloud_ymonsd_1-6.nc"))
189
system(paste("cdo  -f nc4c -z zip -O -chname,CF,CF_sd -ymonstd -selmon,7,8,9,10,11,12 data/cloud_monthly.nc data/cloud_ymonsd_7-12.nc"))
190
system(paste("cdo  -f nc4c -z zip -O mergetime  data/cloud_ymonsd_1-6.nc  data/cloud_ymonsd_7-12.nc data/cloud_ymonstd.nc"))
191

  
192
system("cdo -f nc4c -z zip  timmin data/cloud_ymonmean.nc data/cloud_min.nc")
193
system("cdo -f nc4c -z zip  timmax data/cloud_ymonmean.nc data/cloud_max.nc")
194

  
195
## standard deviation of mean monthly values give intra-annual variability
196
system("cdo -f nc4c -z zip -chname,CF,CFsd -timstd data/cloud_ymonmean.nc data/cloud_std_intra.nc")
197
## mean of monthly standard deviations give inter-annual variability 
198
system("cdo -f nc4c -z zip -chname,CF,CFsd -timmean data/cloud_ymonstd.nc data/cloud_std_inter.nc")
199

  
200

  
201
# Regressions through time by season
202
s=c("DJF","MAM","JJA","SON")
203

  
204
system(paste("cdo  -f nc4c -O regres -selseas,",s[1]," data/cloud_monthly.nc data/slope_",s[1],".nc",sep=""))
205
system(paste("cdo  -f nc4c -O regres -selseas,",s[2]," data/cloud_monthly.nc data/slope_",s[2],".nc",sep=""))
206
system(paste("cdo  -f nc4c -O regres -selseas,",s[3]," data/cloud_monthly.nc data/slope_",s[3],".nc",sep=""))
207
system(paste("cdo  -f nc4c -O regres -selseas,",s[4]," data/cloud_monthly.nc data/slope_",s[4],".nc",sep=""))
208

  
209

  
210

  
211
## Daily animations
212
regs=list(
213
    Venezuela=extent(c(-69,-59,0,7)),
214
    Cascades=extent(c(-122.8,-118,44.9,47)),
215
    Hawaii=extent(c(-156.5,-154,18.75,20.5)),
216
    Boliva=extent(c(-71,-63,-20,-15)),
217
    CFR=extent(c(17.75,22.5,-34.8,-32.6)),
218
    Madagascar=extent(c(46,52,-17,-12))
219
    )
220

  
221
r=1
222

  
223
system(paste("cdo  -f nc4c -O inttime,2012-01-15,12:00:00,7day  -sellonlatbox,",
224
             paste(regs[[r]]@xmin,regs[[r]]@xmax,regs[[r]]@ymin,regs[[r]]@ymax,sep=","),
225
             "  data/cloud_monthly.nc data/daily_",names(regs[r]),".nc",sep=""))
226

  
227

  
228

  
229

  
230
### Long term summaries
231
seasconc <- function(x,return.Pc=T,return.thetat=F) {
232
          #################################################################################################
233
          ## Precipitation Concentration function
234
          ## This function calculates Precipitation Concentration based on Markham's (1970) technique as described in Schulze (1997)
235
          ## South Africa Atlas of Agrohydology and Climatology - R E Schulze, M Maharaj, S D Lynch, B J Howe, and B Melvile-Thomson
236
          ## Pages 37-38
237
          #################################################################################################
238
          ## x is a vector of precipitation quantities - the mean for each factor in "months" will be taken,
239
          ## so it does not matter if the data are daily or monthly, as long as the "months" factor correctly
240
          ## identifies them into 12 monthly bins, collapse indicates whether the data are already summarized as monthly means.
241
          #################################################################################################
242
          theta=seq(30,360,30)*(pi/180)                                       # set up angles for each month & convert to radians
243
                  if(sum(is.na(x))==12) { return(cbind(Pc=NA,thetat=NA)) ; stop}
244
                  if(return.Pc) {
245
                              rt=sqrt(sum(x * cos(theta))^2 + sum(x * sin(theta))^2)    # the magnitude of the summation
246
                                        Pc=as.integer(round((rt/sum(x))*100))}
247
                  if(return.thetat){
248
                              s1=sum(x*sin(theta),na.rm=T); s2=sum(x*cos(theta),na.rm=T)
249
                                        if(s1>=0 & s2>=0)  {thetat=abs((180/pi)*(atan(sum(x*sin(theta),na.rm=T)/sum(x*cos(theta),na.rm=T))))}
250
                                        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))))}
251
                                        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))))}
252
                                        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))))}
253
                             thetat=as.integer(round(thetat))
254
                            }
255
                  if(return.thetat&return.Pc) return(c(conc=Pc,theta=thetat))
256
                  if(return.Pc)          return(Pc)
257
                  if(return.thetat)  return(thetat)
258
        }
259

  
260

  
261

  
262
## read in monthly dataset
263
mod09=brick("data/cloud_ymonmean.nc",varname="CF")
264
plot(mod09[1])
265

  
266
mod09_seas=calc(mod09,seasconc,return.Pc=T,return.thetat=F,overwrite=T,filename="data/mod09_seas.nc",NAflag=255,datatype="INT1U")
267
mod09_seas2=calc(mod09,seasconc,return.Pc=F,return.thetat=T,overwrite=T,filename="data/mod09_seas_theta.nc",datatype="INT1U")
268

  
269
plot(mod09_seas)

Also available in: Unified diff