Revision e2f70c46
Added by Adam Wilson almost 11 years ago
climate/research/cloud/GetCloudProducts.R | ||
---|---|---|
1 |
## download cloud products from GEWEX for comparison |
|
2 |
setwd("~/acrobates/adamw/projects/cloud/") |
|
3 |
library(rasterVis) |
|
4 |
|
|
5 |
|
|
6 |
## get PATMOS-X 1-deg data |
|
7 |
dir1="data/gewex/" |
|
8 |
|
|
9 |
for(y in 2000:2009) system(paste("wget -nc -P ",dir1," http://climserv.ipsl.polytechnique.fr/gewexca/DATA/instruments/PATMOSX/variables/CA/CA_PATMOSX_NOAA_0130PM_",y,".nc.gz",sep="")) |
|
10 |
## decompress |
|
11 |
lapply(list.files(dir1,pattern="gz",full=T),function(f) system(paste("gzip -dc < ",f," > ",dir1," ",sub(".gz","",basename(f)),sep=""))) |
|
12 |
## mergetime |
|
13 |
system(paste("cdo -mergetime ",list.files(dir1,pattern="nc$",full=T)," ",dir1,"CA_PATMOSX_NOAA.nc",sep="")) |
|
14 |
|
|
15 |
|
|
16 |
## Get |
|
17 |
|
climate/research/cloud/MOD09/GetCloudProducts.R | ||
---|---|---|
1 |
## download cloud products from GEWEX for comparison |
|
2 |
setwd("~/acrobates/adamw/projects/cloud/") |
|
3 |
library(rasterVis) |
|
4 |
|
|
5 |
|
|
6 |
## get PATMOS-X 1-deg data |
|
7 |
dir1="data/gewex/" |
|
8 |
|
|
9 |
for(y in 2000:2009) system(paste("wget -nc -P ",dir1," http://climserv.ipsl.polytechnique.fr/gewexca/DATA/instruments/PATMOSX/variables/CA/CA_PATMOSX_NOAA_0130PM_",y,".nc.gz",sep="")) |
|
10 |
## decompress |
|
11 |
lapply(list.files(dir1,pattern="gz",full=T),function(f) system(paste("gzip -dc < ",f," > ",dir1," ",sub(".gz","",basename(f)),sep=""))) |
|
12 |
## mergetime |
|
13 |
system(paste("cdo -mergetime ",list.files(dir1,pattern="nc$",full=T)," ",dir1,"CA_PATMOSX_NOAA.nc",sep="")) |
|
14 |
|
|
15 |
|
|
16 |
## Get |
|
17 |
|
climate/research/cloud/MOD09/NDP-026D.R | ||
---|---|---|
1 |
### Script to download and process the NDP-026D station cloud dataset |
|
2 |
### to validate MODIS cloud frequencies |
|
3 |
|
|
4 |
setwd("~/acrobates/adamw/projects/cloud/data/NDP026D") |
|
5 |
|
|
6 |
library(multicore) |
|
7 |
library(doMC) |
|
8 |
library(rasterVis) |
|
9 |
library(rgdal) |
|
10 |
library(reshape) |
|
11 |
|
|
12 |
|
|
13 |
## Data available here http://cdiac.ornl.gov/epubs/ndp/ndp026d/ndp026d.html |
|
14 |
|
|
15 |
## Get station locations |
|
16 |
system("wget -N -nd http://cdiac.ornl.gov/ftp/ndp026d/cat01/01_STID -P data/") |
|
17 |
st=read.table("data/01_STID",skip=1) |
|
18 |
colnames(st)=c("StaID","LAT","LON","ELEV","ny1","fy1","ly1","ny7","fy7","ly7","SDC","b5c") |
|
19 |
st$lat=st$LAT/100 |
|
20 |
st$lon=st$LON/100 |
|
21 |
st$lon[st$lon>180]=st$lon[st$lon>180]-360 |
|
22 |
st=st[,c("StaID","ELEV","lat","lon")] |
|
23 |
colnames(st)=c("id","elev","lat","lon") |
|
24 |
write.csv(st,"stations.csv",row.names=F) |
|
25 |
coordinates(st)=c("lon","lat") |
|
26 |
projection(st)="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" |
|
27 |
st@data[,c("lon","lat")]=coordinates(st) |
|
28 |
|
|
29 |
## download data |
|
30 |
system("wget -N -nd ftp://cdiac.ornl.gov/pub/ndp026d/cat67_78/* -A '.tc.Z' -P data/") |
|
31 |
|
|
32 |
system("gunzip data/*.Z") |
|
33 |
|
|
34 |
## define FWF widths |
|
35 |
f162=c(5,5,4,7,7,7,4) #format 162 |
|
36 |
c162=c("StaID","YR","Nobs","Amt","Fq","AWP","NC") |
|
37 |
|
|
38 |
## use monthly timeseries |
|
39 |
cld=do.call(rbind.data.frame,mclapply(sprintf("%02d",1:12),function(m) { |
|
40 |
d=read.fwf(list.files("data",pattern=paste("MNYDC.",m,".tc$",sep=""),full=T),skip=1,widths=f162) |
|
41 |
colnames(d)=c162 |
|
42 |
d$month=as.numeric(m) |
|
43 |
print(m) |
|
44 |
return(d)} |
|
45 |
)) |
|
46 |
|
|
47 |
## add lat/lon |
|
48 |
cld[,c("lat","lon")]=coordinates(st)[match(cld$StaID,st$id),] |
|
49 |
|
|
50 |
## drop missing values |
|
51 |
cld=cld[,!grepl("Fq|AWP|NC",colnames(cld))] |
|
52 |
cld$Amt[cld$Amt<0]=NA |
|
53 |
cld$Amt=cld$Amt/100 |
|
54 |
|
|
55 |
## calculate means and sds for full record (1970-2009) |
|
56 |
Nobsthresh=20 #minimum number of observations to include |
|
57 |
|
|
58 |
cldm=do.call(rbind.data.frame,by(cld,list(month=as.factor(cld$month),StaID=as.factor(cld$StaID)),function(x){ |
|
59 |
data.frame( |
|
60 |
month=x$month[1], |
|
61 |
StaID=x$StaID[1], |
|
62 |
cld_all=mean(x$Amt[x$Nobs>=Nobsthresh],na.rm=T), # full record |
|
63 |
cldsd_all=sd(x$Amt[x$Nobs>=Nobsthresh],na.rm=T), |
|
64 |
cld=mean(x$Amt[x$YR>=2000&x$Nobs>=Nobsthresh],na.rm=T), #only MODIS epoch |
|
65 |
cldsd=sd(x$Amt[x$YR>=2000&x$Nobs>=Nobsthresh],na.rm=T))})) |
|
66 |
cldm[,c("lat","lon")]=coordinates(st)[match(cldm$StaID,st$id),c("lat","lon")] |
|
67 |
|
|
68 |
|
|
69 |
|
|
70 |
## add the MOD09 data to cld |
|
71 |
#### Evaluate MOD35 Cloud data |
|
72 |
mod09=brick("~/acrobates/adamw/projects/cloud/data/cloud_ymonmean.nc") |
|
73 |
mod09std=brick("~/acrobates/adamw/projects/cloud/data/cloud_ymonstd.nc") |
|
74 |
|
|
75 |
## overlay the data with 32km diameter (16km radius) buffer |
|
76 |
## buffer size from Dybbroe, et al. (2005) doi:10.1175/JAM-2189.1. |
|
77 |
buf=16000 |
|
78 |
bins=cut(st$lat,10) |
|
79 |
rerun=F |
|
80 |
if(rerun&file.exists("valid.csv")) file.remove("valid.csv") |
|
81 |
mod09sta=lapply(levels(bins),function(lb) { |
|
82 |
l=which(bins==lb) |
|
83 |
## mean |
|
84 |
td=extract(mod09,st[l,],buffer=buf,fun=mean,na.rm=T,df=T) |
|
85 |
td$id=st$id[l] |
|
86 |
td$type="mean" |
|
87 |
## std |
|
88 |
td2=extract(mod09std,st[l,],buffer=buf,fun=mean,na.rm=T,df=T) |
|
89 |
td2$id=st$id[l] |
|
90 |
td2$type="sd" |
|
91 |
print(lb)#as.vector(c(l,td[,1:4]))) |
|
92 |
write.table(rbind(td,td2),"valid.csv",append=T,col.names=F,quote=F,sep=",",row.names=F) |
|
93 |
td |
|
94 |
})#,mc.cores=3) |
|
95 |
|
|
96 |
## read it back in |
|
97 |
mod09st=read.csv("valid.csv",header=F)[,-c(1)] |
|
98 |
colnames(mod09st)=c(names(mod09),"id","type") |
|
99 |
mod09stl=melt(mod09st,id.vars=c("id","type")) |
|
100 |
mod09stl[,c("year","month")]=do.call(rbind,strsplit(sub("X","",mod09stl$variable),"[.]"))[,1:2] |
|
101 |
mod09stl$value[mod09stl$value<0]=NA |
|
102 |
mod09stl=cast(mod09stl,id+year+month~type,value="value") |
|
103 |
|
|
104 |
## add it to cld |
|
105 |
cldm$mod09=mod09stl$mean[match(paste(cldm$StaID,cldm$month),paste(mod09stl$id,as.numeric(mod09stl$month)))] |
|
106 |
cldm$mod09sd=mod09stl$sd[match(paste(cldm$StaID,cldm$month),paste(mod09stl$id,as.numeric(mod09stl$month)))] |
|
107 |
|
|
108 |
|
|
109 |
## LULC |
|
110 |
#system(paste("gdalwarp -r near -co \"COMPRESS=LZW\" -tr ",paste(res(mod09),collapse=" ",sep=""), |
|
111 |
# "-tap -multi -t_srs \"", projection(mod09),"\" /mnt/data/jetzlab/Data/environ/global/landcover/MODIS/MCD12Q1_IGBP_2005_v51.tif ../modis/mod12/MCD12Q1_IGBP_2005_v51.tif")) |
|
112 |
lulc=raster("~/acrobates/adamw/projects/interp/data/modis/mod12/MCD12Q1_IGBP_2005_v51.tif") |
|
113 |
require(plotKML); data(worldgrids_pal) #load IGBP palette |
|
114 |
IGBP=data.frame(ID=0:16,col=worldgrids_pal$IGBP[-c(18,19)],stringsAsFactors=F) |
|
115 |
IGBP$class=rownames(IGBP);rownames(IGBP)=1:nrow(IGBP) |
|
116 |
levels(lulc)=list(IGBP) |
|
117 |
## function to get modal lulc value |
|
118 |
Mode <- function(x) { |
|
119 |
ux <- na.omit(unique(x)) |
|
120 |
ux[which.max(tabulate(match(x, ux)))] |
|
121 |
} |
|
122 |
lulcst=extract(lulc,st,fun=Mode,buffer=buf,df=T) |
|
123 |
colnames(lulcst)=c("id","lulc") |
|
124 |
## add it to cld |
|
125 |
cldm$lulc=lulcst$lulc[match(cldm$StaID,lulcst$id)] |
|
126 |
cldm$lulcc=IGBP$class[match(cldm$lulc,IGBP$ID)] |
|
127 |
|
|
128 |
|
|
129 |
### Add biome data |
|
130 |
if(!file.exists("../teow/biomes.shp")){ |
|
131 |
teow=readOGR("/mnt/data/jetzlab/Data/environ/global/teow/official/","wwf_terr_ecos") |
|
132 |
teow=teow[teow$BIOME<90,] |
|
133 |
biome=unionSpatialPolygons(teow,teow$BIOME, threshold=5) |
|
134 |
biomeid=read.csv("/mnt/data/jetzlab/Data/environ/global/teow/official/biome.csv",stringsAsFactors=F) |
|
135 |
biome=SpatialPolygonsDataFrame(biome,data=biomeid[as.numeric(row.names(biome)),]) |
|
136 |
writeOGR(biome,"../teow","biomes",driver="ESRI Shapefile",overwrite=T) |
|
137 |
} |
|
138 |
biome=readOGR("../teow/","biomes") |
|
139 |
projection(biome)=projection(st) |
|
140 |
#st$biome=over(st,biome,returnList=F)$BiomeID |
|
141 |
dists=apply(gDistance(st,biome,byid=T),2,which.min) |
|
142 |
st$biome=biome$BiomeID[dists] |
|
143 |
|
|
144 |
cldm$biome=st$biome[match(cldm$StaID,st$id)] |
|
145 |
|
|
146 |
|
|
147 |
## write out the tables |
|
148 |
write.csv(cld,file="cld.csv",row.names=F) |
|
149 |
write.csv(cldm,file="cldm.csv",row.names=F) |
|
150 |
writeOGR(st,dsn=".",layer="stations",driver="ESRI Shapefile",overwrite_layer=T) |
|
151 |
######################################################################### |
|
152 |
|
climate/research/cloud/MOD09/ee/EE_simple.py | ||
---|---|---|
1 |
import ee |
|
2 |
from ee import mapclient |
|
3 |
|
|
4 |
import logging |
|
5 |
logging.basicConfig() |
|
6 |
|
|
7 |
MY_SERVICE_ACCOUNT = '511722844190@developer.gserviceaccount.com' # replace with your service account |
|
8 |
MY_PRIVATE_KEY_FILE = '/Users/adamw/EarthEngine-privatekey.p12' # replace with you private key file path |
|
9 |
|
|
10 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
image = ee.Image('srtm90_v4') |
|
15 |
map = ee.mapclient.MapClient() |
|
16 |
map.addOverlay(mapclient.MakeOverlay(image.getMapId({'min': 0, 'max': 3000}))) |
climate/research/cloud/MOD09/ee/MODISLANDObservationFrequency.js | ||
---|---|---|
1 |
// MODIS LAND Observation Frequency |
|
2 |
|
|
3 |
// Proportion of days in the month with at least 1 MODIS observation |
|
4 |
var p_07 = ee.ImageCollection("MOD09GA"). |
|
5 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
6 |
filter(ee.Filter.calendarRange(7,7,"month")).map(function(img) { |
|
7 |
return img.select(['num_observations_1km']).gte(1)}).mean().multiply(ee.Image(100)).select([0],["p07"]); |
|
8 |
|
|
9 |
// mean number of observations per day |
|
10 |
var n_07 = ee.ImageCollection("MOD09GA"). |
|
11 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
12 |
filter(ee.Filter.calendarRange(7,7,"month")).map(function(img) { |
|
13 |
return img.select(['num_observations_1km'])}).mean().select([0],["n07"]); |
|
14 |
|
|
15 |
var n_12 = ee.ImageCollection("MOD09GA"). |
|
16 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
17 |
filter(ee.Filter.calendarRange(12,12,"month")).map(function(img) { |
|
18 |
return img.select(['num_observations_1km']).gte(1)}).mean().multiply(ee.Image(100)).select([0],["p12"]); |
|
19 |
|
|
20 |
// mean number of observations per day |
|
21 |
var p_12 = ee.ImageCollection("MOD09GA"). |
|
22 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
23 |
filter(ee.Filter.calendarRange(12,12,"month")).map(function(img) { |
|
24 |
return img.select(['num_observations_1km'])}).mean().select([0],["n12"]); |
|
25 |
|
|
26 |
// Combine anything into image for download |
|
27 |
var image=n_07.addBands(p_07).addBands(n_12).addBands(p_12) |
|
28 |
//var reproj = image.reproject('EPSG:4326', [0.008333333333, 0, -180, 0, -0.008333333333, -90]) |
|
29 |
|
|
30 |
//var palette="000000,00FF00,FF0000" |
|
31 |
//addToMap(image.select([0]),{min:0,max:100,palette:palette},"July"); |
|
32 |
//addToMap(n_12,{min:0,max:100,palette:palette},"Decenber"); |
|
33 |
|
|
34 |
|
|
35 |
var driveFolder="EarthEngineOutput" |
|
36 |
|
|
37 |
exportImage(image, |
|
38 |
'PObs', |
|
39 |
{'name': 'PObs', |
|
40 |
'maxPixels':1000000000, |
|
41 |
'driveFolder':driveFolder, |
|
42 |
'crs': 'EPSG:4326', //4326 |
|
43 |
'crsTransform':[0.008333333333, 0, -180, 0, -0.008333333333, -90], |
|
44 |
// 'scale': 0.008333333333, |
|
45 |
'region': '[[-180, -89], [-180, 89], [180, 89], [180, -89]]' //global |
|
46 |
// 'region': '[[-180, 0], [-180, 10], [180, 10], [180, 0]]' // |
|
47 |
}); |
climate/research/cloud/MOD09/ee/MODIS_Cloud.py | ||
---|---|---|
1 |
import ee |
|
2 |
from ee import mapclient |
|
3 |
|
|
4 |
import logging |
|
5 |
logging.basicConfig() |
|
6 |
|
|
7 |
MY_SERVICE_ACCOUNT = '511722844190@developer.gserviceaccount.com' # replace with your service account |
|
8 |
MY_PRIVATE_KEY_FILE = '/Users/adamw/EarthEngine-privatekey.p12' # replace with you private key file path |
|
9 |
|
|
10 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
11 |
|
|
12 |
#// EVI_Cloud_month |
|
13 |
|
|
14 |
#// Make land mask |
|
15 |
#// Select the forest classes from the MODIS land cover image and intersect them |
|
16 |
#// with elevations above 1000m. |
|
17 |
elev = ee.Image('srtm90_v4'); |
|
18 |
cover = ee.Image('MCD12Q1/MCD12Q1_005_2001_01_01').select('Land_Cover_Type_1'); |
|
19 |
blank = ee.Image(0); |
|
20 |
#// Where (cover == 0) and (elev > 0), set the output to 1. |
|
21 |
land = blank.where( |
|
22 |
cover.neq(0).and(cover.neq(15)),//.and(elev.gt(0)), |
|
23 |
1); |
|
24 |
|
|
25 |
palette = ["aec3d4", // water |
|
26 |
"152106", "225129", "369b47", "30eb5b", "387242", // forest |
|
27 |
"6a2325", "c3aa69", "b76031", "d9903d", "91af40", // shrub, grass, savanah |
|
28 |
"111149", // wetlands |
|
29 |
"cdb33b", // croplands |
|
30 |
"cc0013", // urban |
|
31 |
"33280d", // crop mosaic |
|
32 |
"d7cdcc", // snow and ice |
|
33 |
"f7e084", // barren |
|
34 |
"6f6f6f"].join(',');// tundra |
|
35 |
|
|
36 |
#// make binary map for forest/nonforest |
|
37 |
forest = blank.where(cover.gte(1).and(cover.lte(5)),1); |
|
38 |
|
|
39 |
#//addToMap(forest, {min: 0, max: 1}); |
|
40 |
#//addToMap(cover, {min: 0, max: 17, palette:palette}); |
|
41 |
|
|
42 |
#// MODIS EVI Collection |
|
43 |
collection = ee.ImageCollection("MCD43A4_EVI"); |
|
44 |
|
|
45 |
#//define reducers and filters |
|
46 |
COUNT = ee.call("Reducer.count"); |
|
47 |
#// Loop through months and get monthly % cloudiness |
|
48 |
#//for (var month = 1; month < 2; month += 1) { |
|
49 |
#//month=1; |
|
50 |
FilterMonth = ee.Filter(ee.call("Filter.calendarRange", |
|
51 |
start=month,end=month,field="month")); |
|
52 |
tmonth=collection.filter(FilterMonth) |
|
53 |
|
|
54 |
n=tmonth.getInfo().features.length; #// Get total number of images |
|
55 |
print(n+" Layers in the collection for month "+month) |
|
56 |
tcloud=tmonth.reduce(COUNT).float() |
|
57 |
c=ee.Image(n); #// make raster with constant value of n |
|
58 |
c1=ee.Image(-1); #// make raster with constant value of -1 to convert to % cloudy |
|
59 |
|
|
60 |
#///////////////////////////////////////////////// |
|
61 |
#// Generate the cloud frequency surface: |
|
62 |
#// 1 Calculate the number of days with measurements |
|
63 |
#// 2 divide by the total number of layers |
|
64 |
#// 3 Add -1 and multiply by -1 to invert to % cloudy |
|
65 |
#// 4 Rename to "PCloudy_month" |
|
66 |
tcloud = tcloud.divide(c).add(c1).multiply(c1).expression("b()*100").int8().select_([0],["PCloudy_"+month]); |
|
67 |
#//if(month==1) {var cloud=tcloud} // if first year, make new object |
|
68 |
#//if(month>1) {var cloud=cloud.addBands(tcloud)} // if not first year, append to first year |
|
69 |
#//} //end loop over months |
|
70 |
# // end loop over years |
|
71 |
|
|
72 |
|
|
73 |
#//print(evi_miss.stats()) |
|
74 |
#//addToMap(tcloud,{min:0,max:100,palette:"000000,00FF00,FF0000"}); |
|
75 |
#//addToMap(elev,{min:0,max:2500,palette:"000000,00FF00,FF0000"}); |
|
76 |
|
|
77 |
#//centerMap(-122.418, 37.72, 10); |
|
78 |
path = tcloud.getDownloadURL({ |
|
79 |
'scale': 1000, |
|
80 |
'crs': 'EPSG:4326', |
|
81 |
'region': '[[-90, 0], [-90, 20], [-50, 0], [-50, 20]]' //h11v08 |
|
82 |
#// 'region': '[[-180, -90], [-180, 90], [180, -90], [180, 90]]' |
|
83 |
}); |
|
84 |
print('https://earthengine.googleapis.com' + path); |
|
85 |
|
climate/research/cloud/MOD09/ee/README.txt | ||
---|---|---|
1 |
This folder holds scripts related to work on Google Earth Engine, primarily for processing MODIS cloud data. |
climate/research/cloud/MOD09/ee/ee.MOD09.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
|
|
3 |
## Example script that downloads data from Google Earth Engine using the python API |
|
4 |
## MODIS MOD09GA data is processed to extract the MOD09 cloud flag and calculate monthly cloud frequency |
|
5 |
|
|
6 |
|
|
7 |
## import some libraries |
|
8 |
import ee |
|
9 |
from ee import mapclient |
|
10 |
import ee.mapclient |
|
11 |
import datetime |
|
12 |
import wget |
|
13 |
import os |
|
14 |
import sys |
|
15 |
import subprocess |
|
16 |
import time |
|
17 |
|
|
18 |
import logging |
|
19 |
logging.basicConfig(filename='error.log',level=logging.DEBUG) |
|
20 |
|
|
21 |
def Usage(): |
|
22 |
print('Usage: ee.MOD9.py -projwin ulx uly urx ury lrx lry llx lly -year year -month month -regionname 1') |
|
23 |
sys.exit( 1 ) |
|
24 |
|
|
25 |
ulx = float(sys.argv[2]) |
|
26 |
uly = float(sys.argv[3]) |
|
27 |
urx = float(sys.argv[4]) |
|
28 |
ury = float(sys.argv[5]) |
|
29 |
lrx = float(sys.argv[6]) |
|
30 |
lry = float(sys.argv[7]) |
|
31 |
llx = float(sys.argv[8]) |
|
32 |
lly = float(sys.argv[9]) |
|
33 |
year = int(sys.argv[11]) |
|
34 |
month = int(sys.argv[13]) |
|
35 |
regionname = str(sys.argv[15]) |
|
36 |
#``` |
|
37 |
#ulx=-159 |
|
38 |
#uly=20 |
|
39 |
#lrx=-154.5 |
|
40 |
#lry=18.5 |
|
41 |
#year=2001 |
|
42 |
#month=6 |
|
43 |
#``` |
|
44 |
## Define output filename |
|
45 |
output=regionname+'_'+str(year)+'_'+str(month) |
|
46 |
|
|
47 |
## set working directory (where files will be downloaded) |
|
48 |
cwd='/mnt/data2/projects/cloud/mod09/' |
|
49 |
## Wget always starts with a temporary file called "download", so move to a subdirectory to |
|
50 |
## prevent overwrting when parallel downloading |
|
51 |
if not os.path.exists(cwd+output): |
|
52 |
os.makedirs(cwd+output) |
|
53 |
os.chdir(cwd+output) |
|
54 |
|
|
55 |
# output filename |
|
56 |
unzippedfilename=output+".mod09.tif" |
|
57 |
# Check if file already exists and continue if so... |
|
58 |
if(os.path.exists(unzippedfilename)): |
|
59 |
sys.exit("File exists:"+output) |
|
60 |
|
|
61 |
## initialize GEE |
|
62 |
MY_SERVICE_ACCOUNT = '511722844190@developer.gserviceaccount.com' # replace with your service account |
|
63 |
MY_PRIVATE_KEY_FILE = '/home/adamw/EarthEngine-privatekey.p12' # replace with you private key file path |
|
64 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
65 |
|
|
66 |
## set map center to speed up viewing |
|
67 |
#ee.mapclient.centerMap(-121.767, 46.852, 11) |
|
68 |
|
|
69 |
#/////////////////////////////////// |
|
70 |
#// Function to extract cloud flags |
|
71 |
def getmod09(img): return(img.select(['state_1km']).expression("((b(0)/1024)%2)").gte(1)); |
|
72 |
|
|
73 |
#//////////////////////////////////////////////////// |
|
74 |
##################################################### |
|
75 |
# Processing Function |
|
76 |
# MOD09 internal cloud flag for this year-month |
|
77 |
# to filter by a date range: filterDate(datetime.datetime(yearstart,monthstart,1),datetime.datetime(yearstop,monthstop,31)) |
|
78 |
mod09 = ee.ImageCollection("MOD09GA").filter(ee.Filter.calendarRange(year,year,"year")).filter(ee.Filter.calendarRange(month,month,"month")).map(getmod09); |
|
79 |
# myd09 = ee.ImageCollection("MYD09GA").filter(ee.Filter.calendarRange(year,year,"year")).filter(ee.Filter.calendarRange(month,month,"month")).map(getmod09); |
|
80 |
# calculate mean cloudiness (%), rename band, multiply by 100, and convert to integer |
|
81 |
mod09a=mod09.mean().select([0], ['mod09']).multiply(ee.Image(1000)).int16(); |
|
82 |
# myd09a=myd09.mean().select([0], ['MYD09_'+str(year)+'_'+str(month)]).multiply(ee.Image(100)).int8(); |
|
83 |
## Set data equal to whatver you want downloaded |
|
84 |
data=mod09a |
|
85 |
###################################################### |
|
86 |
|
|
87 |
## define region for download |
|
88 |
region=[llx, lly],[lrx, lry],[urx, ury],[ulx,uly] #h11v08 |
|
89 |
strregion=str(list(region)) |
|
90 |
|
|
91 |
# add to plot to confirm it's working |
|
92 |
#ee.mapclient.addToMap(data, {'range': '0,100'}, 'MOD09') |
|
93 |
|
|
94 |
# build the URL and name the object (so that when it's unzipped we know what it is!) |
|
95 |
path =mod09a.getDownloadUrl({ |
|
96 |
'crs': 'SR-ORG:6974', # MODIS Sinusoidal |
|
97 |
'scale': '926.625433055833', # MODIS ~1km |
|
98 |
'name': output, # name the file (otherwise it will be a uninterpretable hash) |
|
99 |
'region': strregion # region defined above |
|
100 |
}); |
|
101 |
|
|
102 |
# print info to confirm there is data |
|
103 |
print(data.getInfo()) |
|
104 |
print(' Processing.... '+output+' Coords:'+strregion) |
|
105 |
print(path) |
|
106 |
|
|
107 |
#test=wget.download(path) |
|
108 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
109 |
print('download sucess for tile '+output+': '+str(test)) |
|
110 |
|
|
111 |
## Sometimes EE will serve a corrupt zipped file with no error |
|
112 |
# try to unzip it |
|
113 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
114 |
|
|
115 |
if zipstatus==0: #if sucessful, quit |
|
116 |
os.remove("mod09.zip") |
|
117 |
sys.exit("Finished: "+output) |
|
118 |
|
|
119 |
# if file doesn't exists or it didn't unzip, try again |
|
120 |
if zipstatus!=0: |
|
121 |
print("Zip Error for: "+output+"... Trying again (#2)") |
|
122 |
time.sleep(15) |
|
123 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
124 |
|
|
125 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
126 |
|
|
127 |
if zipstatus==0: #if sucessful, quit |
|
128 |
os.remove("mod09.zip") |
|
129 |
sys.exit("Finished: "+output) |
|
130 |
|
|
131 |
# if file doesn't exists or it didn't unzip, try again |
|
132 |
if zipstatus!=0: |
|
133 |
print("Zip Error for: "+output+"... Trying again (#3)") |
|
134 |
time.sleep(30) |
|
135 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
136 |
|
|
137 |
# try again #4 |
|
138 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
139 |
|
|
140 |
if zipstatus==0: #if sucessful, quit |
|
141 |
os.remove("mod09.zip") |
|
142 |
sys.exit("Finished: "+output) |
|
143 |
|
|
144 |
# if file doesn't exists or it didn't unzip, try again |
|
145 |
if zipstatus!=0: |
|
146 |
print("Zip Error for: "+output+"... Trying again (#4)") |
|
147 |
time.sleep(30) |
|
148 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
149 |
|
|
150 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
151 |
|
|
152 |
if zipstatus==0: #if sucessful, quit |
|
153 |
os.remove("mod09.zip") |
|
154 |
sys.exit("Finished: "+output) |
|
155 |
|
|
156 |
## delete the zipped file (the unzipped version is kept) |
|
157 |
os.remove("mod09.zip") |
|
158 |
sys.exit("Zip Error for: "+output) |
|
159 |
|
|
160 |
|
climate/research/cloud/MOD09/ee/ee.MOD09_parallel.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
|
|
3 |
## Example script that downloads data from Google Earth Engine using the python API |
|
4 |
## MODIS MOD09GA data is processed to extract the MOD09 cloud flag and calculate monthly cloud frequency |
|
5 |
|
|
6 |
## import some libraries |
|
7 |
import ee |
|
8 |
from ee import mapclient |
|
9 |
import ee.mapclient |
|
10 |
import datetime |
|
11 |
import wget |
|
12 |
import os |
|
13 |
import sys |
|
14 |
|
|
15 |
def Usage(): |
|
16 |
print('Usage: ee.MOD9.py -projwin ulx uly lrx lry -o output ') |
|
17 |
sys.exit( 1 ) |
|
18 |
|
|
19 |
ulx = float(sys.argv[2]) |
|
20 |
uly = float(sys.argv[3]) |
|
21 |
lrx = float(sys.argv[4]) |
|
22 |
lry = float(sys.argv[5]) |
|
23 |
output = sys.argv[7] |
|
24 |
|
|
25 |
print ( output , ulx ,uly ,lrx , lry ) |
|
26 |
|
|
27 |
#import logging |
|
28 |
|
|
29 |
MY_SERVICE_ACCOUNT = '364044830827-ubb6ja607b8j7t8m9uooi4c01vgah4ms@developer.gserviceaccount.com' # replace with your service account |
|
30 |
MY_PRIVATE_KEY_FILE = '/home/selv/GEE/fe3f13d90031e3eedaa9974baa6994e467b828f7-privatekey.p12' # replace with you private key file path |
|
31 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
32 |
|
|
33 |
#/////////////////////////////////// |
|
34 |
#// Function to extract cloud flags |
|
35 |
def getmod09(img): return(img.select(['state_1km']).expression("((b(0)/1024)%2)")); |
|
36 |
|
|
37 |
## set a year-month if you don't want to run the loop (for testing) |
|
38 |
year=2001 |
|
39 |
month=1 |
|
40 |
|
|
41 |
print('Processing '+str(year)+'_'+str(month)) |
|
42 |
|
|
43 |
## MOD09 internal cloud flag for this year-month |
|
44 |
## to filter by a date range: filterDate(datetime.datetime(yearstart,monthstart,1),datetime.datetime(yearstop,monthstop,31)) |
|
45 |
mod09 = ee.ImageCollection("MOD09GA").filter(ee.Filter.calendarRange(year,year,"year")).filter(ee.Filter.calendarRange(month,month,"month")).map(getmod09); |
|
46 |
|
|
47 |
## calculate mean cloudiness (%), rename band, multiply by 100, and convert to integer |
|
48 |
mod09a=mod09.mean().select([0], ['MOD09_'+str(year)+'_'+str(month)]).multiply(ee.Image(100)).byte(); |
|
49 |
|
|
50 |
## print info to confirm there is data |
|
51 |
# mod09a.getInfo() |
|
52 |
|
|
53 |
## define region for download |
|
54 |
region=[ulx,lry ], [ulx, uly], [lrx, uly], [lrx, lry] #h11v08 |
|
55 |
strregion=str(list(region)) |
|
56 |
|
|
57 |
## Define tiles |
|
58 |
region='[[-72, -1], [-72, 11], [-59, 11], [-59, -1]]' |
|
59 |
## build the URL and name the object (so that when it's unzipped we know what it is!) |
|
60 |
path =mod09a.getDownloadUrl({ |
|
61 |
'name': output, # name the file (otherwise it will be a uninterpretable hash) |
|
62 |
'scale': 926, # resolution in meters |
|
63 |
'crs': 'EPSG:4326', # MODIS sinusoidal |
|
64 |
'region': strregion # region defined above |
|
65 |
}); |
|
66 |
|
|
67 |
## download with wget |
|
68 |
wget.download(path) |
|
69 |
|
|
70 |
|
|
71 |
|
climate/research/cloud/MOD09/ee/ee_compile.R | ||
---|---|---|
1 |
### Script to compile the monthly cloud data from earth engine into a netcdf file for further processing |
|
2 |
|
|
3 |
library(raster) |
|
4 |
library(doMC) |
|
5 |
library(multicore) |
|
6 |
library(foreach) |
|
7 |
#library(doMPI) |
|
8 |
registerDoMC(4) |
|
9 |
#beginCluster(4) |
|
10 |
|
|
11 |
wd="~/acrobates/adamw/projects/cloud" |
|
12 |
setwd(wd) |
|
13 |
|
|
14 |
tempdir="tmp" |
|
15 |
if(!file.exists(tempdir)) dir.create(tempdir) |
|
16 |
|
|
17 |
## Get list of available files |
|
18 |
df=data.frame(path=list.files("/mnt/data2/projects/cloud/mod09",pattern="*.tif$",full=T,recur=T),stringsAsFactors=F) |
|
19 |
df[,c("region","year","month")]=do.call(rbind,strsplit(basename(df$path),"_|[.]"))[,c(1,2,3)] |
|
20 |
df$date=as.Date(paste(df$year,"_",df$month,"_15",sep=""),"%Y_%m_%d") |
|
21 |
|
|
22 |
## add stats to test for missing data |
|
23 |
addstats=F |
|
24 |
if(addstats){ |
|
25 |
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))))) |
|
26 |
table(df$sd==0) |
|
27 |
} |
|
28 |
|
|
29 |
## subset to testtiles? |
|
30 |
#df=df[df$region%in%testtiles,] |
|
31 |
#df=df[df$month==1,] |
|
32 |
table(df$year,df$month) |
|
33 |
|
|
34 |
writeLines(paste("Tiling options will produce",nrow(tiles),"tiles and ",nrow(jobs),"tile-months. Current todo list is ",length(todo))) |
|
35 |
|
|
36 |
|
|
37 |
## drop some if not complete |
|
38 |
#df=df[df$month%in%1:9&df$year%in%c(2001:2012),] |
|
39 |
rerun=F # set to true to recalculate all dates even if file already exists |
|
40 |
|
|
41 |
## Loop over existing months to build composite netcdf files |
|
42 |
foreach(date=unique(df$date)) %dopar% { |
|
43 |
## get date |
|
44 |
print(date) |
|
45 |
## Define output and check if it already exists |
|
46 |
vrtfile=paste(tempdir,"/mod09_",date,".vrt",sep="") |
|
47 |
ncfile=paste(tempdir,"/mod09_",date,".nc",sep="") |
|
48 |
tffile=paste(tempdir,"/mod09_",date,".tif",sep="") |
|
49 |
|
|
50 |
if(!rerun&file.exists(ncfile)) return(NA) |
|
51 |
## merge regions to a new netcdf file |
|
52 |
# system(paste("gdal_merge.py -o ",tffile," -init -32768 -n -32768.000 -ot Int16 ",paste(df$path[df$date==date],collapse=" "))) |
|
53 |
system(paste("gdalbuildvrt -overwrite -srcnodata -32768 -vrtnodata -32768 ",vrtfile," ",paste(df$path[df$date==date],collapse=" "))) |
|
54 |
## Warp to WGS84 grid and convert to netcdf |
|
55 |
##ops="-t_srs 'EPSG:4326' -multi -r cubic -te -180 0 180 10 -tr 0.008333333333333 -0.008333333333333 -wo SOURCE_EXTRA=50" #-wo SAMPLE_GRID=YES -wo SAMPLE_STEPS=100 |
|
56 |
ops="-t_srs 'EPSG:4326' -multi -r cubic -te -180 -90 180 90 -tr 0.008333333333333 -0.008333333333333 -wo SOURCE_EXTRA=50" |
|
57 |
|
|
58 |
system(paste("gdalwarp -overwrite ",ops," -et 0 -srcnodata -32768 -dstnodata -32768 ",vrtfile," ",tffile," -ot Int16")) |
|
59 |
system(paste("gdal_translate -of netCDF ",tffile," ",ncfile)) |
|
60 |
# system(paste("gdalwarp -overwrite ",ops," -srcnodata -32768 -dstnodata -32768 -of netCDF ",vrtfile," ",tffile," -ot Int16")) |
|
61 |
file.remove(tffile) |
|
62 |
setwd(wd) |
|
63 |
system(paste("ncecat -O -u time ",ncfile," ",ncfile,sep="")) |
|
64 |
## create temporary nc file with time information to append to MOD06 data |
|
65 |
cat(paste(" |
|
66 |
netcdf time { |
|
67 |
dimensions: |
|
68 |
time = 1 ; |
|
69 |
variables: |
|
70 |
int time(time) ; |
|
71 |
time:units = \"days since 2000-01-01 00:00:00\" ; |
|
72 |
time:calendar = \"gregorian\"; |
|
73 |
time:long_name = \"time of observation\"; |
|
74 |
data: |
|
75 |
time=",as.integer(date-as.Date("2000-01-01")),"; |
|
76 |
}"),file=paste(tempdir,"/",date,"_time.cdl",sep="")) |
|
77 |
system(paste("ncgen -o ",tempdir,"/",date,"_time.nc ",tempdir,"/",date,"_time.cdl",sep="")) |
|
78 |
system(paste("ncks -A ",tempdir,"/",date,"_time.nc ",ncfile,sep="")) |
|
79 |
## add other attributes |
|
80 |
system(paste("ncrename -v Band1,CF ",ncfile,sep="")) |
|
81 |
system(paste("ncatted ", |
|
82 |
" -a units,CF,o,c,\"%\" ", |
|
83 |
# " -a valid_range,CF,o,b,\"0,100\" ", |
|
84 |
" -a scale_factor,CF,o,f,\"0.1\" ", |
|
85 |
" -a _FillValue,CF,o,f,\"-32768\" ", |
|
86 |
" -a long_name,CF,o,c,\"Cloud Frequency(%)\" ", |
|
87 |
" -a NETCDF_VARNAME,CF,o,c,\"Cloud Frequency(%)\" ", |
|
88 |
" -a title,global,o,c,\"Cloud Climatology from MOD09 Cloud Mask\" ", |
|
89 |
" -a institution,global,o,c,\"Jetz Lab, EEB, Yale University, New Haven, CT\" ", |
|
90 |
" -a source,global,o,c,\"Derived from MOD09GA Daily Data\" ", |
|
91 |
" -a comment,global,o,c,\"Developed by Adam M. Wilson (adam.wilson@yale.edu / http://adamwilson.us)\" ", |
|
92 |
ncfile,sep="")) |
|
93 |
|
|
94 |
## add the fillvalue attribute back (without changing the actual values) |
|
95 |
#system(paste("ncatted -a _FillValue,CF,o,b,-32768 ",ncfile,sep="")) |
|
96 |
|
|
97 |
if(as.numeric(system(paste("cdo -s ntime ",ncfile),intern=T))<1) { |
|
98 |
print(paste(ncfile," has no time, deleting")) |
|
99 |
file.remove(ncfile) |
|
100 |
} |
|
101 |
print(paste(basename(ncfile)," Finished")) |
|
102 |
|
|
103 |
|
|
104 |
} |
|
105 |
|
|
106 |
|
|
107 |
### merge all the tiles to a single global composite |
|
108 |
#system(paste("ncdump -h ",list.files(tempdir,pattern="mod09.*.nc$",full=T)[10])) |
|
109 |
file.remove("tmp/mod09_2000-01-15.nc") |
|
110 |
system(paste("cdo -O mergetime -setrtomiss,-32768,-1 ",paste(list.files(tempdir,pattern="mod09.*.nc$",full=T),collapse=" ")," data/cloud_monthly.nc")) |
|
111 |
|
|
112 |
# Overall mean |
|
113 |
system(paste("cdo -O timmean data/cloud_monthly.nc data/cloud_mean.nc")) |
|
114 |
|
|
115 |
### generate the monthly mean and sd |
|
116 |
#system(paste("cdo -P 10 -O merge -ymonmean data/mod09.nc -chname,CF,CF_sd -ymonstd data/mod09.nc data/mod09_clim.nc")) |
|
117 |
system(paste("cdo -f nc4c -O -ymonmean data/cloud_monthly.nc data/cloud_ymonmean.nc")) |
|
118 |
|
|
119 |
|
|
120 |
## Seasonal Means |
|
121 |
system(paste("cdo -f nc4c -O -yseasmean data/cloud_monthly.nc data/cloud_yseasmean.nc")) |
|
122 |
system(paste("cdo -f nc4c -O -yseasstd data/cloud_monthly.nc data/cloud_yseasstd.nc")) |
|
123 |
|
|
124 |
## standard deviations, had to break to limit memory usage |
|
125 |
system(paste("cdo -f nc4c -O -chname,CF,CF_sd -ymonstd -selmon,1,2,3,4,5,6 data/cloud_monthly.nc data/cloud_ymonsd_1-6.nc")) |
|
126 |
system(paste("cdo -f nc4c -O -chname,CF,CF_sd -ymonstd -selmon,7,8,9,10,11,12 data/cloud_monthly.nc data/cloud_ymonsd_7-12.nc")) |
|
127 |
system(paste("cdo -f nc4c -O mergetime data/cloud_ymonsd_1-6.nc data/cloud_ymonsd_7-12.nc data/cloud_ymonstd.nc")) |
|
128 |
|
|
129 |
|
|
130 |
#if(!file.exists("data/mod09_metrics.nc")) { |
|
131 |
system("cdo -f nc4c timmin data/cloud_ymonmean.nc data/cloud_min.nc") |
|
132 |
system("cdo -f nc4c timmax data/cloud_ymonmean.nc data/cloud_max.nc") |
|
133 |
system("cdo -f nc4c -chname,CF,CFsd -timstd data/cloud_ymonmean.nc data/cloud_std.nc") |
|
134 |
# system("cdo -f nc2 merge data/mod09_std.nc data/mod09_min.nc data/cloud_max.nc data/cloud_metrics.nc") |
|
135 |
# system("cdo merge -chname,CF,CFmin -timmin data/cloud_ymonmean.nc -chname,CF,CFmax -timmax data/cloud_ymonmean.nc -chname,CF,CFsd -timstd data/cloud_ymonmean.nc data/cloud_metrics.nc") |
|
136 |
#} |
|
137 |
|
|
138 |
|
|
139 |
# Regressions through time by season |
|
140 |
s=c("DJF","MAM","JJA","SON") |
|
141 |
|
|
142 |
system(paste("cdo -f nc4c -O regres -selseas,",s[1]," data/cloud_monthly.nc data/slope_",s[1],".nc",sep="")) |
|
143 |
system(paste("cdo -f nc4c -O regres -selseas,",s[2]," data/cloud_monthly.nc data/slope_",s[2],".nc",sep="")) |
|
144 |
system(paste("cdo -f nc4c -O regres -selseas,",s[3]," data/cloud_monthly.nc data/slope_",s[3],".nc",sep="")) |
|
145 |
system(paste("cdo -f nc4c -O regres -selseas,",s[4]," data/cloud_monthly.nc data/slope_",s[4],".nc",sep="")) |
|
146 |
|
|
147 |
|
|
148 |
|
|
149 |
## Daily animations |
|
150 |
regs=list( |
|
151 |
Venezuela=extent(c(-69,-59,0,7)), |
|
152 |
Cascades=extent(c(-122.8,-118,44.9,47)), |
|
153 |
Hawaii=extent(c(-156.5,-154,18.75,20.5)), |
|
154 |
Boliva=extent(c(-71,-63,-20,-15)), |
|
155 |
CFR=extent(c(17.75,22.5,-34.8,-32.6)), |
|
156 |
Madagascar=extent(c(46,52,-17,-12)) |
|
157 |
) |
|
158 |
|
|
159 |
r=1 |
|
160 |
|
|
161 |
system(paste("cdo -f nc4c -O inttime,2012-01-15,12:00:00,1day -sellonlatbox,", |
|
162 |
paste(regs[[r]]@xmin,regs[[r]]@xmax,regs[[r]]@ymin,regs[[r]]@ymax,sep=","), |
|
163 |
" data/cloud_monthly.nc data/daily_",names(regs[r]),".nc",sep="")) |
|
164 |
|
|
165 |
|
|
166 |
|
|
167 |
|
|
168 |
### Long term summaries |
|
169 |
seasconc <- function(x,return.Pc=T,return.thetat=F) { |
|
170 |
################################################################################################# |
|
171 |
## Precipitation Concentration function |
|
172 |
## This function calculates Precipitation Concentration based on Markham's (1970) technique as described in Schulze (1997) |
|
173 |
## South Africa Atlas of Agrohydology and Climatology - R E Schulze, M Maharaj, S D Lynch, B J Howe, and B Melvile-Thomson |
|
174 |
## Pages 37-38 |
|
175 |
################################################################################################# |
|
176 |
## x is a vector of precipitation quantities - the mean for each factor in "months" will be taken, |
|
177 |
## so it does not matter if the data are daily or monthly, as long as the "months" factor correctly |
|
178 |
## identifies them into 12 monthly bins, collapse indicates whether the data are already summarized as monthly means. |
|
179 |
################################################################################################# |
|
180 |
theta=seq(30,360,30)*(pi/180) # set up angles for each month & convert to radians |
|
181 |
if(sum(is.na(x))==12) { return(cbind(Pc=NA,thetat=NA)) ; stop} |
|
182 |
if(return.Pc) { |
|
183 |
rt=sqrt(sum(x * cos(theta))^2 + sum(x * sin(theta))^2) # the magnitude of the summation |
|
184 |
Pc=as.integer(round((rt/sum(x))*100))} |
|
185 |
if(return.thetat){ |
|
186 |
s1=sum(x*sin(theta),na.rm=T); s2=sum(x*cos(theta),na.rm=T) |
|
187 |
if(s1>=0 & s2>=0) {thetat=abs((180/pi)*(atan(sum(x*sin(theta),na.rm=T)/sum(x*cos(theta),na.rm=T))))} |
|
188 |
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))))} |
|
189 |
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))))} |
|
190 |
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))))} |
|
191 |
thetat=as.integer(round(thetat)) |
|
192 |
} |
|
193 |
if(return.thetat&return.Pc) return(c(conc=Pc,theta=thetat)) |
|
194 |
if(return.Pc) return(Pc) |
|
195 |
if(return.thetat) return(thetat) |
|
196 |
} |
|
197 |
|
|
198 |
|
|
199 |
|
|
200 |
## read in monthly dataset |
|
201 |
mod09=brick("data/cloud_ymonmean.nc",varname="CF") |
|
202 |
plot(mod09[1]) |
|
203 |
|
|
204 |
mod09_seas=calc(mod09,seasconc,return.Pc=T,return.thetat=F,overwrite=T,filename="data/mod09_seas.nc",NAflag=255,datatype="INT1U") |
|
205 |
mod09_seas2=calc(mod09,seasconc,return.Pc=F,return.thetat=T,overwrite=T,filename="data/mod09_seas_theta.nc",datatype="INT1U") |
|
206 |
|
|
207 |
plot(mod09_seas) |
climate/research/cloud/MOD09/ee/ee_download.R | ||
---|---|---|
1 |
library(doMC) |
|
2 |
library(foreach) |
|
3 |
registerDoMC(4) |
|
4 |
|
|
5 |
wd="~/acrobates/adamw/projects/cloud" |
|
6 |
setwd(wd) |
|
7 |
|
|
8 |
### Build Tiles |
|
9 |
|
|
10 |
## bin sizes in degrees |
|
11 |
ybin=30 |
|
12 |
xbin=30 |
|
13 |
|
|
14 |
tiles=expand.grid(ulx=seq(-180,180-xbin,by=xbin),uly=seq(90,-90+ybin,by=-ybin)) |
|
15 |
tiles$h=factor(tiles$ulx,labels=paste("h",sprintf("%02d",1:length(unique(tiles$ulx))),sep="")) |
|
16 |
tiles$v=factor(tiles$uly,labels=paste("v",sprintf("%02d",1:length(unique(tiles$uly))),sep="")) |
|
17 |
tiles$tile=paste(tiles$h,tiles$v,sep="") |
|
18 |
tiles$urx=tiles$ulx+xbin |
|
19 |
tiles$ury=tiles$uly |
|
20 |
tiles$lrx=tiles$ulx+xbin |
|
21 |
tiles$lry=tiles$uly-ybin |
|
22 |
tiles$llx=tiles$ulx |
|
23 |
tiles$lly=tiles$uly-ybin |
|
24 |
tiles$cy=(tiles$uly+tiles$lry)/2 |
|
25 |
tiles$cx=(tiles$ulx+tiles$urx)/2 |
|
26 |
tiles=tiles[,c("tile","h","v","ulx","uly","urx","ury","lrx","lry","llx","lly","cx","cy")] |
|
27 |
|
|
28 |
jobs=expand.grid(tile=tiles$tile,year=2000:2012,month=1:12) |
|
29 |
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")] |
|
30 |
|
|
31 |
## drop Janurary 2000 from list (pre-modis) |
|
32 |
jobs=jobs[!(jobs$year==2000&jobs$month==1),] |
|
33 |
|
|
34 |
|
|
35 |
## Run the python downloading script |
|
36 |
#system("~/acrobates/adamw/projects/environmental-layers/climate/procedures/ee.MOD09.py -projwin -159 20 -154.5 18.5 -year 2001 -month 6 -region test") |
|
37 |
i=1 |
|
38 |
todo=1:nrow(jobs) |
|
39 |
|
|
40 |
## Get list of available files |
|
41 |
df=data.frame(path=list.files("/mnt/data2/projects/cloud/mod09",pattern="*.tif$",full=T,recur=T),stringsAsFactors=F) |
|
42 |
df[,c("region","year","month")]=do.call(rbind,strsplit(basename(df$path),"_|[.]"))[,c(1,2,3)] |
|
43 |
df$date=as.Date(paste(df$year,"_",df$month,"_15",sep=""),"%Y_%m_%d") |
|
44 |
|
|
45 |
table(df$year,df$month) |
|
46 |
|
|
47 |
|
|
48 |
checkcomplete=T |
|
49 |
if(checkcomplete&exists("df")){ #if desired (and "df" exists from below) drop complete date-tiles |
|
50 |
todo=which(!paste(jobs$tile,jobs$year,jobs$month)%in%paste(df$region,df$year,df$month)) |
|
51 |
} |
|
52 |
|
|
53 |
|
|
54 |
writeLines(paste("Tiling options will produce",nrow(tiles),"tiles and ",nrow(jobs),"tile-months. Current todo list is ",length(todo))) |
|
55 |
|
|
56 |
t=foreach(i=todo,.inorder=FALSE,.verbose=F) %dopar%{ |
|
57 |
system(paste("python ~/acrobates/adamw/projects/environmental-layers/climate/procedures/ee.MOD09.py -projwin ", |
|
58 |
jobs$ulx[i]," ",jobs$uly[i]," ",jobs$urx[i]," ",jobs$ury[i]," ",jobs$lrx[i]," ",jobs$lry[i]," ",jobs$llx[i]," ",jobs$lly[i]," ", |
|
59 |
" -year ",jobs$year[i]," -month ",jobs$month[i]," -region ",jobs$tile[i],sep="")) |
|
60 |
} |
|
61 |
|
|
62 |
|
|
63 |
|
|
64 |
|
|
65 |
|
climate/research/cloud/MODIS_Cloud.py | ||
---|---|---|
1 |
import ee |
|
2 |
from ee import mapclient |
|
3 |
|
|
4 |
import logging |
|
5 |
logging.basicConfig() |
|
6 |
|
|
7 |
MY_SERVICE_ACCOUNT = '511722844190@developer.gserviceaccount.com' # replace with your service account |
|
8 |
MY_PRIVATE_KEY_FILE = '/Users/adamw/EarthEngine-privatekey.p12' # replace with you private key file path |
|
9 |
|
|
10 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
11 |
|
|
12 |
#// EVI_Cloud_month |
|
13 |
|
|
14 |
#// Make land mask |
|
15 |
#// Select the forest classes from the MODIS land cover image and intersect them |
|
16 |
#// with elevations above 1000m. |
|
17 |
elev = ee.Image('srtm90_v4'); |
|
18 |
cover = ee.Image('MCD12Q1/MCD12Q1_005_2001_01_01').select('Land_Cover_Type_1'); |
|
19 |
blank = ee.Image(0); |
|
20 |
#// Where (cover == 0) and (elev > 0), set the output to 1. |
|
21 |
land = blank.where( |
|
22 |
cover.neq(0).and(cover.neq(15)),//.and(elev.gt(0)), |
|
23 |
1); |
|
24 |
|
|
25 |
palette = ["aec3d4", // water |
|
26 |
"152106", "225129", "369b47", "30eb5b", "387242", // forest |
|
27 |
"6a2325", "c3aa69", "b76031", "d9903d", "91af40", // shrub, grass, savanah |
|
28 |
"111149", // wetlands |
|
29 |
"cdb33b", // croplands |
|
30 |
"cc0013", // urban |
|
31 |
"33280d", // crop mosaic |
|
32 |
"d7cdcc", // snow and ice |
|
33 |
"f7e084", // barren |
|
34 |
"6f6f6f"].join(',');// tundra |
|
35 |
|
|
36 |
#// make binary map for forest/nonforest |
|
37 |
forest = blank.where(cover.gte(1).and(cover.lte(5)),1); |
|
38 |
|
|
39 |
#//addToMap(forest, {min: 0, max: 1}); |
|
40 |
#//addToMap(cover, {min: 0, max: 17, palette:palette}); |
|
41 |
|
|
42 |
#// MODIS EVI Collection |
|
43 |
collection = ee.ImageCollection("MCD43A4_EVI"); |
|
44 |
|
|
45 |
#//define reducers and filters |
|
46 |
COUNT = ee.call("Reducer.count"); |
|
47 |
#// Loop through months and get monthly % cloudiness |
|
48 |
#//for (var month = 1; month < 2; month += 1) { |
|
49 |
#//month=1; |
|
50 |
FilterMonth = ee.Filter(ee.call("Filter.calendarRange", |
|
51 |
start=month,end=month,field="month")); |
|
52 |
tmonth=collection.filter(FilterMonth) |
|
53 |
|
|
54 |
n=tmonth.getInfo().features.length; #// Get total number of images |
|
55 |
print(n+" Layers in the collection for month "+month) |
|
56 |
tcloud=tmonth.reduce(COUNT).float() |
|
57 |
c=ee.Image(n); #// make raster with constant value of n |
|
58 |
c1=ee.Image(-1); #// make raster with constant value of -1 to convert to % cloudy |
|
59 |
|
|
60 |
#///////////////////////////////////////////////// |
|
61 |
#// Generate the cloud frequency surface: |
|
62 |
#// 1 Calculate the number of days with measurements |
|
63 |
#// 2 divide by the total number of layers |
|
64 |
#// 3 Add -1 and multiply by -1 to invert to % cloudy |
|
65 |
#// 4 Rename to "PCloudy_month" |
|
66 |
tcloud = tcloud.divide(c).add(c1).multiply(c1).expression("b()*100").int8().select_([0],["PCloudy_"+month]); |
|
67 |
#//if(month==1) {var cloud=tcloud} // if first year, make new object |
|
68 |
#//if(month>1) {var cloud=cloud.addBands(tcloud)} // if not first year, append to first year |
|
69 |
#//} //end loop over months |
|
70 |
# // end loop over years |
|
71 |
|
|
72 |
|
|
73 |
#//print(evi_miss.stats()) |
|
74 |
#//addToMap(tcloud,{min:0,max:100,palette:"000000,00FF00,FF0000"}); |
|
75 |
#//addToMap(elev,{min:0,max:2500,palette:"000000,00FF00,FF0000"}); |
|
76 |
|
|
77 |
#//centerMap(-122.418, 37.72, 10); |
|
78 |
path = tcloud.getDownloadURL({ |
|
79 |
'scale': 1000, |
|
80 |
'crs': 'EPSG:4326', |
|
81 |
'region': '[[-90, 0], [-90, 20], [-50, 0], [-50, 20]]' //h11v08 |
|
82 |
#// 'region': '[[-180, -90], [-180, 90], [180, -90], [180, 90]]' |
|
83 |
}); |
|
84 |
print('https://earthengine.googleapis.com' + path); |
|
85 |
|
climate/research/cloud/NDP-026D.R | ||
---|---|---|
1 |
### Script to download and process the NDP-026D station cloud dataset |
|
2 |
### to validate MODIS cloud frequencies |
|
3 |
|
|
4 |
setwd("~/acrobates/adamw/projects/cloud/data/NDP026D") |
|
5 |
|
|
6 |
library(multicore) |
|
7 |
library(doMC) |
|
8 |
library(rasterVis) |
|
9 |
library(rgdal) |
|
10 |
library(reshape) |
|
11 |
|
|
12 |
|
|
13 |
## Data available here http://cdiac.ornl.gov/epubs/ndp/ndp026d/ndp026d.html |
|
14 |
|
|
15 |
## Get station locations |
|
16 |
system("wget -N -nd http://cdiac.ornl.gov/ftp/ndp026d/cat01/01_STID -P data/") |
|
17 |
st=read.table("data/01_STID",skip=1) |
|
18 |
colnames(st)=c("StaID","LAT","LON","ELEV","ny1","fy1","ly1","ny7","fy7","ly7","SDC","b5c") |
|
19 |
st$lat=st$LAT/100 |
|
20 |
st$lon=st$LON/100 |
|
21 |
st$lon[st$lon>180]=st$lon[st$lon>180]-360 |
|
22 |
st=st[,c("StaID","ELEV","lat","lon")] |
|
23 |
colnames(st)=c("id","elev","lat","lon") |
|
24 |
write.csv(st,"stations.csv",row.names=F) |
|
25 |
coordinates(st)=c("lon","lat") |
|
26 |
projection(st)="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" |
|
27 |
st@data[,c("lon","lat")]=coordinates(st) |
|
28 |
|
|
29 |
## download data |
|
30 |
system("wget -N -nd ftp://cdiac.ornl.gov/pub/ndp026d/cat67_78/* -A '.tc.Z' -P data/") |
|
31 |
|
|
32 |
system("gunzip data/*.Z") |
|
33 |
|
|
34 |
## define FWF widths |
|
35 |
f162=c(5,5,4,7,7,7,4) #format 162 |
|
36 |
c162=c("StaID","YR","Nobs","Amt","Fq","AWP","NC") |
|
37 |
|
|
38 |
## use monthly timeseries |
|
39 |
cld=do.call(rbind.data.frame,mclapply(sprintf("%02d",1:12),function(m) { |
|
40 |
d=read.fwf(list.files("data",pattern=paste("MNYDC.",m,".tc$",sep=""),full=T),skip=1,widths=f162) |
|
41 |
colnames(d)=c162 |
|
42 |
d$month=as.numeric(m) |
|
43 |
print(m) |
|
44 |
return(d)} |
|
45 |
)) |
|
46 |
|
|
47 |
## add lat/lon |
|
48 |
cld[,c("lat","lon")]=coordinates(st)[match(cld$StaID,st$id),] |
|
49 |
|
|
50 |
## drop missing values |
|
51 |
cld=cld[,!grepl("Fq|AWP|NC",colnames(cld))] |
|
52 |
cld$Amt[cld$Amt<0]=NA |
|
53 |
cld$Amt=cld$Amt/100 |
|
54 |
|
|
55 |
## calculate means and sds for full record (1970-2009) |
|
56 |
Nobsthresh=20 #minimum number of observations to include |
|
57 |
|
|
58 |
cldm=do.call(rbind.data.frame,by(cld,list(month=as.factor(cld$month),StaID=as.factor(cld$StaID)),function(x){ |
|
59 |
data.frame( |
|
60 |
month=x$month[1], |
|
61 |
StaID=x$StaID[1], |
|
62 |
cld_all=mean(x$Amt[x$Nobs>=Nobsthresh],na.rm=T), # full record |
|
63 |
cldsd_all=sd(x$Amt[x$Nobs>=Nobsthresh],na.rm=T), |
|
64 |
cld=mean(x$Amt[x$YR>=2000&x$Nobs>=Nobsthresh],na.rm=T), #only MODIS epoch |
|
65 |
cldsd=sd(x$Amt[x$YR>=2000&x$Nobs>=Nobsthresh],na.rm=T))})) |
|
66 |
cldm[,c("lat","lon")]=coordinates(st)[match(cldm$StaID,st$id),c("lat","lon")] |
|
67 |
|
|
68 |
|
|
69 |
|
|
70 |
## add the MOD09 data to cld |
|
71 |
#### Evaluate MOD35 Cloud data |
|
72 |
mod09=brick("~/acrobates/adamw/projects/cloud/data/cloud_ymonmean.nc") |
|
73 |
mod09std=brick("~/acrobates/adamw/projects/cloud/data/cloud_ymonstd.nc") |
|
74 |
|
|
75 |
## overlay the data with 32km diameter (16km radius) buffer |
|
76 |
## buffer size from Dybbroe, et al. (2005) doi:10.1175/JAM-2189.1. |
|
77 |
buf=16000 |
|
78 |
bins=cut(st$lat,10) |
|
79 |
rerun=F |
|
80 |
if(rerun&file.exists("valid.csv")) file.remove("valid.csv") |
|
81 |
mod09sta=lapply(levels(bins),function(lb) { |
|
82 |
l=which(bins==lb) |
|
83 |
## mean |
|
84 |
td=extract(mod09,st[l,],buffer=buf,fun=mean,na.rm=T,df=T) |
|
85 |
td$id=st$id[l] |
|
86 |
td$type="mean" |
|
87 |
## std |
|
88 |
td2=extract(mod09std,st[l,],buffer=buf,fun=mean,na.rm=T,df=T) |
|
89 |
td2$id=st$id[l] |
|
90 |
td2$type="sd" |
|
91 |
print(lb)#as.vector(c(l,td[,1:4]))) |
|
92 |
write.table(rbind(td,td2),"valid.csv",append=T,col.names=F,quote=F,sep=",",row.names=F) |
|
93 |
td |
|
94 |
})#,mc.cores=3) |
|
95 |
|
|
96 |
## read it back in |
|
97 |
mod09st=read.csv("valid.csv",header=F)[,-c(1)] |
|
98 |
colnames(mod09st)=c(names(mod09),"id","type") |
|
99 |
mod09stl=melt(mod09st,id.vars=c("id","type")) |
|
100 |
mod09stl[,c("year","month")]=do.call(rbind,strsplit(sub("X","",mod09stl$variable),"[.]"))[,1:2] |
|
101 |
mod09stl$value[mod09stl$value<0]=NA |
|
102 |
mod09stl=cast(mod09stl,id+year+month~type,value="value") |
|
103 |
|
|
104 |
## add it to cld |
|
105 |
cldm$mod09=mod09stl$mean[match(paste(cldm$StaID,cldm$month),paste(mod09stl$id,as.numeric(mod09stl$month)))] |
|
106 |
cldm$mod09sd=mod09stl$sd[match(paste(cldm$StaID,cldm$month),paste(mod09stl$id,as.numeric(mod09stl$month)))] |
|
107 |
|
|
108 |
|
|
109 |
## LULC |
|
110 |
#system(paste("gdalwarp -r near -co \"COMPRESS=LZW\" -tr ",paste(res(mod09),collapse=" ",sep=""), |
|
111 |
# "-tap -multi -t_srs \"", projection(mod09),"\" /mnt/data/jetzlab/Data/environ/global/landcover/MODIS/MCD12Q1_IGBP_2005_v51.tif ../modis/mod12/MCD12Q1_IGBP_2005_v51.tif")) |
|
112 |
lulc=raster("~/acrobates/adamw/projects/interp/data/modis/mod12/MCD12Q1_IGBP_2005_v51.tif") |
|
113 |
require(plotKML); data(worldgrids_pal) #load IGBP palette |
|
114 |
IGBP=data.frame(ID=0:16,col=worldgrids_pal$IGBP[-c(18,19)],stringsAsFactors=F) |
|
115 |
IGBP$class=rownames(IGBP);rownames(IGBP)=1:nrow(IGBP) |
|
116 |
levels(lulc)=list(IGBP) |
|
117 |
## function to get modal lulc value |
|
118 |
Mode <- function(x) { |
|
119 |
ux <- na.omit(unique(x)) |
|
120 |
ux[which.max(tabulate(match(x, ux)))] |
|
121 |
} |
|
122 |
lulcst=extract(lulc,st,fun=Mode,buffer=buf,df=T) |
|
123 |
colnames(lulcst)=c("id","lulc") |
|
124 |
## add it to cld |
|
125 |
cldm$lulc=lulcst$lulc[match(cldm$StaID,lulcst$id)] |
|
126 |
cldm$lulcc=IGBP$class[match(cldm$lulc,IGBP$ID)] |
|
127 |
|
|
128 |
|
|
129 |
### Add biome data |
|
130 |
if(!file.exists("../teow/biomes.shp")){ |
|
131 |
teow=readOGR("/mnt/data/jetzlab/Data/environ/global/teow/official/","wwf_terr_ecos") |
|
132 |
teow=teow[teow$BIOME<90,] |
|
133 |
biome=unionSpatialPolygons(teow,teow$BIOME, threshold=5) |
|
134 |
biomeid=read.csv("/mnt/data/jetzlab/Data/environ/global/teow/official/biome.csv",stringsAsFactors=F) |
|
135 |
biome=SpatialPolygonsDataFrame(biome,data=biomeid[as.numeric(row.names(biome)),]) |
|
136 |
writeOGR(biome,"../teow","biomes",driver="ESRI Shapefile",overwrite=T) |
|
137 |
} |
|
138 |
biome=readOGR("../teow/","biomes") |
|
139 |
projection(biome)=projection(st) |
|
140 |
#st$biome=over(st,biome,returnList=F)$BiomeID |
|
141 |
dists=apply(gDistance(st,biome,byid=T),2,which.min) |
|
142 |
st$biome=biome$BiomeID[dists] |
|
143 |
|
|
144 |
cldm$biome=st$biome[match(cldm$StaID,st$id)] |
|
145 |
|
|
146 |
|
|
147 |
## write out the tables |
|
148 |
write.csv(cld,file="cld.csv",row.names=F) |
|
149 |
write.csv(cldm,file="cldm.csv",row.names=F) |
|
150 |
writeOGR(st,dsn=".",layer="stations",driver="ESRI Shapefile",overwrite_layer=T) |
|
151 |
######################################################################### |
|
152 |
|
climate/research/cloud/ee/EE_simple.py | ||
---|---|---|
1 |
import ee |
|
2 |
from ee import mapclient |
|
3 |
|
|
4 |
import logging |
|
5 |
logging.basicConfig() |
|
6 |
|
|
7 |
MY_SERVICE_ACCOUNT = '511722844190@developer.gserviceaccount.com' # replace with your service account |
|
8 |
MY_PRIVATE_KEY_FILE = '/Users/adamw/EarthEngine-privatekey.p12' # replace with you private key file path |
|
9 |
|
|
10 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
image = ee.Image('srtm90_v4') |
|
15 |
map = ee.mapclient.MapClient() |
|
16 |
map.addOverlay(mapclient.MakeOverlay(image.getMapId({'min': 0, 'max': 3000}))) |
climate/research/cloud/ee/MODISLANDObservationFrequency.js | ||
---|---|---|
1 |
// MODIS LAND Observation Frequency |
|
2 |
|
|
3 |
// Proportion of days in the month with at least 1 MODIS observation |
|
4 |
var p_07 = ee.ImageCollection("MOD09GA"). |
|
5 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
6 |
filter(ee.Filter.calendarRange(7,7,"month")).map(function(img) { |
|
7 |
return img.select(['num_observations_1km']).gte(1)}).mean().multiply(ee.Image(100)).select([0],["p07"]); |
|
8 |
|
|
9 |
// mean number of observations per day |
|
10 |
var n_07 = ee.ImageCollection("MOD09GA"). |
|
11 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
12 |
filter(ee.Filter.calendarRange(7,7,"month")).map(function(img) { |
|
13 |
return img.select(['num_observations_1km'])}).mean().select([0],["n07"]); |
|
14 |
|
|
15 |
var n_12 = ee.ImageCollection("MOD09GA"). |
|
16 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
17 |
filter(ee.Filter.calendarRange(12,12,"month")).map(function(img) { |
|
18 |
return img.select(['num_observations_1km']).gte(1)}).mean().multiply(ee.Image(100)).select([0],["p12"]); |
|
19 |
|
|
20 |
// mean number of observations per day |
|
21 |
var p_12 = ee.ImageCollection("MOD09GA"). |
|
22 |
filter(ee.Filter.calendarRange(2011,2012,"year")). |
|
23 |
filter(ee.Filter.calendarRange(12,12,"month")).map(function(img) { |
|
24 |
return img.select(['num_observations_1km'])}).mean().select([0],["n12"]); |
|
25 |
|
|
26 |
// Combine anything into image for download |
|
27 |
var image=n_07.addBands(p_07).addBands(n_12).addBands(p_12) |
|
28 |
//var reproj = image.reproject('EPSG:4326', [0.008333333333, 0, -180, 0, -0.008333333333, -90]) |
|
29 |
|
|
30 |
//var palette="000000,00FF00,FF0000" |
|
31 |
//addToMap(image.select([0]),{min:0,max:100,palette:palette},"July"); |
|
32 |
//addToMap(n_12,{min:0,max:100,palette:palette},"Decenber"); |
|
33 |
|
|
34 |
|
|
35 |
var driveFolder="EarthEngineOutput" |
|
36 |
|
|
37 |
exportImage(image, |
|
38 |
'PObs', |
|
39 |
{'name': 'PObs', |
|
40 |
'maxPixels':1000000000, |
|
41 |
'driveFolder':driveFolder, |
|
42 |
'crs': 'EPSG:4326', //4326 |
|
43 |
'crsTransform':[0.008333333333, 0, -180, 0, -0.008333333333, -90], |
|
44 |
// 'scale': 0.008333333333, |
|
45 |
'region': '[[-180, -89], [-180, 89], [180, 89], [180, -89]]' //global |
|
46 |
// 'region': '[[-180, 0], [-180, 10], [180, 10], [180, 0]]' // |
|
47 |
}); |
climate/research/cloud/ee/README.txt | ||
---|---|---|
1 |
This folder holds scripts related to work on Google Earth Engine, primarily for processing MODIS cloud data. |
climate/research/cloud/ee/ee.MOD09.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
|
|
3 |
## Example script that downloads data from Google Earth Engine using the python API |
|
4 |
## MODIS MOD09GA data is processed to extract the MOD09 cloud flag and calculate monthly cloud frequency |
|
5 |
|
|
6 |
|
|
7 |
## import some libraries |
|
8 |
import ee |
|
9 |
from ee import mapclient |
|
10 |
import ee.mapclient |
|
11 |
import datetime |
|
12 |
import wget |
|
13 |
import os |
|
14 |
import sys |
|
15 |
import subprocess |
|
16 |
import time |
|
17 |
|
|
18 |
import logging |
|
19 |
logging.basicConfig(filename='error.log',level=logging.DEBUG) |
|
20 |
|
|
21 |
def Usage(): |
|
22 |
print('Usage: ee.MOD9.py -projwin ulx uly urx ury lrx lry llx lly -year year -month month -regionname 1') |
|
23 |
sys.exit( 1 ) |
|
24 |
|
|
25 |
ulx = float(sys.argv[2]) |
|
26 |
uly = float(sys.argv[3]) |
|
27 |
urx = float(sys.argv[4]) |
|
28 |
ury = float(sys.argv[5]) |
|
29 |
lrx = float(sys.argv[6]) |
|
30 |
lry = float(sys.argv[7]) |
|
31 |
llx = float(sys.argv[8]) |
|
32 |
lly = float(sys.argv[9]) |
|
33 |
year = int(sys.argv[11]) |
|
34 |
month = int(sys.argv[13]) |
|
35 |
regionname = str(sys.argv[15]) |
|
36 |
#``` |
|
37 |
#ulx=-159 |
|
38 |
#uly=20 |
|
39 |
#lrx=-154.5 |
|
40 |
#lry=18.5 |
|
41 |
#year=2001 |
|
42 |
#month=6 |
|
43 |
#``` |
|
44 |
## Define output filename |
|
45 |
output=regionname+'_'+str(year)+'_'+str(month) |
|
46 |
|
|
47 |
## set working directory (where files will be downloaded) |
|
48 |
cwd='/mnt/data2/projects/cloud/mod09/' |
|
49 |
## Wget always starts with a temporary file called "download", so move to a subdirectory to |
|
50 |
## prevent overwrting when parallel downloading |
|
51 |
if not os.path.exists(cwd+output): |
|
52 |
os.makedirs(cwd+output) |
|
53 |
os.chdir(cwd+output) |
|
54 |
|
|
55 |
# output filename |
|
56 |
unzippedfilename=output+".mod09.tif" |
|
57 |
# Check if file already exists and continue if so... |
|
58 |
if(os.path.exists(unzippedfilename)): |
|
59 |
sys.exit("File exists:"+output) |
|
60 |
|
|
61 |
## initialize GEE |
|
62 |
MY_SERVICE_ACCOUNT = '511722844190@developer.gserviceaccount.com' # replace with your service account |
|
63 |
MY_PRIVATE_KEY_FILE = '/home/adamw/EarthEngine-privatekey.p12' # replace with you private key file path |
|
64 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
65 |
|
|
66 |
## set map center to speed up viewing |
|
67 |
#ee.mapclient.centerMap(-121.767, 46.852, 11) |
|
68 |
|
|
69 |
#/////////////////////////////////// |
|
70 |
#// Function to extract cloud flags |
|
71 |
def getmod09(img): return(img.select(['state_1km']).expression("((b(0)/1024)%2)").gte(1)); |
|
72 |
|
|
73 |
#//////////////////////////////////////////////////// |
|
74 |
##################################################### |
|
75 |
# Processing Function |
|
76 |
# MOD09 internal cloud flag for this year-month |
|
77 |
# to filter by a date range: filterDate(datetime.datetime(yearstart,monthstart,1),datetime.datetime(yearstop,monthstop,31)) |
|
78 |
mod09 = ee.ImageCollection("MOD09GA").filter(ee.Filter.calendarRange(year,year,"year")).filter(ee.Filter.calendarRange(month,month,"month")).map(getmod09); |
|
79 |
# myd09 = ee.ImageCollection("MYD09GA").filter(ee.Filter.calendarRange(year,year,"year")).filter(ee.Filter.calendarRange(month,month,"month")).map(getmod09); |
|
80 |
# calculate mean cloudiness (%), rename band, multiply by 100, and convert to integer |
|
81 |
mod09a=mod09.mean().select([0], ['mod09']).multiply(ee.Image(1000)).int16(); |
|
82 |
# myd09a=myd09.mean().select([0], ['MYD09_'+str(year)+'_'+str(month)]).multiply(ee.Image(100)).int8(); |
|
83 |
## Set data equal to whatver you want downloaded |
|
84 |
data=mod09a |
|
85 |
###################################################### |
|
86 |
|
|
87 |
## define region for download |
|
88 |
region=[llx, lly],[lrx, lry],[urx, ury],[ulx,uly] #h11v08 |
|
89 |
strregion=str(list(region)) |
|
90 |
|
|
91 |
# add to plot to confirm it's working |
|
92 |
#ee.mapclient.addToMap(data, {'range': '0,100'}, 'MOD09') |
|
93 |
|
|
94 |
# build the URL and name the object (so that when it's unzipped we know what it is!) |
|
95 |
path =mod09a.getDownloadUrl({ |
|
96 |
'crs': 'SR-ORG:6974', # MODIS Sinusoidal |
|
97 |
'scale': '926.625433055833', # MODIS ~1km |
|
98 |
'name': output, # name the file (otherwise it will be a uninterpretable hash) |
|
99 |
'region': strregion # region defined above |
|
100 |
}); |
|
101 |
|
|
102 |
# print info to confirm there is data |
|
103 |
print(data.getInfo()) |
|
104 |
print(' Processing.... '+output+' Coords:'+strregion) |
|
105 |
print(path) |
|
106 |
|
|
107 |
#test=wget.download(path) |
|
108 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
109 |
print('download sucess for tile '+output+': '+str(test)) |
|
110 |
|
|
111 |
## Sometimes EE will serve a corrupt zipped file with no error |
|
112 |
# try to unzip it |
|
113 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
114 |
|
|
115 |
if zipstatus==0: #if sucessful, quit |
|
116 |
os.remove("mod09.zip") |
|
117 |
sys.exit("Finished: "+output) |
|
118 |
|
|
119 |
# if file doesn't exists or it didn't unzip, try again |
|
120 |
if zipstatus!=0: |
|
121 |
print("Zip Error for: "+output+"... Trying again (#2)") |
|
122 |
time.sleep(15) |
|
123 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
124 |
|
|
125 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
126 |
|
|
127 |
if zipstatus==0: #if sucessful, quit |
|
128 |
os.remove("mod09.zip") |
|
129 |
sys.exit("Finished: "+output) |
|
130 |
|
|
131 |
# if file doesn't exists or it didn't unzip, try again |
|
132 |
if zipstatus!=0: |
|
133 |
print("Zip Error for: "+output+"... Trying again (#3)") |
|
134 |
time.sleep(30) |
|
135 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
136 |
|
|
137 |
# try again #4 |
|
138 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
139 |
|
|
140 |
if zipstatus==0: #if sucessful, quit |
|
141 |
os.remove("mod09.zip") |
|
142 |
sys.exit("Finished: "+output) |
|
143 |
|
|
144 |
# if file doesn't exists or it didn't unzip, try again |
|
145 |
if zipstatus!=0: |
|
146 |
print("Zip Error for: "+output+"... Trying again (#4)") |
|
147 |
time.sleep(30) |
|
148 |
test=subprocess.call(['-c','-q','--timeout=0','--ignore-length','--no-http-keep-alive','-O','mod09.zip',path],executable='wget') |
|
149 |
|
|
150 |
zipstatus=subprocess.call("unzip -o mod09.zip",shell=True) |
|
151 |
|
|
152 |
if zipstatus==0: #if sucessful, quit |
|
153 |
os.remove("mod09.zip") |
|
154 |
sys.exit("Finished: "+output) |
|
155 |
|
|
156 |
## delete the zipped file (the unzipped version is kept) |
|
157 |
os.remove("mod09.zip") |
|
158 |
sys.exit("Zip Error for: "+output) |
|
159 |
|
|
160 |
|
climate/research/cloud/ee/ee.MOD09_parallel.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
|
|
3 |
## Example script that downloads data from Google Earth Engine using the python API |
|
4 |
## MODIS MOD09GA data is processed to extract the MOD09 cloud flag and calculate monthly cloud frequency |
|
5 |
|
|
6 |
## import some libraries |
|
7 |
import ee |
|
8 |
from ee import mapclient |
|
9 |
import ee.mapclient |
|
10 |
import datetime |
|
11 |
import wget |
|
12 |
import os |
|
13 |
import sys |
|
14 |
|
|
15 |
def Usage(): |
|
16 |
print('Usage: ee.MOD9.py -projwin ulx uly lrx lry -o output ') |
|
17 |
sys.exit( 1 ) |
|
18 |
|
|
19 |
ulx = float(sys.argv[2]) |
|
20 |
uly = float(sys.argv[3]) |
|
21 |
lrx = float(sys.argv[4]) |
|
22 |
lry = float(sys.argv[5]) |
|
23 |
output = sys.argv[7] |
|
24 |
|
|
25 |
print ( output , ulx ,uly ,lrx , lry ) |
|
26 |
|
|
27 |
#import logging |
|
28 |
|
|
29 |
MY_SERVICE_ACCOUNT = '364044830827-ubb6ja607b8j7t8m9uooi4c01vgah4ms@developer.gserviceaccount.com' # replace with your service account |
|
30 |
MY_PRIVATE_KEY_FILE = '/home/selv/GEE/fe3f13d90031e3eedaa9974baa6994e467b828f7-privatekey.p12' # replace with you private key file path |
|
31 |
ee.Initialize(ee.ServiceAccountCredentials(MY_SERVICE_ACCOUNT, MY_PRIVATE_KEY_FILE)) |
|
32 |
|
|
33 |
#/////////////////////////////////// |
|
34 |
#// Function to extract cloud flags |
|
35 |
def getmod09(img): return(img.select(['state_1km']).expression("((b(0)/1024)%2)")); |
|
36 |
|
|
37 |
## set a year-month if you don't want to run the loop (for testing) |
|
38 |
year=2001 |
|
39 |
month=1 |
|
40 |
|
|
41 |
print('Processing '+str(year)+'_'+str(month)) |
|
42 |
|
|
43 |
## MOD09 internal cloud flag for this year-month |
|
44 |
## to filter by a date range: filterDate(datetime.datetime(yearstart,monthstart,1),datetime.datetime(yearstop,monthstop,31)) |
|
45 |
mod09 = ee.ImageCollection("MOD09GA").filter(ee.Filter.calendarRange(year,year,"year")).filter(ee.Filter.calendarRange(month,month,"month")).map(getmod09); |
|
46 |
|
|
47 |
## calculate mean cloudiness (%), rename band, multiply by 100, and convert to integer |
|
48 |
mod09a=mod09.mean().select([0], ['MOD09_'+str(year)+'_'+str(month)]).multiply(ee.Image(100)).byte(); |
|
49 |
|
|
50 |
## print info to confirm there is data |
|
51 |
# mod09a.getInfo() |
|
52 |
|
|
53 |
## define region for download |
|
54 |
region=[ulx,lry ], [ulx, uly], [lrx, uly], [lrx, lry] #h11v08 |
|
55 |
strregion=str(list(region)) |
|
56 |
|
|
57 |
## Define tiles |
|
58 |
region='[[-72, -1], [-72, 11], [-59, 11], [-59, -1]]' |
|
59 |
## build the URL and name the object (so that when it's unzipped we know what it is!) |
|
60 |
path =mod09a.getDownloadUrl({ |
|
61 |
'name': output, # name the file (otherwise it will be a uninterpretable hash) |
|
62 |
'scale': 926, # resolution in meters |
|
63 |
'crs': 'EPSG:4326', # MODIS sinusoidal |
|
64 |
'region': strregion # region defined above |
|
65 |
}); |
|
66 |
|
|
67 |
## download with wget |
|
68 |
wget.download(path) |
|
69 |
|
|
70 |
|
|
71 |
|
climate/research/cloud/ee/ee_compile.R | ||
---|---|---|
1 |
### Script to compile the monthly cloud data from earth engine into a netcdf file for further processing |
|
2 |
|
|
3 |
library(raster) |
|
4 |
library(doMC) |
|
5 |
library(multicore) |
|
6 |
library(foreach) |
|
7 |
#library(doMPI) |
Also available in: Unified diff
rearrange MOD09 folders