Revision 2adbe5f7
Added by Adam M. Wilson almost 11 years ago
climate/research/cloud/MOD09/ee/ee_MCD09CF.js | ||
---|---|---|
1 |
// MCD09_MCloudFreq |
|
2 |
//////////////////////////////////////////////////////////// |
|
3 |
// Adam.wilson@yale.edu |
|
4 |
// Generate a cloud frequency climatology from MOD09 data |
|
5 |
// This script does the following |
|
6 |
// 1) Extracts daily cloud flag from MOD09GA and MYD09GA and create single collection for each month |
|
7 |
// 2) Calculate mean cloud frequency for each month |
|
8 |
// 3) Calculate overall mean and sd of monthly mean cloud frequencies for each month |
|
9 |
// 4) Export the monthly mean/sd cloud frequency separately (as separate tasks) for each month |
|
10 |
//////////////////////////////////////////////////////////// |
|
11 |
|
|
12 |
// Specify destination and run name |
|
13 |
var driveFolder="ee_combined"; |
|
14 |
var run="combined" |
|
15 |
|
|
16 |
// limit overall date range by year (only years in this range will be included) |
|
17 |
var yearstart=2000 |
|
18 |
var yearstop=2013 |
|
19 |
|
|
20 |
// limit overall date range by month |
|
21 |
var monthstart=1 |
|
22 |
var monthstop=12 |
|
23 |
|
|
24 |
// specify what happens |
|
25 |
var verbose=true // print info about collections along the way (slows things down) |
|
26 |
var exportDrive=true // add exports to task window |
|
27 |
var exportGME=false // add exports to task window and send to GME |
|
28 |
var download=false // show download URL |
|
29 |
var drawmap=false // add image to map |
|
30 |
|
|
31 |
|
|
32 |
// Get current date as string for file metadata |
|
33 |
var currentdate = new Date() |
|
34 |
var date= currentdate.getFullYear()+''+currentdate.getMonth()+1+''+currentdate.getDate() |
|
35 |
|
|
36 |
// get array of years to process |
|
37 |
var years=Array.apply(0, Array(yearstop-yearstart+1)).map(function (x, y) { return yearstart +y ; }); |
|
38 |
var nYears=years.length |
|
39 |
if(verbose){print('Processing '+years)} |
|
40 |
|
|
41 |
///////////////////////////////////////////////////////////////////////////// |
|
42 |
/// Functions |
|
43 |
/** |
|
44 |
* Returns an image containing just the specified QA bits. |
|
45 |
* |
|
46 |
* Args: |
|
47 |
* image - The QA Image to get bits from. |
|
48 |
* start - The first bit position, 0-based. |
|
49 |
* end - The last bit position, inclusive. |
|
50 |
* name - A name for the output image. |
|
51 |
*/ |
|
52 |
var getQABits = function(image, start, end, newName) { |
|
53 |
// Compute the bits we need to extract. |
|
54 |
var pattern = 0; |
|
55 |
for (var i = start; i <= end; i++) { |
|
56 |
pattern += Math.pow(2, i); |
|
57 |
} |
|
58 |
return image.select([0], [newName]) |
|
59 |
.bitwise_and(pattern) |
|
60 |
.right_shift(start); |
|
61 |
}; |
|
62 |
|
|
63 |
// function to extract MOD09 internal cloud flag |
|
64 |
//var getcf=function(img){ return(img.select(['state_1km']).expression("((b(0)/1024)%1)").multiply(ee.Image(100)))}; |
|
65 |
var getcf=function(img){ return( getQABits(img.select(['state_1km']),10, 10, 'cloud').expression("b(0) == 1").multiply(ee.Image(100)))}; |
|
66 |
|
|
67 |
//function to get mean combined (terra + aqua) cloud frequency for a particular year-month |
|
68 |
function fMOD09(year,month,collection){ |
|
69 |
// define filters |
|
70 |
var getmonth=ee.Filter.calendarRange(month,month,"month"); |
|
71 |
var getyear=ee.Filter.calendarRange(year,year,"year"); |
|
72 |
// extract values |
|
73 |
var MOD09=ee.ImageCollection(collection).filter(getmonth).filter(getyear).map(getcf).mean(); |
|
74 |
// get monthly combined mean |
|
75 |
var tMOD09m=MOD09; |
|
76 |
return(tMOD09m); |
|
77 |
} |
|
78 |
|
|
79 |
// function to return the total number of observations in the collection |
|
80 |
var getcount=function(img) { |
|
81 |
return img.select(['num_observations_1km']).select([0],['nObs'])}//.multiply(ee.Image(10))}; |
|
82 |
|
|
83 |
// function to return the proportion of days with at least one observation in the collection |
|
84 |
var getprop=function(img) { |
|
85 |
return img.select(['num_observations_1km']).gte(1).multiply(ee.Image(100)).select([0],['pObs'])}; |
|
86 |
|
|
87 |
|
|
88 |
//////////////////////////////////////////////////// |
|
89 |
// Loop through months and get cloud frequency for each month in year range |
|
90 |
for (var m = monthstart; m <= monthstop; m ++ ) { |
|
91 |
|
|
92 |
//For this month, build array to hold means for every year |
|
93 |
var mod = new Array (nYears); |
|
94 |
var myd = new Array (nYears); |
|
95 |
|
|
96 |
// loop over years and and put the mean monthly CF in the array |
|
97 |
for (var i=0; i<nYears; i ++) { |
|
98 |
mod[i]= fMOD09(years[i],m,"MOD09GA"); |
|
99 |
myd[i]= fMOD09(years[i],m,"MYD09GA"); |
|
100 |
} |
|
101 |
|
|
102 |
if(verbose){print('Processing '+nYears+' years of data for Month '+m)} |
|
103 |
|
|
104 |
// build an image collection for all years for this month using the array |
|
105 |
var MOD09m=ee.ImageCollection(mod); |
|
106 |
var MYD09m=ee.ImageCollection(myd); |
|
107 |
|
|
108 |
if(verbose){print(MOD09m.getInfo())} |
|
109 |
|
|
110 |
///////////////////////////////////////////////////////////////////////////////////////////////////// |
|
111 |
/// Process MODIS observation frequency/proportion |
|
112 |
|
|
113 |
// get number of obs and proportion of days with at least one obs |
|
114 |
//MOD |
|
115 |
var MOD09_pObs = ee.ImageCollection("MOD09GA"). |
|
116 |
filter(ee.Filter.calendarRange(yearstart,yearstop,"year")). |
|
117 |
filter(ee.Filter.calendarRange(m,m,"month")).map(getprop).mean().byte(); |
|
118 |
|
|
119 |
var MOD09_nObs = ee.ImageCollection("MOD09GA"). |
|
120 |
filter(ee.Filter.calendarRange(yearstart,yearstop,"year")). |
|
121 |
filter(ee.Filter.calendarRange(m,m,"month")).map(getcount).mean().multiply(ee.Image(4)).byte(); |
|
122 |
|
|
123 |
//MYD |
|
124 |
var MYD09_pObs = ee.ImageCollection("MYD09GA"). |
|
125 |
filter(ee.Filter.calendarRange(yearstart,yearstop,"year")). |
|
126 |
filter(ee.Filter.calendarRange(m,m,"month")).map(getprop).mean().byte(); |
|
127 |
|
|
128 |
var MYD09_nObs = ee.ImageCollection("MYD09GA"). |
|
129 |
filter(ee.Filter.calendarRange(yearstart,yearstop,"year")). |
|
130 |
filter(ee.Filter.calendarRange(m,m,"month")).map(getcount).mean().multiply(ee.Image(4)).byte(); |
|
131 |
|
|
132 |
////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
133 |
// Process cloud frequency |
|
134 |
|
|
135 |
// take overall mean and SD across all years for this month for MOD |
|
136 |
var MOD09_mean=MOD09m.mean().byte(); |
|
137 |
var MOD09_sd=MOD09m.reduce(ee.call("Reducer.sampleStdDev")).multiply(ee.Image(4)).byte(); |
|
138 |
|
|
139 |
|
|
140 |
// take overall mean and SD across all years for this month for MYD |
|
141 |
var MYD09_mean=MYD09m.mean().byte(); |
|
142 |
var MYD09_sd=MYD09m.reduce(ee.call("Reducer.sampleStdDev")).multiply(ee.Image(4)).byte(); |
|
143 |
|
|
144 |
|
|
145 |
///////////////////////////////////////////////////////////////////////////////////////////////////// |
|
146 |
// Build a single 8-bit image with all bands |
|
147 |
var MOD09=MOD09_mean.addBands(MOD09_sd).addBands(MOD09_nObs).addBands(MOD09_pObs); |
|
148 |
var MOD09o=MOD09_nObs.addBands(MOD09_pObs); // Strange, include this line or the above line doesn't work |
|
149 |
var MOD09o2=MOD09_pObs.addBands(MOD09_nObs); // Strange, include this line or the above line doesn't work |
|
150 |
|
|
151 |
var MYD09=MYD09_mean.addBands(MYD09_sd).addBands(MYD09_nObs).addBands(MYD09_pObs); |
|
152 |
var MYD09o=MYD09_nObs.addBands(MYD09_pObs); // Strange, include this line or the above line doesn't work |
|
153 |
var MYD09o2=MYD09_pObs.addBands(MYD09_nObs); // Strange, include this line or the above line doesn't work |
|
154 |
|
|
155 |
|
|
156 |
if(verbose){ print(MOD09.getInfo()) } |
|
157 |
//if(verbose){ print(MOD09o.getInfo()) } |
|
158 |
|
|
159 |
|
|
160 |
// Test with getDownloadURL |
|
161 |
if(download){ |
|
162 |
var path = MOD09.getDownloadURL({ |
|
163 |
'name': date+'_'+run+'_MOD09_'+m, |
|
164 |
'crs': 'SR-ORG:6974', //4326 |
|
165 |
'scale': '926.625433055833', |
|
166 |
'region': '[[-18, 0], [-18, 30], [15, 30], [15, 0]]' // Sahara |
|
167 |
}); |
|
168 |
print(path); |
|
169 |
} |
|
170 |
|
|
171 |
|
|
172 |
if(exportDrive){ |
|
173 |
exportImage(MOD09, |
|
174 |
date+'_'+run+'_'+yearstart+yearstop+'_MOD09_'+m, |
|
175 |
{'maxPixels':1000000000, |
|
176 |
'driveFolder':driveFolder, |
|
177 |
// 'crs': 'EPSG:4326', //4326 |
|
178 |
'crs': 'SR-ORG:6974', //4326 |
|
179 |
'scale': '926.625433055833', |
|
180 |
// 'crsTransform':[0.008333333333, 0, -180, 0, -0.008333333333, -90], |
|
181 |
'region': '[[-180, -89.9], [-180, 89.9], [180, 89.9], [180, -89.9]]' //global |
|
182 |
// 'region': '[[-18, 0], [-18, 30], [15, 30], [15, 0]]' // Sahara |
|
183 |
}); |
|
184 |
|
|
185 |
exportImage(MYD09, |
|
186 |
date+'_'+run+'_'+yearstart+yearstop+'_MYD09_'+m, |
|
187 |
{'maxPixels':1000000000, |
|
188 |
'driveFolder':driveFolder, |
|
189 |
// 'crs': 'EPSG:4326', //4326 |
|
190 |
'crs': 'SR-ORG:6974', //4326 |
|
191 |
'scale': '926.625433055833', |
|
192 |
// 'crsTransform':[0.008333333333, 0, -180, 0, -0.008333333333, -90], |
|
193 |
'region': '[[-180, -89.9], [-180, 89.9], [180, 89.9], [180, -89.9]]' //global |
|
194 |
// 'region': '[[-18, 0], [-18, 30], [15, 30], [15, 0]]' // Sahara |
|
195 |
}); |
|
196 |
} |
|
197 |
|
|
198 |
|
|
199 |
// Export to GME |
|
200 |
if(exportGME){ |
|
201 |
exportImage(MCD09, |
|
202 |
date+'_GME_'+run+'_MCD09_'+m, |
|
203 |
{'maxPixels':1000000000, |
|
204 |
// 'crs': 'EPSG:4326', //4326 |
|
205 |
'crs': 'SR-ORG:6974', //4326 |
|
206 |
'scale': '926.625433055833', |
|
207 |
// 'crsTransform':[0.008333333333, 0, -180, 0, -0.008333333333, -90], |
|
208 |
// 'region': '[[-180, -89], [-180, 89], [180, 89], [180, -89]]' //global |
|
209 |
'region': '[[-18, 0], [-18, 30], [15, 30], [15, 0]]', // Sahara |
|
210 |
'gmeProjectId' : 'MAP OF LIFE', |
|
211 |
'gmeAttributionName': 'Copyright MAP OF LIFE', |
|
212 |
'gmeMosaic': 'cloud' |
|
213 |
}); |
|
214 |
} |
|
215 |
|
|
216 |
|
|
217 |
} // close loop through months |
|
218 |
|
|
219 |
|
|
220 |
// Draw the map? |
|
221 |
if(drawmap) { |
|
222 |
var palette="000000,00FF00,FF0000" |
|
223 |
|
|
224 |
//addToMap(MOD09,{min:0,max:100,palette:palette}, "mod09"); |
|
225 |
addToMap(MOD09_mean,{min:0,max:100,palette:palette}, "mean"); |
|
226 |
addToMap(MOD09_sd,{min:0,max:200,palette:palette}, "sd"); |
|
227 |
addToMap(MOD09_nObs,{min:0,max:20,palette:palette}, "nObs"); |
|
228 |
addToMap(MOD09_pObs,{min:0,max:100,palette:palette}, "pObs"); |
|
229 |
|
|
230 |
} |
Also available in: Unified diff
adding earthengine script for processing MCD09CF