├── CFSv2_TFA_Daily_Mean_Export_2_Assets
├── CFSv2_TFA_Day_or_Night_Export_2_Assets
├── Continuous LST Daily Export
├── Continuous LST Day Export
├── Continuous LST Night Export
├── Convert_LSTcont_GeoTIFF_to_NETCDF.ipynb
├── Explore TFA graphs
├── LST_in_Qgis.gif
├── LSTcont_web_app
├── MODIS_TFA_Daily_Mean_Export_2_Assets
├── MODIS_TFA_Day_or_Night_Export_2_Assets
├── README.md
├── RMSE Daily LST Vs TFA + cfsv2 anomalies iteration
├── RMSE Day LST Vs TFA + cfsv2 anomalies iteration
└── RMSE Night LST Vs TFA + cfsv2 anomalies iteration
/CFSv2_TFA_Daily_Mean_Export_2_Assets:
--------------------------------------------------------------------------------
1 | // This code uses Temporal Fourier Analysis to build 365 images, for each day of year,
2 | // of the climatological tempratures based on the daily mean temperatures.
3 |
4 | // Change the path to your own assets folder
5 | var Assets_path = 'users/shilosh/CFSv2_TFA_Daily_'
6 |
7 | var Temperature_Band = 'Maximum_temperature_height_above_ground_6_Hour_Interval';
8 | var collection = 'NOAA/CFSV2/FOR6H';
9 | // var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]); //Israel
10 | var geometry = ee.Geometry.Rectangle([20,50,25,54]); //Poland
11 | // var geometry = ee.Geometry.Rectangle([43,0,48,4]); //France
12 | // var geometry = ee.Geometry.Rectangle([49,7,54,11]); //Germany
13 | // var geometry = ee.Geometry.Rectangle([-76,36.0,-79,40]); //Maryland (Urban Heat Island)
14 | // var geometry = ee.Geometry.Rectangle([-90,41,-95,44.0]);//Iowa (Corn Belt)
15 | // var geometry = ee.Geometry.Rectangle([-60,-6,-55,-2]); //Brazil (Equatorial)
16 | // var geometry = ee.Geometry.Rectangle([-50,-20,-45,-16]); //SouthBrazil
17 | // var geometry = ee.Geometry.Rectangle([-69,-34,-64,-30]); //Argentina
18 | // var geometry = ee.Geometry.Rectangle([12,24,17,28]); //Libya (Sahara)
19 | // var geometry = ee.Geometry.Rectangle([105,30,110,34]); //China
20 | // var geometry = ee.Geometry.Rectangle([145,-37,150,-33]); //SouthAustralia
21 | // var geometry = ee.Geometry.Rectangle([135,-25,140,-20]); //MidAustralia
22 | // var geometry = ee.Geometry.Rectangle([-130,58,-125,62]); //Canada (Mid latitudes)
23 |
24 | var geometry_json = geometry.toGeoJSON();
25 |
26 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Israel'
27 | var TFA_File_Name = 'CFSv2_Daily_TFA_Poland'
28 | // var TFA_File_Name = 'CFSv2_Daily_TFA_France'
29 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Germany'
30 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Maryland'
31 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Iowa'
32 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Brazil'
33 | // var TFA_File_Name = 'CFSv2_Daily_TFA_SouthBrazil'
34 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Argentina'
35 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Libya'
36 | // var TFA_File_Name = 'CFSv2_Daily_TFA_China'
37 | // var TFA_File_Name = 'CFSv2_Daily_TFA_SouthAustralia'
38 | // var TFA_File_Name = 'CFSv2_Daily_TFA_MidAustralia'
39 | // var TFA_File_Name = 'CFSv2_Daily_TFA_Canada'
40 |
41 | // The number of cycles per year to model.
42 | var harmonics = 3;
43 |
44 | // Make a list of harmonic frequencies to model.
45 | // These also serve as band name suffixes.
46 | var harmonicFrequencies = ee.List.sequence(1, harmonics);
47 | // Function to get a sequence of band names for harmonic terms.
48 | var getNames = function(base, list) {
49 | return ee.List(list).map(function(i) {
50 | return ee.String(base).cat(ee.Number(i).int());
51 | });
52 | };
53 |
54 | // Construct lists of names for the harmonic terms.
55 | var cosNames = getNames('cos_', harmonicFrequencies);
56 | var sinNames = getNames('sin_', harmonicFrequencies);
57 |
58 | // Function to convert Kelvin to Celsius
59 | var k2celsius = function(image) {
60 | return image.subtract(ee.Image(273.15))
61 | .set('system:time_start', image.get('system:time_start'));
62 | };
63 |
64 | // Function to compute the specified number of harmonics
65 | // and add them as bands.
66 | // for p = 0, Nharmonics-1 do begin
67 | // a[p] = a[p] + 2*TS_t*cos(2*!pi*(p+1)*(t+1)/N)
68 | // b[p] = b[p] + 2*TS_t*sin(2*!pi*(p+1)*(t+1)/N)
69 | var addHarmonics = function(freqs) {
70 | return function(image) {
71 | // Make an image of frequencies.
72 | var frequencies = ee.Image.constant(freqs);
73 | // This band should represent surface temperatures.
74 | var st = ee.Image(image).select(Temperature_Band);
75 | // This band should represent days from start.
76 | var time = ee.Image(image).select('t');
77 | // Get the cosine terms.
78 | var cosines = st.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).cos())
79 | .rename(cosNames);
80 | // Get the sin terms.
81 | var sines = st.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).sin())
82 | .rename(sinNames);
83 | return image.addBands(cosines).addBands(sines);
84 | };
85 | };
86 |
87 | // This function reads all CFSv2 dataset (1979-now), iterates through every day of year
88 | // and calculates daily mean temperatures in each day of year
89 | var LST = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
90 | return ee.ImageCollection(collection)
91 | .select(Temperature_Band)
92 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
93 | // .filter(ee.Filter.eq('start_hour', 12))
94 | .map(k2celsius)
95 | .mean()
96 | .set({doy: doy})
97 | .addBands(ee.Image(ee.Number(doy)).rename('t'))
98 | // .map(addHarmonics(harmonicFrequencies));
99 | }))
100 | print('LST = ', LST)
101 | LST = LST.map(addHarmonics(harmonicFrequencies));
102 |
103 | // a = a / N_TS
104 | // b = b / N_TS
105 | var num_days = 365;//ee.Date(lastDay).difference(ee.Date(firstDay), 'day');
106 | var a_coef_1 = LST.select('cos_1').sum().divide(num_days);
107 | var a_coef_2 = LST.select('cos_2').sum().divide(num_days);
108 | var a_coef_3 = LST.select('cos_3').sum().divide(num_days);
109 | var b_coef_1 = LST.select('sin_1').sum().divide(num_days);
110 | var b_coef_2 = LST.select('sin_2').sum().divide(num_days);
111 | var b_coef_3 = LST.select('sin_3').sum().divide(num_days);
112 |
113 | // ; ========================================
114 | // ; prepare the first 3 harmonics of the TFA
115 | // ; ========================================
116 | // H0 = total(TS) / N_TS ;mean
117 | // FTA = MAKE_ARRAY(N_TS, /FLOAT, VALUE=0.)
118 | // H = MAKE_ARRAY(Nharmonics, N_TS, /FLOAT, VALUE=0.)
119 | // omega = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
120 | // Phase = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
121 | // Amplitude = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
122 | // for p = 0, Nharmonics-1 do begin
123 | // omega[p] = 2. * !pi * (p+1) / N
124 | // Phase[p] = atan( -b[p], a[p] )
125 | // Amplitude[p] = sqrt( a[p]^2 + b[p]^2 )
126 |
127 | var H0 = LST.select(Temperature_Band).mean();
128 | // Get the omega terms.
129 | var omega_1 = ee.Image(1.0).multiply(2.0 * Math.PI).divide(365.0);
130 | var omega_2 = ee.Image(2.0).multiply(2.0 * Math.PI).divide(365.0);
131 | var omega_3 = ee.Image(3.0).multiply(2.0 * Math.PI).divide(365.0);
132 |
133 | var phase_1 = a_coef_1.atan2(b_coef_1.multiply(ee.Image(-1.0)));
134 | var phase_2 = a_coef_2.atan2(b_coef_2.multiply(ee.Image(-1.0)));
135 | var phase_3 = a_coef_3.atan2(b_coef_3.multiply(ee.Image(-1.0)));
136 |
137 | var amplitude_1 = (a_coef_1.pow(2).add(b_coef_1.pow(2))).sqrt();
138 | var amplitude_2 = (a_coef_2.pow(2).add(b_coef_2.pow(2))).sqrt();
139 | var amplitude_3 = (a_coef_3.pow(2).add(b_coef_3.pow(2))).sqrt();
140 |
141 | // for t = 0, N_TS-1 do begin
142 | // H[p,t] = Amplitude[p] * cos(omega[p]*(t+1) + Phase[p])
143 |
144 | // Function to add a H band.
145 | var addH = function(image) {
146 | var H_1 = amplitude_1.multiply((omega_1.multiply(image.select('t')).add(phase_1)).cos()).rename('H_1');
147 | var H_2 = amplitude_2.multiply((omega_2.multiply(image.select('t')).add(phase_2)).cos()).rename('H_2');
148 | var H_3 = amplitude_3.multiply((omega_3.multiply(image.select('t')).add(phase_3)).cos()).rename('H_3');
149 | // FTA[t] = H0 + H[0,t] + H[1,t] + H[2,t]
150 | var TFA = H0.add(H_1).add(H_2).add(H_3).rename('TFA');
151 |
152 | var Anomalies = TFA.subtract(image.select(Temperature_Band)).rename('Anomalies');
153 | return image.addBands(TFA).addBands(Anomalies);
154 | };
155 |
156 | var LST_TFA = LST.map(addH);
157 |
158 | // Define the visualization parameters.
159 | var vizParams = {
160 | bands: ['mean', 'phase', 'amplitude'],
161 | min: [285.0,2.0,5.0],
162 | max: [295.0,3.0,10.0],
163 | gamma: [1.0, 1.0, 1.0]
164 | };
165 |
166 | //display the image.
167 | var img = ee.Image(H0.addBands(phase_1).addBands(amplitude_1).rename('mean', 'phase', 'amplitude'));
168 | // Map.addLayer(img, vizParams, 'RGB');
169 |
170 | // var modelTFA = LST_TFA.select(['TFA', Temperature_Band, 'Anomalies']);
171 | // var modisTFA = LST_TFA.select(['TFA', Temperature_Band]);
172 |
173 | // print(LST_TFA)
174 | //Iterating over the image collection using this function....
175 | var TFA_Images = LST_TFA.select('TFA')
176 | .sort('t')
177 | .iterate(function(img, all) {
178 | return ee.Image(all).addBands(img);
179 | }, ee.Image().select());
180 |
181 | // print('TFA_Images = ', TFA_Images );
182 | // Map.addLayer(ee.Image(TFA_Images))
183 |
184 | Export.image.toAsset({
185 | image: ee.Image(TFA_Images),
186 | assetId: Assets_path + TFA_File_Name,
187 | region: geometry_json,
188 | crs: ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection().crs().getInfo(),
189 | crsTransform: [0.20454520376789903, 0, -180, 0, -0.20442210122586923, 90],
190 | description: 'exportToAsset-CFSV2-TFA-' + TFA_File_Name,
191 | pyramidingPolicy: {'.default': 'sample'}
192 | });
193 |
--------------------------------------------------------------------------------
/CFSv2_TFA_Day_or_Night_Export_2_Assets:
--------------------------------------------------------------------------------
1 | // This code uses Temporal Fourier Analysis to build 365 images, for each day of year,
2 | // of the climatological tempratures based on the day (or night) temperatures.
3 |
4 | // Choose here either day or night
5 | var start_hour = '12'
6 | // var start_hour = '00'
7 |
8 | // Insert here the coordinates of the area of interest.
9 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
10 | var geometry_json = geometry.toGeoJSON();
11 |
12 | // Change the path to your own assets folder
13 | var Assets_path = 'users/shilosh/CFSv2_TFA_'
14 |
15 | var Temperature_Band = 'Maximum_temperature_height_above_ground_6_Hour_Interval';
16 | var collection = 'NOAA/CFSV2/FOR6H';
17 | // The number of cycles per year to model.
18 | var harmonics = 3;
19 |
20 | // Make a list of harmonic frequencies to model.
21 | // These also serve as band name suffixes.
22 | var harmonicFrequencies = ee.List.sequence(1, harmonics);
23 | // Function to get a sequence of band names for harmonic terms.
24 | var getNames = function(base, list) {
25 | return ee.List(list).map(function(i) {
26 | return ee.String(base).cat(ee.Number(i).int());
27 | });
28 | };
29 |
30 | // Construct lists of names for the harmonic terms.
31 | var cosNames = getNames('cos_', harmonicFrequencies);
32 | var sinNames = getNames('sin_', harmonicFrequencies);
33 |
34 | var k2celsius = function(image) {
35 | return image.subtract(ee.Image(273.15)) //convert Kelvin to Celsius
36 | .set('system:time_start', image.get('system:time_start'));
37 | };
38 |
39 |
40 |
41 | // Function to compute the specified number of harmonics
42 | // and add them as bands.
43 | // for p = 0, Nharmonics-1 do begin
44 | // a[p] = a[p] + 2*TS_t*cos(2*!pi*(p+1)*(t+1)/N)
45 | // b[p] = b[p] + 2*TS_t*sin(2*!pi*(p+1)*(t+1)/N)
46 | var addHarmonics = function(freqs) {
47 | return function(image) {
48 | // Make an image of frequencies.
49 | var frequencies = ee.Image.constant(freqs);
50 | // This band should represent lst.
51 | var lst = ee.Image(image).select(Temperature_Band);
52 | // This band should represent days from start.
53 | var time = ee.Image(image).select('t');
54 | // Get the cosine terms.
55 | var cosines = lst.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).cos())
56 | .rename(cosNames);
57 | // Get the sin terms.
58 | var sines = lst.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).sin())
59 | .rename(sinNames);
60 | return image.addBands(cosines).addBands(sines);
61 | };
62 | };
63 |
64 | var LST = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
65 | return ee.ImageCollection(collection)
66 | .select(Temperature_Band)
67 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
68 | .filter(ee.Filter.stringEndsWith('system:index', start_hour))
69 | .map(k2celsius)
70 | .mean()
71 | .set({doy: doy})
72 | .addBands(ee.Image(ee.Number(doy)).rename('t'))
73 | // .map(addHarmonics(harmonicFrequencies));
74 | }))
75 |
76 | LST = LST.map(addHarmonics(harmonicFrequencies));
77 |
78 | // a = a / N_TS
79 | // b = b / N_TS
80 | var num_days = 365;//ee.Date(lastDay).difference(ee.Date(firstDay), 'day');
81 | var a_coef_1 = LST.select('cos_1').sum().divide(num_days);
82 | var a_coef_2 = LST.select('cos_2').sum().divide(num_days);
83 | var a_coef_3 = LST.select('cos_3').sum().divide(num_days);
84 | var b_coef_1 = LST.select('sin_1').sum().divide(num_days);
85 | var b_coef_2 = LST.select('sin_2').sum().divide(num_days);
86 | var b_coef_3 = LST.select('sin_3').sum().divide(num_days);
87 |
88 | // ; ========================================
89 | // ; prepare the first 3 harmonics of the TFA
90 | // ; ========================================
91 | // H0 = total(TS) / N_TS ;mean
92 | // FTA = MAKE_ARRAY(N_TS, /FLOAT, VALUE=0.)
93 | // H = MAKE_ARRAY(Nharmonics, N_TS, /FLOAT, VALUE=0.)
94 | // omega = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
95 | // Phase = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
96 | // Amplitude = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
97 | // for p = 0, Nharmonics-1 do begin
98 | // omega[p] = 2. * !pi * (p+1) / N
99 | // Phase[p] = atan( -b[p], a[p] )
100 | // Amplitude[p] = sqrt( a[p]^2 + b[p]^2 )
101 |
102 | var H0 = LST.select(Temperature_Band).mean();
103 | // Get the omega terms.
104 | var omega_1 = ee.Image(1.0).multiply(2.0 * Math.PI).divide(365.0);
105 | var omega_2 = ee.Image(2.0).multiply(2.0 * Math.PI).divide(365.0);
106 | var omega_3 = ee.Image(3.0).multiply(2.0 * Math.PI).divide(365.0);
107 |
108 | var phase_1 = a_coef_1.atan2(b_coef_1.multiply(ee.Image(-1.0)));
109 | var phase_2 = a_coef_2.atan2(b_coef_2.multiply(ee.Image(-1.0)));
110 | var phase_3 = a_coef_3.atan2(b_coef_3.multiply(ee.Image(-1.0)));
111 |
112 | var amplitude_1 = (a_coef_1.pow(2).add(b_coef_1.pow(2))).sqrt();
113 | var amplitude_2 = (a_coef_2.pow(2).add(b_coef_2.pow(2))).sqrt();
114 | var amplitude_3 = (a_coef_3.pow(2).add(b_coef_3.pow(2))).sqrt();
115 |
116 | // for t = 0, N_TS-1 do begin
117 | // H[p,t] = Amplitude[p] * cos(omega[p]*(t+1) + Phase[p])
118 |
119 | // Function to add a H band.
120 | var addH = function(image) {
121 | var H_1 = amplitude_1.multiply((omega_1.multiply(image.select('t')).add(phase_1)).cos()).rename('H_1');
122 | var H_2 = amplitude_2.multiply((omega_2.multiply(image.select('t')).add(phase_2)).cos()).rename('H_2');
123 | var H_3 = amplitude_3.multiply((omega_3.multiply(image.select('t')).add(phase_3)).cos()).rename('H_3');
124 | // FTA[t] = H0 + H[0,t] + H[1,t] + H[2,t]
125 | var TFA = H0.add(H_1).add(H_2).add(H_3).rename('TFA');
126 |
127 | var Anomalies = TFA.subtract(image.select(Temperature_Band)).rename('Anomalies');
128 | return image.addBands(TFA).addBands(Anomalies);
129 | };
130 |
131 | var LST_TFA = LST.map(addH);
132 |
133 | // Define the visualization parameters.
134 | var vizParams = {
135 | bands: ['mean', 'phase', 'amplitude'],
136 | min: [285.0,2.0,5.0],
137 | max: [295.0,3.0,10.0],
138 | gamma: [1.0, 1.0, 1.0]
139 | };
140 |
141 | //display the image.
142 | var img = ee.Image(H0.addBands(phase_1).addBands(amplitude_1).rename('mean', 'phase', 'amplitude'));
143 | // Map.addLayer(img, vizParams, 'RGB');
144 |
145 | // var modelTFA = LST_TFA.select(['TFA', Temperature_Band, 'Anomalies']);
146 | // var modisTFA = LST_TFA.select(['TFA', Temperature_Band]);
147 |
148 | // print(LST_TFA)
149 | //Iterating over the image collection using this function....
150 | var TFA_Images = LST_TFA.select('TFA')
151 | .sort('t')
152 | .iterate(function(img, all) {
153 | return ee.Image(all).addBands(img);
154 | }, ee.Image().select());
155 |
156 | // print('TFA_Images = ', TFA_Images );
157 | // Map.addLayer(ee.Image(TFA_Images))
158 |
159 | // Export one single file with all the bands
160 | Export.image.toAsset({
161 | image: ee.Image(TFA_Images),
162 | assetId: Assets_path + start_hour,
163 | region: geometry_json,
164 | crs: ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection().crs().getInfo(),
165 | crsTransform: [0.20454520376789903, 0, -180, 0, -0.20442210122586923, 90],
166 | description: 'exportToAsset-CFSV2-TFA-' + start_hour,
167 | pyramidingPolicy: {'.default': 'sample'}
168 | });
169 |
--------------------------------------------------------------------------------
/Continuous LST Daily Export:
--------------------------------------------------------------------------------
1 | // Change the path to your own TFA images
2 | var CFSV2_TFA = ee.Image("users/shilosh/CFSv2_Daily_LST_TFA"),
3 | MODIS_TFA = ee.Image("users/shilosh/MODIS_Daily_LST_TFA");
4 | var firstDay = '2019-02-27';
5 | var lastDay = '2019-03-01';
6 | var Assets_path = 'users/shilosh/';
7 | var FileName = 'MODIS_Continuous_LST_Daily_2018';
8 | var Temperature_Band = 'Maximum_temperature_height_above_ground_6_Hour_Interval';
9 | var Day_Temperature_Band = 'LST_Day_1km';
10 | var Night_Temperature_Band = 'LST_Night_1km';
11 | var collection = 'NOAA/CFSV2/FOR6H';
12 |
13 | // Reverse the images into imageCollections
14 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
15 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
16 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
17 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
18 |
19 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
20 | var geometry_json = geometry.toGeoJSON();
21 | // Map.addLayer(geometry)
22 |
23 |
24 | var modisProjection = MODIS_TFA.projection().crs().getInfo()
25 | var scale = ee.Image(MODIS_TFA).projection().nominalScale().getInfo();
26 |
27 | // Get the CFSv2 data at MODIS scale and projection.
28 | var resample = function(image) {
29 | return image.resample('bilinear')
30 | .reproject({
31 | crs: modisProjection,
32 | scale: scale})
33 | .set('system:DOY', image.get('system:DOY'))
34 | .set('system:time_start', image.get('system:time_start'));
35 | };
36 |
37 | //convert Kelvin to Celsius
38 | var k2celsius = function(image) {
39 | return image.subtract(ee.Image(273.15))
40 | .clip(geometry)
41 | .set('system:DOY', image.get('system:DOY'))
42 | .set('system:time_start', image.get('system:time_start'));};
43 |
44 | // Add a property with doy to the colection.
45 | function createDoyBand(img) {
46 | var d = ee.Date(img.get('system:time_start'))
47 | .getRelative('day', 'year')
48 | .add(1);
49 | img=img.set('system:DOY', d);
50 | return img;
51 | }
52 |
53 | // Construct image date from 'system:index' and add it to a new 'date' property
54 | var addTimeStampToCFSv2 = function(image) {
55 | var start = ee.String(image.get('system:index'));
56 | var y = start.slice(0,4);
57 | var m = start.slice(4,6);
58 | var d = start.slice(6,8);
59 | var date = y.cat('-').cat(m).cat('-').cat(d);
60 | return image.set({'system:time_start': date});
61 | };
62 | // Construct image date from 'system:index' and add it to a new 'date' property
63 | var addTimeStampToMODIS = function(image) {
64 | var start = ee.String(image.get('system:index'));
65 | // var date = start.replace(/_/g, '-');
66 | start = start.replace('_', '-');
67 | var date = start.replace('_', '-');
68 | return image.set({'system:time_start': ee.String(date)});
69 | };
70 |
71 | // Calculate the daily mean of the 4 images (00, 06, 12, 18)
72 | var daily_mean = function(image) {
73 | return image.reduce(ee.Reducer.mean())
74 | .set('system:DOY', image.get('system:DOY'))
75 | .set('system:time_start', image.get('system:time_start'));
76 | };
77 |
78 | CFSV2_TFA_ic = CFSV2_TFA_ic.map(resample);
79 |
80 | // Convert the date string into milliseconds integer
81 | var dayMillis = 86400000 // 86400000 is 1 day in milliseconds
82 | var intFirstDay = ee.Date(firstDay).millis()
83 | var intLastDay = ee.Date(lastDay).millis().subtract(dayMillis)
84 |
85 | // Collect all 4 images of each day and create imageCollection from the daily mean.
86 | var CFSV2 = ee.ImageCollection(ee.List.sequence(intFirstDay, intLastDay, dayMillis).map(function (day){
87 | return ee.ImageCollection('NOAA/CFSV2/FOR6H')
88 | .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
89 | .filterDate(day, ee.Number(day).add(dayMillis))
90 | // .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
91 | .map(resample)
92 | .map(k2celsius)
93 | .mean()
94 | .set({'system:DOY': ee.Date(day).getRelative('day', 'year').add(1)})
95 | .set({'system:time_start': ee.Date(day)})
96 | }))
97 |
98 | // Use an equals filter to specify how the collections match.
99 | var Filter = ee.Filter.equals({
100 | leftField: 'system:DOY',
101 | rightField: 'system:DOY'
102 | });
103 | // Define the join.
104 | var innerJoin = ee.Join.inner('primary', 'secondary');
105 |
106 | // Join CFSV2 with CFSV2_TFA_ic by DOY
107 | // Apply the join.
108 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
109 |
110 | // Calculate CFSv2 anomalies
111 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
112 | var tfa = ee.Image(f.get('secondary'));
113 | var actual = ee.Image(f.get('primary'));
114 | return actual.subtract(tfa)
115 | .set('system:time_start', actual.get('system:time_start'))
116 | .set('system:DOY', actual.get('system:DOY'));
117 | })//.map(addTimeStampToCFSv2)
118 | //.map(createDoyBand);
119 |
120 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
121 | // Apply the join.
122 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
123 | // print('MODIS_JoinInner = ' ,MODIS_JoinInner)
124 |
125 | // Calculate MODIS TFA Plus CFSv2 anomalies
126 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
127 | var anomalies = ee.Image(f.get('primary'));
128 | var tfa = ee.Image(f.get('secondary'));
129 | // Anomalies at night do not conribute to the TFA only prediction,
130 | // therefor because we are trying to predict daily mean LST, we only add half of the daily anomalies
131 | return (anomalies.divide(ee.Image(2))).add(tfa)//.subtract(anomalies);
132 | .set('system:time_start', anomalies.get('system:time_start'))
133 | .set('system:DOY', anomalies.get('system:DOY'));
134 | })//.map(addTimeStampToCFSv2)
135 | //.map(createDoyBand);
136 |
137 | // print('MODIS_Continuous = ' ,MODIS_Continuous)
138 |
139 | var Temperature_Band = 'LST_Day_1km';
140 | var collection = 'MODIS/006/MYD11A1';
141 | //convert Kelvin to Celsius
142 | var modis_k2celsius = function(image) {
143 | return image.updateMask(image.select(Day_Temperature_Band))
144 | .updateMask(image.select(Night_Temperature_Band))
145 | .reduce( ee.Reducer.mean()).rename(Temperature_Band)
146 | .multiply(ee.Image(0.02))
147 | .subtract(ee.Image(273.15))
148 | .clip(geometry)
149 | .set('system:time_start', ee.Date(image.get('system:time_start')))
150 | .rename([ee.String('daily_').cat(image.get('system:time_start'))]);
151 | };
152 |
153 | var MODIS_LST = ee.ImageCollection(collection)
154 | .filterDate(firstDay, lastDay)
155 | .select(Day_Temperature_Band, Night_Temperature_Band)
156 | //.map(function (image){return image.reduce(ee.Reducer.mean())})
157 | .map(addTimeStampToMODIS)
158 | .map(modis_k2celsius)
159 |
160 | print('MODIS_LST = ' ,MODIS_LST)
161 | // Function to calculate the daily mean value of each pixel
162 | // MODIS_LST = MODIS_LST.map(function (image){
163 | // return (image.select(0).add(image.select(1))).divide(ee.Image(2))
164 | // .clip(geometry)
165 | // // .reduce(ee.Reducer.mean())
166 | // .set({'system:DOY': image.get('system:DOY')})
167 | // //.rename('MODIS_LST')
168 | // });
169 |
170 | // Use an equals filter to specify how the collections match.
171 | Filter = ee.Filter.equals({
172 | leftField: 'system:time_start',
173 | rightField: 'system:time_start'
174 | });
175 |
176 | // Join MODIS_LST with MODIS_TFA_plus_CFSV2_Anomalies by DOY
177 | // Apply the join.
178 | var MODIS_Blended_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
179 | // Blend the results to fill LST gaps
180 | var MODIS_LST_Blended = MODIS_Blended_JoinInner.map(function(f) {
181 | var prediction = ee.Image(f.get('secondary'));
182 | var lst = ee.Image(f.get('primary'));
183 | return prediction.blend(lst);
184 | })
185 |
186 | // print(MODIS_LST_Blended)
187 | // print(MODIS_LST)
188 | // print('MODIS_LST_Blended = ' ,MODIS_LST_Blended)
189 | // print('MODIS_Continuous = ' ,MODIS_Continuous)
190 |
191 | // Map.addLayer(ee.Image(MODIS_LST.first()),{},'MODIS_LST')
192 | // Map.addLayer(ee.Image(MODIS_Continuous.first()),{},'MODIS_Continuous')
193 | // Map.addLayer(ee.Image(MODIS_LST_Blended.first()),{},'MODIS_LST_Blended')
194 | // // Map.addLayer(ee.ImageCollection(MODIS_LST_Blended).mean())
195 |
196 | //Iterating over the image collection using this function....
197 | var LST_Images = MODIS_LST_Blended//.select(Temperature_Band)
198 | .iterate(function(img, all) {
199 | return ee.Image(all).addBands(img);
200 | }, ee.Image().select());
201 |
202 | var LST_ic = ee.ImageCollection(ee.Image(LST_Images).bandNames().map(function(name) {
203 | return ee.Image(LST_Images).select([ee.Algorithms.String(name)],[Temperature_Band]).set('system:index', name) }))
204 |
205 | // Map.addLayer(ee.Image(LST_ic.first()),{min:5, max:35},'LST_continuous')
206 |
207 | // Export.image.toAsset({
208 | // image: ee.Image(LST_Images),
209 | // assetId: Assets_path + FileName,
210 | // region: geometry_json,
211 | // crs: ee.Image(LST_Images).projection().crs().getInfo(), // from the projection output
212 | // crsTransform: [926.625433056,0,-20015109.354,0,-926.625433055,10007554.677], // from the projection output
213 | // description: 'exportToAsset-MODIS-LST-TS',
214 | // pyramidingPolicy: {'.default': 'sample'}
215 | // });
216 |
217 | // Enable batch download to Drive
218 | var batch = require('users/fitoprincipe/geetools:batch')
219 |
220 | var scale = ee.Image(MODIS_LST_Blended.first()).select([0]).projection().nominalScale().getInfo()
221 | // export collection to google drive
222 | batch.Download.ImageCollection.toDrive(ee.ImageCollection(LST_ic), 'LST_cont', {
223 | // name: {system:id},
224 | scale: scale,
225 | crs: "EPSG:4326",
226 | region: geometry.getInfo() // or geometry.getInfo()
227 | })
228 |
--------------------------------------------------------------------------------
/Continuous LST Day Export:
--------------------------------------------------------------------------------
1 | // Change the path to your own TFA images
2 | var CFSV2_TFA = ee.Image("users/shilosh/CFSv2_LST_TFA_Day"),
3 | MODIS_TFA = ee.Image("users/shilosh/MODIS_LST_TFA_Day");
4 | var firstDay = '2019-01-01';
5 | var lastDay = '2019-01-03';
6 | var Assets_path = 'users/shilosh/';
7 | var Temperature_Band = 'Maximum_temperature_height_above_ground_6_Hour_Interval';
8 | var collection = 'NOAA/CFSV2/FOR6H';
9 | var start_hour = '12'
10 |
11 | // Reverse the images into imageCollections
12 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
13 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
14 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
15 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
16 |
17 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
18 | var geometry_json = geometry.toGeoJSON();
19 | // Map.addLayer(geometry)
20 |
21 |
22 | var modisProjection = MODIS_TFA.projection().crs().getInfo()
23 | var scale = ee.Image(MODIS_TFA).projection().nominalScale().getInfo();
24 |
25 | // Get the CFSv2 data at MODIS scale and projection.
26 | var resample = function(image) {
27 | return image.resample('bilinear')
28 | .reproject({
29 | crs: modisProjection,
30 | scale: scale})
31 | .set('system:DOY', image.get('system:DOY'))
32 | .set('system:time_start', image.get('system:time_start'));
33 | };
34 |
35 | //convert Kelvin to Celsius
36 | var k2celsius = function(image) {
37 | return image.subtract(ee.Image(273.15))
38 | .clip(geometry)
39 | .set('system:time_start', image.get('system:time_start'));
40 | };
41 |
42 | // Add a property with doy to the colection.
43 | function createDoyBand(img) {
44 | var d = ee.Date(img.get('system:time_start'))
45 | .getRelative('day', 'year')
46 | .add(1);
47 | img=img.set('system:DOY', d);
48 | return img;
49 | }
50 |
51 | // Construct image date from 'system:index' and add it to a new 'date' property
52 | var addTimeStampToCFSv2 = function(image) {
53 | var start = ee.String(image.get('system:index'));
54 | var y = start.slice(0,4);
55 | var m = start.slice(4,6);
56 | var d = start.slice(6,8);
57 | var date = y.cat('-').cat(m).cat('-').cat(d);
58 | return image.set({'system:time_start': date});
59 | };
60 | // Construct image date from 'system:index' and add it to a new 'date' property
61 | var addTimeStampToMODIS = function(image) {
62 | var start = ee.String(image.get('system:index'));
63 | // var date = start.replace(/_/g, '-');
64 | start = start.replace('_', '-');
65 | var date = start.replace('_', '-');
66 | return image.set({'system:time_start': ee.String(date)});
67 | };
68 |
69 | CFSV2_TFA_ic = CFSV2_TFA_ic.map(resample)
70 |
71 | var CFSV2 = ee.ImageCollection(collection)
72 | .filterDate(firstDay, lastDay)
73 | .filter(ee.Filter.stringEndsWith('system:index', start_hour))
74 | .map(resample)
75 | .select(Temperature_Band)
76 | .map(k2celsius)
77 | .map(createDoyBand)
78 |
79 | // Use an equals filter to specify how the collections match.
80 | var Filter = ee.Filter.equals({
81 | leftField: 'system:DOY',
82 | rightField: 'system:DOY'
83 | });
84 | // Define the join.
85 | var innerJoin = ee.Join.inner('primary', 'secondary');
86 |
87 | // Join CFSV2 with CFSV2_TFA_ic by DOY
88 | // Apply the join.
89 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
90 |
91 | // Calculate CFSv2 anomalies
92 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
93 | var tfa = ee.Image(f.get('secondary'));
94 | var actual = ee.Image(f.get('primary'));
95 | return actual.subtract(tfa);
96 | }).map(addTimeStampToCFSv2)
97 | .map(createDoyBand);
98 |
99 | print('MODIS_TFA_ic = ' ,MODIS_TFA_ic)
100 | print('CFSV2_Anomalies = ' ,CFSV2_Anomalies)
101 |
102 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
103 | // Apply the join.
104 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
105 | // print('MODIS_JoinInner = ' ,MODIS_JoinInner)
106 |
107 | // Calculate MODIS TFA Plus CFSv2 anomalies
108 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
109 | var anomalies = ee.Image(f.get('primary'));
110 | var tfa = ee.Image(f.get('secondary'));
111 | return anomalies.add(tfa)//.subtract(anomalies);
112 | }).map(addTimeStampToCFSv2)
113 | .map(createDoyBand);
114 |
115 | // print('MODIS_Continuous = ' ,MODIS_Continuous)
116 |
117 | var Temperature_Band = 'LST_Day_1km';
118 | var collection = 'MODIS/006/MYD11A1';
119 | //convert Kelvin to Celsius
120 | var modis_k2celsius = function(image) {
121 | return image.multiply(ee.Image(0.02))
122 | .subtract(ee.Image(273.15))
123 | .clip(geometry)
124 | .set('system:time_start', image.get('system:time_start'))
125 | .rename([ee.String('day_').cat(image.get('system:time_start'))]);
126 | };
127 |
128 | var MODIS_LST = ee.ImageCollection(collection)
129 | .filterDate(firstDay, lastDay)
130 | .select(Temperature_Band)
131 | .map(addTimeStampToMODIS)
132 | .map(modis_k2celsius)
133 |
134 | // Use an equals filter to specify how the collections match.
135 | Filter = ee.Filter.equals({
136 | leftField: 'system:time_start',
137 | rightField: 'system:time_start'
138 | });
139 |
140 | // Join MODIS_LST with MODIS_TFA_plus_CFSV2_Anomalies by DOY
141 | // Apply the join.
142 | var MODIS_Blended_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
143 | // Blend the results to fill LST gaps
144 | var MODIS_LST_Blended = MODIS_Blended_JoinInner.map(function(f) {
145 | var prediction = ee.Image(f.get('secondary'));
146 | var lst = ee.Image(f.get('primary'));
147 | return prediction.blend(lst);
148 | })
149 |
150 | // Map.addLayer(ee.Image(MODIS_LST.first()),{},'MODIS_LST')
151 | // Map.addLayer(ee.Image(MODIS_Continuous.first()),{},'MODIS_Continuous')
152 | // Map.addLayer(ee.Image(MODIS_LST_Blended.first()),{},'MODIS_LST_Blended')
153 | // Map.addLayer(ee.ImageCollection(MODIS_LST_Blended).mean())
154 |
155 | //Iterating over the image collection using this function....
156 | var LST_Images = MODIS_LST_Blended//.select(Temperature_Band)
157 | .iterate(function(img, all) {
158 | return ee.Image(all).addBands(img);
159 | }, ee.Image().select());
160 |
161 | print(LST_Images)
162 |
163 | var LST_ic = ee.ImageCollection(ee.Image(LST_Images).bandNames().map(function(name) {
164 | return ee.Image(LST_Images).select([ee.Algorithms.String(name)],[Temperature_Band]).set('system:index', name) }))
165 |
166 | print(LST_ic)
167 | Map.addLayer(ee.Image(LST_ic.first()))
168 | print('Projection = ', ee.Image(LST_Images).projection())
169 |
170 | // Export.image.toAsset({
171 | // image: ee.Image(LST_Images),
172 | // assetId: 'users/shilosh/MODIS_Continuous_LST_Day_2013',
173 | // region: geometry_json,
174 | // // scale: scale,
175 | // crs: ee.Image(LST_Images).projection().crs().getInfo(), // from the projection output
176 | // crsTransform: [926.625433056,0,-20015109.354,0,-926.625433055,10007554.677], // from the projection output
177 | // description: 'exportToAsset-MODIS-LST-TS',
178 | // pyramidingPolicy: {'.default': 'sample'}
179 | // });
180 |
181 | // Enable batch download to Drive
182 | var batch = require('users/fitoprincipe/geetools:batch')
183 |
184 | var scale = ee.Image(MODIS_LST_Blended.first()).select([0]).projection().nominalScale().getInfo()
185 | // export collection to google drive
186 | batch.Download.ImageCollection.toDrive(ee.ImageCollection(LST_ic), 'LST_cont', {
187 | // name: {system:id},
188 | scale: scale,
189 | crs: "EPSG:4326",
190 | region: geometry.getInfo() // or geometry.getInfo()
191 | })
192 |
--------------------------------------------------------------------------------
/Continuous LST Night Export:
--------------------------------------------------------------------------------
1 | var MODIS_TFA = ee.Image("users/shilosh/MODIS_LST_TFA_Night"),
2 | CFSV2_TFA = ee.Image("users/shilosh/CFSv2_LST_TFA_Night");
3 | // Reverse the images into imageCollections
4 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
5 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
6 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
7 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
8 |
9 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
10 | var geometry_json = geometry.toGeoJSON();
11 | // Map.addLayer(geometry)
12 | var firstDay = '2013-01-01';
13 | var lastDay = '2016-01-01';
14 | var Temperature_Band = 'Temperature_height_above_ground';
15 | var collection = 'NOAA/CFSV2/FOR6H';
16 |
17 |
18 | var modisProjection = MODIS_TFA.projection().crs().getInfo()
19 | var scale = ee.Image(MODIS_TFA).projection().nominalScale().getInfo();
20 |
21 | // Get the CFSv2 data at MODIS scale and projection.
22 | var resample = function(image) {
23 | return image.resample('bilinear')
24 | .reproject({
25 | crs: modisProjection,
26 | scale: scale})
27 | .set('system:DOY', image.get('system:DOY'))
28 | .set('system:time_start', image.get('system:time_start'));
29 | };
30 |
31 | //convert Kelvin to Celsius
32 | var k2celsius = function(image) {
33 | return image.subtract(ee.Image(273.15))
34 | .clip(geometry)
35 | .set('system:time_start', image.get('system:time_start'));
36 | };
37 |
38 | // Add a property with doy to the colection.
39 | function createDoyBand(img) {
40 | var d = ee.Date(img.get('system:time_start'))
41 | .getRelative('day', 'year')
42 | .add(1);
43 | img=img.set('system:DOY', d);
44 | return img;
45 | }
46 |
47 | // Construct image date from 'system:index' and add it to a new 'date' property
48 | var addTimeStampToCFSv2 = function(image) {
49 | var start = ee.String(image.get('system:index'));
50 | var y = start.slice(0,4);
51 | var m = start.slice(4,6);
52 | var d = start.slice(6,8);
53 | var date = y.cat('-').cat(m).cat('-').cat(d);
54 | return image.set({'system:time_start': date});
55 | };
56 | // Construct image date from 'system:index' and add it to a new 'date' property
57 | var addTimeStampToMODIS = function(image) {
58 | var start = ee.String(image.get('system:index'));
59 | // var date = start.replace(/_/g, '-');
60 | start = start.replace('_', '-');
61 | var date = start.replace('_', '-');
62 | return image.set({'system:time_start': ee.String(date)});
63 | };
64 |
65 | CFSV2_TFA_ic = CFSV2_TFA_ic.map(resample)
66 |
67 | var CFSV2 = ee.ImageCollection(collection)
68 | .filterDate(firstDay, lastDay)
69 | .filter(ee.Filter.stringEndsWith('system:index', '00'))
70 | .map(resample)
71 | .select(Temperature_Band)
72 | .map(k2celsius)
73 | .map(createDoyBand)
74 |
75 | // Use an equals filter to specify how the collections match.
76 | var Filter = ee.Filter.equals({
77 | leftField: 'system:DOY',
78 | rightField: 'system:DOY'
79 | });
80 | // Define the join.
81 | var innerJoin = ee.Join.inner('primary', 'secondary');
82 |
83 | // Join CFSV2 with CFSV2_TFA_ic by DOY
84 | // Apply the join.
85 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
86 |
87 | // Calculate CFSv2 anomalies
88 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
89 | var tfa = ee.Image(f.get('secondary'));
90 | var actual = ee.Image(f.get('primary'));
91 | return actual.subtract(tfa);
92 | }).map(addTimeStampToCFSv2)
93 | .map(createDoyBand);
94 |
95 | print('MODIS_TFA_ic = ' ,MODIS_TFA_ic)
96 | print('CFSV2_Anomalies = ' ,CFSV2_Anomalies)
97 |
98 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
99 | // Apply the join.
100 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
101 | // print('MODIS_JoinInner = ' ,MODIS_JoinInner)
102 |
103 | // Calculate MODIS TFA Plus CFSv2 anomalies
104 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
105 | var anomalies = ee.Image(f.get('primary'));
106 | var tfa = ee.Image(f.get('secondary'));
107 | return anomalies.add(tfa)//.subtract(anomalies);
108 | }).map(addTimeStampToCFSv2)
109 | .map(createDoyBand);
110 |
111 | // print('MODIS_Continuous = ' ,MODIS_Continuous)
112 |
113 | var Temperature_Band = 'LST_Night_1km';
114 | var collection = 'MODIS/006/MYD11A1';
115 | //convert Kelvin to Celsius
116 | var modis_k2celsius = function(image) {
117 | return image.multiply(ee.Image(0.02))
118 | .subtract(ee.Image(273.15))
119 | .clip(geometry)
120 | .set('system:time_start', image.get('system:time_start'))
121 | .rename([ee.String('night_').cat(image.get('system:time_start'))]);
122 | };
123 |
124 | var MODIS_LST = ee.ImageCollection(collection)
125 | .filterDate(firstDay, lastDay)
126 | .select(Temperature_Band)
127 | .map(addTimeStampToMODIS)
128 | .map(modis_k2celsius)
129 |
130 | // Use an equals filter to specify how the collections match.
131 | Filter = ee.Filter.equals({
132 | leftField: 'system:time_start',
133 | rightField: 'system:time_start'
134 | });
135 |
136 | // Join MODIS_LST with MODIS_TFA_plus_CFSV2_Anomalies by DOY
137 | // Apply the join.
138 | var MODIS_Blended_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
139 | // Blend the results to fill LST gaps
140 | var MODIS_LST_Blended = MODIS_Blended_JoinInner.map(function(f) {
141 | var prediction = ee.Image(f.get('secondary'));
142 | var lst = ee.Image(f.get('primary'));
143 | return prediction.blend(lst);
144 | })
145 |
146 | // Map.addLayer(ee.Image(MODIS_LST.first()),{},'MODIS_LST')
147 | // Map.addLayer(ee.Image(MODIS_Continuous.first()),{},'MODIS_Continuous')
148 | // Map.addLayer(ee.Image(MODIS_LST_Blended.first()),{},'MODIS_LST_Blended')
149 | // Map.addLayer(ee.ImageCollection(MODIS_LST_Blended).mean())
150 |
151 | //Iterating over the image collection using this function....
152 | var LST_Images = MODIS_LST_Blended//.select(Temperature_Band)
153 | .iterate(function(img, all) {
154 | return ee.Image(all).addBands(img);
155 | }, ee.Image().select());
156 |
157 | print(LST_Images)
158 |
159 | var LST_ic = ee.ImageCollection(ee.Image(LST_Images).bandNames().map(function(name) {
160 | return ee.Image(LST_Images).select([ee.Algorithms.String(name)],[Temperature_Band]).set('system:index', name) }))
161 |
162 | print(LST_ic)
163 | Map.addLayer(ee.Image(LST_ic.first()))
164 | print('Projection = ', ee.Image(LST_Images).projection())
165 |
166 | // Export.image.toAsset({
167 | // image: LST_Images,
168 | // assetId: 'users/shilosh/MODIS_Continuous_LST_Night_2013_2015',
169 | // region: geometry_json,
170 | // // scale: scale,
171 | // crs: ee.Image(LST_Images).projection().crs().getInfo(), // from the projection output
172 | // crsTransform: [926.625433056,0,-20015109.354,0,-926.625433055,10007554.677], // from the projection output
173 | // description: 'exportToAsset-MODIS-LST-TS',
174 | // pyramidingPolicy: {'.default': 'sample'}
175 | // });
176 |
177 | // Enable batch download to Drive
178 | var batch = require('users/fitoprincipe/geetools:batch')
179 |
180 | var scale = ee.Image(MODIS_LST_Blended.first()).select([0]).projection().nominalScale().getInfo()
181 | // export collection to google drive
182 | batch.Download.ImageCollection.toDrive(ee.ImageCollection(LST_ic), 'LST_cont', {
183 | // name: {system:id},
184 | scale: scale,
185 | crs: "EPSG:4326",
186 | region: geometry.getInfo() // or geometry.getInfo()
187 | })
188 |
--------------------------------------------------------------------------------
/Convert_LSTcont_GeoTIFF_to_NETCDF.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "name": "ContLST GeoTIFF to NETCDF.ipynb",
7 | "provenance": [],
8 | "collapsed_sections": [],
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | }
15 | },
16 | "cells": [
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {
20 | "id": "view-in-github",
21 | "colab_type": "text"
22 | },
23 | "source": [
24 | "
"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {
30 | "id": "5H9HKrXTguow",
31 | "colab_type": "text"
32 | },
33 | "source": [
34 | "# Convert tiff to NetCDF using xarray:"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {
40 | "id": "Zgp9IXPeRuZ9",
41 | "colab_type": "text"
42 | },
43 | "source": [
44 | "connecting gdrive into the google colab"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "metadata": {
50 | "id": "ikvXSppfQLi_",
51 | "colab_type": "code",
52 | "colab": {}
53 | },
54 | "source": [
55 | "from google.colab import drive\n",
56 | "drive.mount('/content/gdrive')"
57 | ],
58 | "execution_count": null,
59 | "outputs": []
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "metadata": {
64 | "id": "OYYpZIY8R-Re",
65 | "colab_type": "text"
66 | },
67 | "source": [
68 | "Test gdrive connection"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "metadata": {
74 | "id": "xnm1V1n0SD9y",
75 | "colab_type": "code",
76 | "colab": {}
77 | },
78 | "source": [
79 | "!ls '/content/gdrive/My Drive/MODIS/2000'"
80 | ],
81 | "execution_count": null,
82 | "outputs": []
83 | },
84 | {
85 | "cell_type": "code",
86 | "metadata": {
87 | "id": "SCwuM4xPRyKd",
88 | "colab_type": "code",
89 | "colab": {}
90 | },
91 | "source": [
92 | "!pip install xarray\n",
93 | "!pip install affine\n",
94 | "!pip install Rasterio \n",
95 | "!pip install netcdf4\n",
96 | "!!pip install geopandas \n"
97 | ],
98 | "execution_count": null,
99 | "outputs": []
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {
104 | "id": "ME075D6MdcoN",
105 | "colab_type": "text"
106 | },
107 | "source": [
108 | "Import libraries"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "metadata": {
114 | "id": "Wk_4dxFc4RXM",
115 | "colab_type": "code",
116 | "colab": {}
117 | },
118 | "source": [
119 | "from affine import Affine\n",
120 | "import glob\n",
121 | "import pandas as pd\n",
122 | "import xarray as xr\n",
123 | "#import xgeo # Needs to be imported to use geo extension\n",
124 | "import geopandas as gpd\n",
125 | "import os"
126 | ],
127 | "execution_count": null,
128 | "outputs": []
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {
133 | "id": "5AL4-JYkdhsR",
134 | "colab_type": "text"
135 | },
136 | "source": [
137 | "function to read the date from file names:"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "metadata": {
143 | "id": "2KylKEVDsGhb",
144 | "colab_type": "code",
145 | "colab": {}
146 | },
147 | "source": [
148 | "\n",
149 | "\n",
150 | "def time_index_from_filenames(filenames):\n",
151 | " '''helper function to create a pandas DatetimeIndex\n",
152 | " Filename example: LST_2002_12_30.tif'''\n",
153 | " #return pd.DatetimeIndex([pd.Timestamp(year=f[4:8], month=f[9:11], day=f[12:14], hour=12) for f in filenames])\n",
154 | " names = [os.path.basename(x) for x in filenames]\n",
155 | " return pd.DatetimeIndex([pd.Timestamp(f[4:8]+f[9:11]+f[12:14]) for f in names])\n",
156 | " "
157 | ],
158 | "execution_count": null,
159 | "outputs": []
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {
164 | "id": "C10yp6qVd4qR",
165 | "colab_type": "text"
166 | },
167 | "source": [
168 | "Iterate through all LSTcont folders in Google Drive and create 1 NetCDF from each folder (1 file for entire year)"
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "metadata": {
174 | "id": "IW1XZqow78To",
175 | "colab_type": "code",
176 | "colab": {
177 | "base_uri": "https://localhost:8080/",
178 | "height": 72
179 | },
180 | "outputId": "cdd1eef3-6281-4f67-fc48-565054a0a351"
181 | },
182 | "source": [
183 | "for year in range (2017, 2018):\n",
184 | " filenames = sorted(glob.glob('/content/gdrive/My Drive/MODIS/' + str(year) + '/*.tif'))\n",
185 | " print(filenames)\n",
186 | " time = xr.Variable('time', time_index_from_filenames(filenames))\n",
187 | " chunks = {'x': 409, 'y': 603}\n",
188 | " da = xr.concat([xr.open_rasterio(f, chunks=chunks) for f in filenames], dim=time)\n",
189 | " da.to_netcdf(path='/content/gdrive/My Drive/MODIS/' + str(year) + '.nc', format='NETCDF4', mode='w', encoding={'__xarray_dataarray_variable__': {'dtype': 'float32', 'scale_factor': 0.02}}) \n",
190 | " print(year)"
191 | ],
192 | "execution_count": null,
193 | "outputs": [
194 | {
195 | "output_type": "stream",
196 | "text": [
197 | "['/content/gdrive/My Drive/MODIS/2017/LST_2017_01_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_01_31.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_02_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_03_31.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_04_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_05_31.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_06_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_07_31.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_08_31.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_09_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_10_31.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_11_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_01.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_02.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_03.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_04.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_05.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_06.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_07.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_08.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_09.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_10.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_11.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_12.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_13.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_14.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_15.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_16.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_17.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_18.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_19.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_20.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_21.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_22.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_23.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_24.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_25.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_26.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_27.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_28.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_29.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_30.tif', '/content/gdrive/My Drive/MODIS/2017/LST_2017_12_31.tif']\n",
198 | "2017\n"
199 | ],
200 | "name": "stdout"
201 | }
202 | ]
203 | },
204 | {
205 | "cell_type": "markdown",
206 | "metadata": {
207 | "id": "l21bfmp1ekey",
208 | "colab_type": "text"
209 | },
210 | "source": [
211 | "# Convert tiff to NetCDF using [gdal_translate](https://gdal.org/programs/gdal_translate.html#gdal-translate):"
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "metadata": {
217 | "colab_type": "code",
218 | "id": "dGpgXNxqfiSp",
219 | "colab": {}
220 | },
221 | "source": [
222 | "from google.colab import drive\n",
223 | "drive.mount('/content/gdrive')"
224 | ],
225 | "execution_count": null,
226 | "outputs": []
227 | },
228 | {
229 | "cell_type": "code",
230 | "metadata": {
231 | "colab_type": "code",
232 | "id": "5S6Hcb6tf-nf",
233 | "colab": {}
234 | },
235 | "source": [
236 | "import gdal"
237 | ],
238 | "execution_count": null,
239 | "outputs": []
240 | },
241 | {
242 | "cell_type": "code",
243 | "metadata": {
244 | "id": "9YUQfONsWksb",
245 | "colab_type": "code",
246 | "colab": {}
247 | },
248 | "source": [
249 | "filename = '/content/gdrive/My Drive/MODIS/LSTconst_validation_full.tif'\n",
250 | "da = gdal.Open(filename)\n",
251 | "out_ds = gdal.Translate('/content/gdrive/My Drive/MODIS/LSTconst_validation.nc', da, options= \"bandList=[1,2,3] format='NC4'\")\n",
252 | "print(da.RasterCount)\n",
253 | "print(out_ds)"
254 | ],
255 | "execution_count": null,
256 | "outputs": []
257 | }
258 | ]
259 | }
260 |
--------------------------------------------------------------------------------
/Explore TFA graphs:
--------------------------------------------------------------------------------
1 | // This code allows the reader to investigate the effects of topography
2 | // and vegetation on the anomalies and LSTcont.
3 | var CFSV2_TFA = ee.Image("users/shilosh/CFSv2_Daily_LST_TFA"),
4 | MODIS_TFA = ee.Image("users/shilosh/MODIS_Daily_LST_TFA"),
5 | LST_Cont = ee.Image("users/shilosh/MODIS_Continuous_LST_Daily_2018");
6 |
7 | var firstDay = '2018-01-01';
8 | var lastDay = '2019-01-01';
9 | var Temperature_Band = 'LST_Daily_Mean';
10 | var Day_Temperature_Band = 'LST_Day_1km';
11 | var Night_Temperature_Band = 'LST_Night_1km';
12 | var collection = 'MODIS/006/MYD11A1';
13 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
14 | var geometry_json = geometry.toGeoJSON();
15 |
16 | // Zoom to a location.
17 | Map.setCenter(34.80, 31.25, 9); // Center on Beer-Sheva
18 |
19 | // Reverse the images into imageCollections
20 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
21 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
22 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
23 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
24 | var Cont_LST = ee.ImageCollection(LST_Cont.bandNames().map(function(name) {
25 | return LST_Cont.select([ee.Algorithms.String(name)],['contLst']).set('system:time_start', ee.Date(ee.Algorithms.String(name).replace('day_',''))) }))
26 |
27 | print('Cont_LST = ', Cont_LST)
28 |
29 | //convert Kelvin to Celsius
30 | var MODIS_k2celsius = function(image) {
31 | return image.updateMask(image.select(Day_Temperature_Band))
32 | .updateMask(image.select(Night_Temperature_Band))
33 | .reduce( ee.Reducer.mean()).rename(Temperature_Band)
34 | .multiply(ee.Image(0.02))
35 | .subtract(ee.Image(273.15)) //convert Kelvin to Celsius
36 | .set('system:time_start', image.get('system:time_start'));
37 | };
38 | var CFSV2_k2celsius = function(image) {
39 | return image.subtract(ee.Image(273.15))
40 | .set('system:time_start', image.get('system:time_start'));
41 | };
42 |
43 | // Add a property with doy to the colection.
44 | function createDoyProperty(img) {
45 | var d = ee.Date(img.get('system:time_start'))
46 | .getRelative('day', 'year')
47 | .add(1);
48 | return img.set('system:DOY', d);
49 | }
50 |
51 | // var MODIS_Daily = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
52 | // return ee.ImageCollection(collection)
53 | // .select(Day_Temperature_Band, Night_Temperature_Band)
54 | // .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
55 | // .map(MODIS_k2celsius)
56 | // .mean()
57 | // .set('system:DOY',doy)
58 | // }))
59 | var MODIS_Daily = ee.ImageCollection(collection)
60 | .filterDate(firstDay, lastDay)
61 | .select('LST_Day_1km', 'LST_Night_1km')
62 | // .map(function (image){return image.reduce(ee.Reducer.mean())
63 | // .set('system:time_start', image.get('system:time_start'))})
64 | // .map(addTimeStampToMODIS)
65 | .map(MODIS_k2celsius)
66 | .map(createDoyProperty)
67 | print('MODIS_Daily = ', MODIS_Daily)
68 |
69 | var CFSV2_Daily = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
70 | return ee.ImageCollection('NOAA/CFSV2/FOR6H')
71 | .filterDate(firstDay, lastDay)
72 | .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
73 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
74 | .map(CFSV2_k2celsius)
75 | .mean()
76 | .set('system:DOY',doy)
77 | }))
78 | print('CFSV2_Daily = ', CFSV2_Daily)
79 |
80 | // Use an equals filter to specify how the collections match.
81 | var Filter = ee.Filter.equals({
82 | leftField: 'system:DOY',
83 | rightField: 'system:DOY'
84 | });
85 | // Define the join.
86 | var innerJoin = ee.Join.inner('primary', 'secondary');
87 |
88 | // Join CFSV2 with CFSV2_TFA_ic by DOY
89 | // Apply the join.
90 | var CFSV2_JoinInner = innerJoin.apply(CFSV2_Daily, CFSV2_TFA_ic, Filter);
91 |
92 | // Calculate CFSv2 anomalies
93 | CFSV2_Daily = CFSV2_JoinInner.map(function(f) {
94 | var CFSv2_TFA = ee.Image(f.get('secondary'));
95 | var CFSv2_Daily_mean = ee.Image(f.get('primary'));
96 |
97 | return CFSv2_Daily_mean.addBands(CFSv2_TFA.rename('CFSv2_TFA'));
98 | })
99 |
100 | // Join CFSV2 with MODIS_TFA_ic by DOY
101 | // Apply the join.
102 | var CFSV2_JoinInner = innerJoin.apply(CFSV2_Daily, MODIS_TFA_ic, Filter);
103 |
104 | // Calculate CFSv2 anomalies
105 | CFSV2_Daily = CFSV2_JoinInner.map(function(f) {
106 | var Modis_TFA = ee.Image(f.get('secondary'));
107 | var CFSv2 = ee.Image(f.get('primary'));
108 |
109 | return CFSv2.addBands(Modis_TFA.rename('MODIS_TFA'));
110 | })
111 |
112 | // Join all with MODIS_Daily by DOY
113 | // Apply the join.
114 | var CFSV2_JoinInner = innerJoin.apply(CFSV2_Daily, MODIS_Daily, Filter);
115 |
116 | // Calculate CFSv2 anomalies
117 | CFSV2_Daily = CFSV2_JoinInner.map(function(f) {
118 | var Modis_daily_mean = ee.Image(f.get('secondary'));
119 | var CFSv2 = ee.Image(f.get('primary'));
120 |
121 | return CFSv2.addBands(Modis_daily_mean.rename('MODIS_Daily'));
122 | })
123 |
124 | var timeFromDOY_LST = function(image) {
125 | var days = ee.Number(image.get('system:DOY'))
126 | // var d = ee.Date('2010-01-01')
127 | var d = ee.Date(firstDay)
128 | return image
129 | .set('system:time_start', d.advance(days.subtract(1), 'day'));
130 | };
131 | CFSV2_Daily = CFSV2_Daily.map(timeFromDOY_LST)
132 | print('CFSV2_Daily = ', CFSV2_Daily)
133 |
134 | // Use an equals filter to specify how the collections match.
135 | var Filter = ee.Filter.equals({
136 | leftField: 'system:time_start',
137 | rightField: 'system:time_start'
138 | });
139 |
140 | // Join all with Cont_LST by system:time_start
141 | // Apply the join.
142 | var CFSV2_JoinInner = innerJoin.apply(CFSV2_Daily, Cont_LST, Filter);
143 |
144 | // Calculate CFSv2 anomalies
145 | CFSV2_Daily = CFSV2_JoinInner.map(function(f) {
146 | var cont_lst = ee.Image(f.get('secondary'));
147 | var CFSv2 = ee.Image(f.get('primary'));
148 |
149 | return CFSv2.addBands(cont_lst);
150 | })
151 | print('CFSV2_Daily = ', CFSV2_Daily)
152 |
153 | var scale = ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().nominalScale().getInfo();
154 | // Map.addLayer(ee.Image(MaskedValues.first()).select('con'))
155 | // Map.addLayer(rmse_val)
156 |
157 | var panel = ui.Panel();
158 | panel.style().set('width', '300px');
159 |
160 | // Create an intro panel with labels.
161 | var intro = ui.Panel([
162 | ui.Label({
163 | value: 'LSTcont Chart Inspector',
164 | style: {fontSize: '20px', fontWeight: 'bold'}
165 | }),
166 | ui.Label('Click a point on the map to inspect 2018 data.')
167 | ]);
168 | panel.add(intro);
169 |
170 | // Create panels to hold lon/lat values.
171 | var lon = ui.Label();
172 | var lat = ui.Label();
173 | panel.add(ui.Panel([lon, lat], ui.Panel.Layout.flow('horizontal')));
174 |
175 | // Register a callback on the default map to be invoked when the map is clicked.
176 | Map.onClick(function(coords) {
177 | // Update the lon/lat panel with values from the click event.
178 | lon.setValue('lon: ' + coords.lon.toFixed(2)),
179 | lat.setValue('lat: ' + coords.lat.toFixed(2));
180 |
181 | // Add a red dot for the point clicked on.
182 | var point = ee.Geometry.Point(coords.lon, coords.lat);
183 | var dot = ui.Map.Layer(point, {color: 'FF0000'});
184 | Map.layers().set(1, dot);
185 |
186 | // Create an LST TFA chart.
187 | // var series = ui.Chart.image.doySeriesByYear(
188 | // LST, Temperature_Band, geometry, ee.Reducer.mean(), 500);
189 | var series = ui.Chart.image.series(
190 | CFSV2_Daily, point, ee.Reducer.mean(), 500);
191 | series.setOptions({
192 | title: 'LST & ContinuousLST',
193 | vAxis: {title: 'Celsius'},
194 | hAxis: {title: 'Day of year', gridlines: {count: 7}},
195 | });
196 | panel.widgets().set(2, series);
197 | });
198 |
199 | Map.style().set('cursor', 'crosshair');
200 |
201 | // Add the panel to the ui.root.
202 | ui.root.insert(0, panel);
203 |
--------------------------------------------------------------------------------
/LST_in_Qgis.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shilosh/ContinuousLST/877fb82f2a62f7bb5015e178638f5a6c1623eba6/LST_in_Qgis.gif
--------------------------------------------------------------------------------
/LSTcont_web_app:
--------------------------------------------------------------------------------
1 | // A UI to interactively filter to a certain date, zoom to an area of interest,
2 | // display the LSTcont (gap-filled LST) for the current extent, and export it as geotif.
3 |
4 | var contLST = function(day, geometry){
5 | var CFSV2_TFA = ee.Image("users/shilosh/CFSv2_TFA_Daily_Global"),
6 | MODIS_TFA = ee.Image("users/shilosh/MODIS_TFA_Daily_Global");
7 | var firstDay = day;
8 | var lastDay = ee.Date(day).advance(1, 'day');
9 | var Temperature_Band = 'Maximum_temperature_height_above_ground_6_Hour_Interval';
10 | var Day_Temperature_Band = 'LST_Day_1km';
11 | var Night_Temperature_Band = 'LST_Night_1km';
12 | var collection = 'NOAA/CFSV2/FOR6H';
13 |
14 | //Multiply by the scale factor to retrive the original values
15 | MODIS_TFA = MODIS_TFA.multiply(0.02)
16 | // Reverse the images into imageCollections
17 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
18 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
19 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
20 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
21 |
22 | var modisProjection = MODIS_TFA.projection().crs().getInfo()
23 | var scale = ee.Image(MODIS_TFA).projection().nominalScale().getInfo();
24 |
25 | // Get the CFSv2 data at MODIS scale and projection.
26 | var resample = function(image) {
27 | return image.resample('bilinear')
28 | .reproject({
29 | crs: modisProjection,
30 | scale: scale})
31 | .set('system:DOY', image.get('system:DOY'))
32 | .set('system:time_start', image.get('system:time_start'));
33 | };
34 |
35 | //convert Kelvin to Celsius
36 | var k2celsius = function(image) {
37 | return image.subtract(ee.Image(273.15))
38 | .clip(geometry)
39 | .set('system:DOY', image.get('system:DOY'))
40 | .set('system:time_start', image.get('system:time_start'));};
41 |
42 | // Add a property with doy to the colection.
43 | function createDoyBand(img) {
44 | var d = ee.Date(img.get('system:time_start'))
45 | .getRelative('day', 'year')
46 | .add(1);
47 | img=img.set('system:DOY', d);
48 | return img;
49 | }
50 |
51 | // Construct image date from 'system:index' and add it to a new 'date' property
52 | var addTimeStampToCFSv2 = function(image) {
53 | var start = ee.String(image.get('system:index'));
54 | var y = start.slice(0,4);
55 | var m = start.slice(4,6);
56 | var d = start.slice(6,8);
57 | var date = y.cat('-').cat(m).cat('-').cat(d);
58 | return image.set({'system:time_start': date});
59 | };
60 | // Construct image date from 'system:index' and add it to a new 'date' property
61 | var addTimeStampToMODIS = function(image) {
62 | var start = ee.String(image.get('system:index'));
63 | // var date = start.replace(/_/g, '-');
64 | start = start.replace('_', '-');
65 | var date = start.replace('_', '-');
66 | return image.set({'system:time_start': ee.String(date)});
67 | };
68 |
69 | // Calculate the daily mean of the 4 images (00, 06, 12, 18)
70 | var daily_mean = function(image) {
71 | return image.reduce(ee.Reducer.mean())
72 | .set('system:DOY', image.get('system:DOY'))
73 | .set('system:time_start', image.get('system:time_start'));
74 | };
75 |
76 | CFSV2_TFA_ic = CFSV2_TFA_ic.map(resample);
77 |
78 | // Convert the date string into milliseconds integer
79 | var dayMillis = 86400000 // 86400000 is 1 day in milliseconds
80 | var intFirstDay = ee.Date(firstDay).millis()
81 | var intLastDay = ee.Date(lastDay).millis().subtract(dayMillis)
82 |
83 | // Collect all 4 images of each day and create imageCollection from the daily mean.
84 | var CFSV2 = ee.ImageCollection(ee.List.sequence(intFirstDay, intLastDay, dayMillis).map(function (day){
85 | return ee.ImageCollection('NOAA/CFSV2/FOR6H')
86 | .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
87 | .filterDate(day, ee.Number(day).add(dayMillis))
88 | // .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
89 | .map(resample)
90 | .map(k2celsius)
91 | .mean()
92 | .set({'system:DOY': ee.Date(day).getRelative('day', 'year').add(1)})
93 | .set({'system:time_start': ee.Date(day)})
94 | }))
95 |
96 | // Use an equals filter to specify how the collections match.
97 | var Filter = ee.Filter.equals({
98 | leftField: 'system:DOY',
99 | rightField: 'system:DOY'
100 | });
101 | // Define the join.
102 | var innerJoin = ee.Join.inner('primary', 'secondary');
103 |
104 | // Join CFSV2 with CFSV2_TFA_ic by DOY
105 | // Apply the join.
106 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
107 |
108 | // Calculate CFSv2 anomalies
109 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
110 | var tfa = ee.Image(f.get('secondary'));
111 | var actual = ee.Image(f.get('primary'));
112 | return actual.subtract(tfa)
113 | .set('system:time_start', actual.get('system:time_start'))
114 | .set('system:DOY', actual.get('system:DOY'));
115 | })//.map(addTimeStampToCFSv2)
116 | //.map(createDoyBand);
117 |
118 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
119 | // Apply the join.
120 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
121 | // print('MODIS_JoinInner = ' ,MODIS_JoinInner)
122 |
123 | // Calculate MODIS TFA Plus CFSv2 anomalies
124 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
125 | var anomalies = ee.Image(f.get('primary'));
126 | var tfa = ee.Image(f.get('secondary'));
127 | // Anomalies at night do not conribute to the TFA only prediction,
128 | // therefor because we are trying to predict daily mean LST, we only add half of the daily anomalies
129 | return (anomalies.divide(ee.Image(2))).add(tfa)//.subtract(anomalies);
130 | .set('system:time_start', anomalies.get('system:time_start'))
131 | .set('system:DOY', anomalies.get('system:DOY'));
132 | })//.map(addTimeStampToCFSv2)
133 | //.map(createDoyBand);
134 |
135 | // print('MODIS_Continuous = ' ,MODIS_Continuous)
136 |
137 | Temperature_Band = 'LST_Day_1km';
138 | collection = 'MODIS/006/MYD11A1';
139 | //convert Kelvin to Celsius
140 | var modis_k2celsius = function(image) {
141 | return image.updateMask(image.select(Day_Temperature_Band))
142 | .updateMask(image.select(Night_Temperature_Band))
143 | .reduce( ee.Reducer.mean()).rename(Temperature_Band)
144 | .multiply(ee.Image(0.02))
145 | .subtract(ee.Image(273.15))
146 | .clip(geometry)
147 | .set('system:time_start', ee.Date(image.get('system:time_start')))
148 | .rename([ee.String('daily_').cat(image.get('system:time_start'))]);
149 | };
150 |
151 | var MODIS_LST = ee.ImageCollection(collection)
152 | .filterDate(firstDay, lastDay)
153 | .select(Day_Temperature_Band, Night_Temperature_Band)
154 | //.map(function (image){return image.reduce(ee.Reducer.mean())})
155 | .map(addTimeStampToMODIS)
156 | .map(modis_k2celsius)
157 | // Use an equals filter to specify how the collections match.
158 | Filter = ee.Filter.equals({
159 | leftField: 'system:time_start',
160 | rightField: 'system:time_start'
161 | });
162 |
163 | // Join MODIS_LST with MODIS_TFA_plus_CFSV2_Anomalies by DOY
164 | // Apply the join.
165 | var MODIS_Blended_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
166 | // Blend the results to fill LST gaps
167 | var MODIS_LST_Blended_Daily = MODIS_Blended_JoinInner.map(function(f) {
168 | var prediction = ee.Image(f.get('secondary'));
169 | var lst = ee.Image(f.get('primary'));
170 | return prediction.blend(lst);
171 | })
172 | // ******* Day LSTcont *********
173 | MODIS_TFA = ee.Image("users/shilosh/MODIS_TFA_Day_Global");
174 |
175 | //Multiply by the scale factor to retrive the original values
176 | MODIS_TFA = MODIS_TFA.multiply(0.02)
177 | // Reverse the images into imageCollections
178 | MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
179 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
180 |
181 | MODIS_Continuous = MODIS_TFA_ic
182 |
183 | Temperature_Band = 'LST_Day_1km';
184 | collection = 'MODIS/006/MYD11A1';
185 | //convert Kelvin to Celsius
186 | var modis_day_k2celsius = function(image) {
187 | return image.updateMask(image.select(Day_Temperature_Band))
188 | .reduce( ee.Reducer.mean())
189 | .multiply(ee.Image(0.02))
190 | .subtract(ee.Image(273.15))
191 | .clip(geometry)
192 | .set('system:time_start', ee.Date(image.get('system:time_start')))
193 | .rename([ee.String('day_').cat(image.get('system:time_start'))]);
194 | };
195 |
196 | var MODIS_LST_Day = ee.ImageCollection(collection)
197 | .filterDate(firstDay, lastDay)
198 | .select(Day_Temperature_Band)
199 | //.map(function (image){return image.reduce(ee.Reducer.mean())})
200 | .map(addTimeStampToMODIS)
201 | .map(modis_day_k2celsius)
202 | .map(createDoyBand)
203 |
204 | // Use an equals filter to specify how the collections match.
205 | Filter = ee.Filter.equals({
206 | leftField: 'system:DOY',
207 | rightField: 'system:DOY'
208 | });
209 |
210 | // Join MODIS_LST with MODIS_TFA_plus_CFSV2_Anomalies by DOY
211 | // Apply the join.
212 | MODIS_Blended_JoinInner = innerJoin.apply(MODIS_LST_Day, MODIS_Continuous, Filter);
213 | // Blend the results to fill LST gaps
214 | var MODIS_LST_Blended_Day = MODIS_Blended_JoinInner.map(function(f) {
215 | var prediction = ee.Image(f.get('secondary'));
216 | var lst = ee.Image(f.get('primary'));
217 | return prediction.blend(lst);
218 | })
219 | // ******* Night LSTcont *********
220 | MODIS_TFA = ee.Image("users/shilosh/MODIS_TFA_Night_Global");
221 |
222 | //Multiply by the scale factor to retrive the original values
223 | MODIS_TFA = MODIS_TFA.multiply(0.02)
224 | // Reverse the images into imageCollections
225 | MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
226 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
227 |
228 | MODIS_Continuous = MODIS_TFA_ic
229 |
230 | Temperature_Band = 'LST_Night_1km';
231 | collection = 'MODIS/006/MYD11A1';
232 | //convert Kelvin to Celsius
233 | var modis_night_k2celsius = function(image) {
234 | return image.updateMask(image.select(Night_Temperature_Band))
235 | .reduce( ee.Reducer.mean())
236 | .multiply(ee.Image(0.02))
237 | .subtract(ee.Image(273.15))
238 | .clip(geometry)
239 | .set('system:time_start', ee.Date(image.get('system:time_start')))
240 | .rename([ee.String('Night_').cat(image.get('system:time_start'))]);
241 | };
242 |
243 | var MODIS_LST_Night = ee.ImageCollection(collection)
244 | .filterDate(firstDay, lastDay)
245 | .select(Night_Temperature_Band)
246 | //.map(function (image){return image.reduce(ee.Reducer.mean())})
247 | .map(addTimeStampToMODIS)
248 | .map(modis_night_k2celsius)
249 | .map(createDoyBand)
250 |
251 | // Use an equals filter to specify how the collections match.
252 | Filter = ee.Filter.equals({
253 | leftField: 'system:DOY',
254 | rightField: 'system:DOY'
255 | });
256 |
257 | // Join MODIS_LST with MODIS_TFA_plus_CFSV2_Anomalies by DOY
258 | // Apply the join.
259 | MODIS_Blended_JoinInner = innerJoin.apply(MODIS_LST_Night, MODIS_Continuous, Filter);
260 | // Blend the results to fill LST gaps
261 | var MODIS_LST_Blended_Night = MODIS_Blended_JoinInner.map(function(f) {
262 | var prediction = ee.Image(f.get('secondary'));
263 | var lst = ee.Image(f.get('primary'));
264 | return prediction.blend(lst);
265 | })
266 | // Check if current day exist, otherwise popup a msgbox
267 | if (MODIS_LST_Blended_Daily.first().getInfo()){
268 | return ee.Image(MODIS_LST_Blended_Daily.first())
269 | .addBands(ee.Image(MODIS_LST_Night.first()))
270 | .addBands(ee.Image(MODIS_LST_Blended_Night.first()))
271 | .addBands(ee.Image(MODIS_LST_Day.first()))
272 | .addBands(ee.Image(MODIS_LST_Blended_Day.first()))
273 |
274 | }else{
275 | alert("Can\'t calculate LST. \nThe selected date has no data");
276 | }
277 | };
278 |
279 | //_________________________________________________
280 |
281 | //function to calculate min & max band values for visualisation
282 | var min_max = function(image, attributeName, bounds){
283 | var minmax = image.reduceRegion({
284 | reducer:ee.Reducer.minMax(),
285 | geometry:bounds,
286 | maxPixels:10000000000,
287 | });
288 | var min = (minmax.getNumber(attributeName.cat('_min')))
289 | var max = (minmax.getNumber(attributeName.cat('_max')))
290 | min = min.getInfo()
291 | max = max.getInfo()
292 | return [min, max]
293 | }
294 | // _________________________________________________________________
295 | // A function to construct a legend for the given single-band vis
296 | // parameters. Requires that the vis parameters specify 'min' and
297 | // 'max' but not 'bands'.
298 | function makeLegend(vis) {
299 | var lon = ee.Image.pixelLonLat().select('longitude');
300 | var gradient = lon.multiply((vis.max-vis.min)/100.0).add(vis.min);
301 | var legendImage = gradient.visualize(vis);
302 |
303 | // Otherwise, add it to a panel and add the panel to the map.
304 | var thumb = ui.Thumbnail({
305 | image: legendImage,
306 | params: {bbox:'0,0,100,8', dimensions:'256x20'},
307 | style: {padding: '1px', position: 'bottom-center'}
308 | });
309 | var min = ee.Number(vis.min).format('%.1f')
310 | var max = ee.Number(vis.max).format('%.1f')
311 |
312 | var panel = ui.Panel({
313 | widgets: [
314 | // ui.Label(String(vis['min'])),
315 | ui.Label(min.getInfo()),
316 | ui.Label('°C'),
317 | ui.Label({style: {stretch: 'horizontal'}}),
318 | ui.Label(max.getInfo()),
319 | ui.Label('°C')
320 | ],
321 | layout: ui.Panel.Layout.flow('horizontal'),
322 | style: {stretch: 'horizontal'}
323 | });
324 | return ui.Panel().add(panel).add(thumb);
325 | }
326 | // _________________________________________________________________
327 |
328 | // A function to construct a panel for the getDownloadURL
329 | function makeUrlPanel(url) {
330 |
331 | // add the panel to the map.
332 | var panel = ui.Panel({
333 | widgets: [
334 | // ui.Label(String(vis['min'])),
335 | ui.Label(url),
336 | // ui.Label({style: {stretch: 'horizontal'}}),
337 | // ui.Label(max.getInfo())
338 | ],
339 | layout: ui.Panel.Layout.flow('horizontal'),
340 | style: {stretch: 'horizontal'}
341 | });
342 | return ui.Panel().add(panel)//.add(thumb);
343 | }
344 |
345 | // _______________________________________________________
346 |
347 | // The namespace for our application. All the state is kept in here.
348 | var app = {};
349 | // Map.setCenter(-3,40,9)
350 | var Datestart = '2020-05-01'
351 |
352 | /** Creates the UI panels. */
353 | app.createPanels = function() {
354 | /* The introduction section. */
355 | app.intro = {
356 | panel: ui.Panel([
357 | ui.Label({
358 | value: 'Continuous MODIS LST',
359 | style: {fontWeight: 'bold', fontSize: '22px', margin: '10px 5px'}
360 | }),
361 | ui.Label('This app uses time-series analysis technics ' +
362 | 'to predict MODIS LST (MYD11A1) values in cloudy pixels.',{fontSize:'12px'})
363 | ])
364 | };
365 |
366 | /* The collection filter controls. */
367 | app.filters = {
368 | startDate: ui.DateSlider({
369 | start: '2002-07-04',
370 | value: Datestart,
371 | period: 1,
372 | style: {width: '250px'},
373 | }),
374 | applyButton: ui.Button('Calculate LST for current extent', app.applyFilters),
375 | loadingLabel: ui.Label({
376 | value: 'Loading...',
377 | style: {stretch: 'vertical', color: 'gray', shown: false}
378 | })
379 | };
380 |
381 | /* The panel for the filter control widgets. */
382 | app.filters.panel = ui.Panel({
383 | widgets: [
384 | ui.Label('1) LST date', {fontWeight: 'bold'}),
385 | //ui.Label('Start date', app.HELPER_TEXT_STYLE),
386 | app.filters.startDate,
387 | // app.filters.mapCenter,
388 | ui.Panel([
389 | app.filters.applyButton,
390 | app.filters.loadingLabel
391 | ], ui.Panel.Layout.flow('horizontal'))
392 | ],
393 | style: app.SECTION_STYLE
394 | });
395 |
396 | /* The export section. */
397 | app.export = {
398 | button: ui.Button({
399 | label: 'Export the current image',
400 | // React to the button's click event.
401 | onClick: function() {
402 | // Select the full image id.
403 | var image = app.image;
404 |
405 | var bounds = ee.Geometry.Rectangle(Map.getBounds(),'EPSG:4326', false);
406 | var ExportingLinks;
407 | if (bounds.area(1000).divide(1000000).getInfo() < 500000){
408 | var url = image.getDownloadURL({
409 | name: "LST_",
410 | // region: ROI,
411 | scale: 1000,//Map.getScale(),
412 | format: 'GeoTIFF',
413 | crs: "EPSG:4326",
414 | });
415 | // print(url)
416 | ExportingLinks=ui.Label('Click to download').setUrl(url); //This creates a hyper link.
417 | app.urlWidget = ExportingLinks
418 | app.export.panel.add(ExportingLinks);
419 | }else{
420 | ExportingLinks=ui.Label('Can\'t download, area is too big',{color:'red',fontWeight :'bold'})
421 | app.export.panel.add(ExportingLinks);
422 | alert("Can\'t download, area is too big. \nDownloadable area is limited to 500,000 sq Km");
423 | }
424 | }
425 | })
426 | };
427 |
428 | /* The panel for the export section with corresponding widgets. */
429 | var geeCodeUrl = 'https://code.earthengine.google.com/?scriptPath=users%2Fshilosh%2Fdefault%3AUser%20Interface%2FLSTcont%20Explorer'
430 | app.export.panel = ui.Panel({
431 | widgets: [
432 | ui.Label('2) Start an export', {fontWeight: 'bold'}),
433 | ui.Label('Click the button to prepare the image and then click the link ' +
434 | 'bellow to download the image as a geotiff. ' +
435 | 'Downloadable area is limited to 500,000 sq Km',{fontSize:'12px'}),
436 | ui.Label('If larger area is needed, click here and ' +
437 | 'log in as a Google Earth Engine User',{fontSize:'12px'}).setUrl(geeCodeUrl),
438 | app.export.button
439 | ],
440 | style: app.SECTION_STYLE
441 | });
442 | };
443 |
444 | /** Creates the app helper functions. */
445 | app.createHelpers = function() {
446 | /**
447 | * Enables or disables loading mode.
448 | * @param {boolean} enabled Whether loading mode is enabled.
449 | */
450 | app.setLoadingMode = function(enabled) {
451 | // Set the loading label visibility to the enabled mode.
452 | app.filters.loadingLabel.style().set('shown', enabled);
453 | // Set each of the widgets to the given enabled mode.
454 | var loadDependentWidgets = [
455 | // app.vis.select,
456 | app.filters.startDate,
457 | // app.filters.endDate,
458 | app.filters.applyButton,
459 | // app.filters.mapCenter,
460 | // app.picker.select,
461 | // app.picker.centerButton,
462 | app.export.button
463 | ];
464 | loadDependentWidgets.forEach(function(widget) {
465 | widget.setDisabled(enabled);
466 | });
467 | };
468 |
469 | /** Applies the selection filters currently selected in the UI. */
470 | app.applyFilters = function() {
471 | app.setLoadingMode(true);
472 | var filtered = ee.ImageCollection(app.COLLECTION_ID);
473 |
474 | // Set filter variables.
475 | var start = ee.Date(app.filters.startDate.getValue()[0]).format('yyyy-MM-dd');
476 |
477 | // // Update the image picker with the given list of ids.
478 | app.setLoadingMode(false);
479 | // Refresh the map layer.
480 | app.refreshMapLayer();
481 | };
482 |
483 | /** Refreshes the current map layer based on the UI widget states. */
484 | app.refreshMapLayer = function() {
485 | Map.clear();
486 | // var imageId = app.picker.select.getValue();
487 | // if (app.image) {
488 | // If an image is found, create an image.
489 | // var image = ee.Image(app.COLLECTION_ID + '/' + imageId );
490 | var bounds = ee.Geometry.Rectangle(Map.getBounds(),'EPSG:4326', false);
491 | // print(bounds.area(1000).divide(1000000))
492 | var day = ee.Date(app.filters.startDate.getValue()[0]).format('yyyy-MM-dd');
493 | var image = contLST(day, bounds)
494 | // Add the image to the map with the corresponding visualization options.
495 | // var visOption = app.VIS_OPTIONS[app.vis.select.getValue()];
496 | app.image = image
497 | var attributeName = ee.String(image.bandNames().getString(0))
498 | var minmax = min_max(image, attributeName, bounds)
499 | app.visParams = {min:minmax[0], max:minmax[1], palette: [
500 | '040274', '040281', '0502a3', '0502b8', '0502ce', '0502e6',
501 | '0602ff', '235cb1', '307ef3', '269db1', '30c8e2', '32d3ef',
502 | '3be285', '3ff38f', '86e26f', '3ae237', 'b5e22e', 'd6e21f',
503 | 'fff705', 'ffd611', 'ffb613', 'ff8b13', 'ff6e08', 'ff500d',
504 | 'ff0000', 'de0101', 'c21301', 'a71001', '911003'
505 | ],}
506 | Map.addLayer(image.select(0), app.visParams, 'Daily continuous LST',true,0.7);
507 | attributeName = ee.String(image.select(2).bandNames().getString(0))
508 | minmax = min_max(image, attributeName, bounds)
509 | Map.addLayer(image.select(1),
510 | {min:minmax[0], max:minmax[1]}, 'Night original LST',false,0.7);
511 | Map.addLayer(image.select(2),
512 | {min:minmax[0], max:minmax[1]}, 'Night continuous LST',false,0.7); attributeName = ee.String(image.select(2).bandNames().getString(0))
513 | attributeName = ee.String(image.select(4).bandNames().getString(0))
514 | minmax = min_max(image, attributeName, bounds)
515 | Map.addLayer(image.select(3),
516 | {min:minmax[0], max:minmax[1]}, 'Day original LST',false,0.7);
517 | Map.addLayer(image.select(4),
518 | {min:minmax[0], max:minmax[1]}, 'Day continuous LST',false,0.7); Map.add(makeLegend(app.visParams));
519 | app.export.panel.remove(app.urlWidget)
520 | // }
521 | };
522 | };
523 |
524 | /** Creates the app constants. */
525 | app.createConstants = function() {
526 | app.COLLECTION_ID = 'LANDSAT/LC08/C01/T1_RT_TOA';
527 | app.SECTION_STYLE = {margin: '20px 0 0 0'};
528 | app.HELPER_TEXT_STYLE = {
529 | margin: '8px 0 -3px 8px',
530 | fontSize: '12px',
531 | color: 'gray'
532 | };
533 | // app.IMAGE_COUNT_LIMIT = 10;
534 | app.urlWidget = ui.Label()
535 | app.image = 0
536 | app.visParams = {}
537 | // app.VIS_OPTIONS = {
538 | // 'False color (B7/B6/B4)': {
539 | // description: 'Vegetation is shades of red, urban areas are ' +
540 | // 'cyan blue, and soils are browns.',
541 | // visParams: {gamma: 1.3, min: 0, max: 0.3, bands: ['B7', 'B6', 'B4']}
542 | // },
543 | // 'Natural color (B4/B3/B2)': {
544 | // description: 'Ground features appear in colors similar to their ' +
545 | // 'appearance to the human visual system.',
546 | // visParams: {gamma: 1.3, min: 0, max: 0.3, bands: ['B4', 'B3', 'B2']}
547 | // },
548 | // 'Atmospheric (B7/B6/B5)': {
549 | // description: 'Coast lines and shores are well-defined. ' +
550 | // 'Vegetation appears blue.',
551 | // visParams: {gamma: 1.3, min: 0, max: 0.3, bands: ['B7', 'B6', 'B5']}
552 | // }
553 | // };
554 | };
555 |
556 | /** Creates the application interface. */
557 | app.boot = function() {
558 | app.createConstants();
559 | app.createHelpers();
560 | app.createPanels();
561 | var main = ui.Panel({
562 | widgets: [
563 | app.intro.panel,
564 | app.filters.panel,
565 | // app.picker.panel,
566 | // app.vis.panel,
567 | app.export.panel
568 | ],
569 | style: {width: '320px', padding: '8px'}
570 | });
571 | // Map.setCenter(-3, 40, 9);
572 | ui.root.insert(0, main);
573 | app.applyFilters();
574 | };
575 |
576 | app.boot();
577 |
--------------------------------------------------------------------------------
/MODIS_TFA_Daily_Mean_Export_2_Assets:
--------------------------------------------------------------------------------
1 | // This code uses Temporal Fourier Analysis to build 365 images, for each day of year,
2 | // of the climatological tempratures based on the daily mean temperatures.
3 |
4 | // Change the path to your own assets folder
5 | var Assets_path = 'users/shilosh/MODIS_TFA_Daily_'
6 |
7 | var Temperature_Band = 'LST_Daily_Mean';
8 | var Day_Temperature_Band = 'LST_Day_1km';
9 | var Night_Temperature_Band = 'LST_Night_1km';
10 | var collection = 'MODIS/006/MYD11A1';
11 | // var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]); //Israel
12 | var geometry = ee.Geometry.Rectangle([20,50,25,54]); //Poland
13 | // var geometry = ee.Geometry.Rectangle([43,0,48,4]); //France
14 | // var geometry = ee.Geometry.Rectangle([49,7,54,11]); //Germany
15 | // var geometry = ee.Geometry.Rectangle([-76,36.0,-79,40]); //Maryland
16 | // var geometry = ee.Geometry.Rectangle([-90,41,-95,44.0]);//Iowa
17 | // var geometry = ee.Geometry.Rectangle([-60,-6,-55,-2]); //Brazil
18 | // var geometry = ee.Geometry.Rectangle([-50,-20,-45,-16]); //SouthBrazil
19 | // var geometry = ee.Geometry.Rectangle([-69,-34,-64,-30]); //Argentina
20 | // var geometry = ee.Geometry.Rectangle([12,24,17,28]); //Libya (Sahara)
21 | // var geometry = ee.Geometry.Rectangle([105,30,110,34]); //China
22 | // var geometry = ee.Geometry.Rectangle([145,-37,150,-33]); //SouthAustralia
23 | // var geometry = ee.Geometry.Rectangle([135,-25,140,-20]); //MidAustralia
24 | // var geometry = ee.Geometry.Rectangle([-130,58,-125,62]); //Canada (Mid latitudes)
25 |
26 |
27 | // var TFA_File_Name = 'MODIS_Daily_TFA_Israel'
28 | var TFA_File_Name = 'MODIS_Daily_TFA_Poland'
29 | // var TFA_File_Name = 'MODIS_Daily_TFA_France'
30 | // var TFA_File_Name = 'MODIS_Daily_TFA_Germany'
31 | // var TFA_File_Name = 'MODIS_Daily_TFA_Maryland'
32 | // var TFA_File_Name = 'MODIS_Daily_TFA_Iowa'
33 | // var TFA_File_Name = 'MODIS_Daily_TFA_Brazil'
34 | // var TFA_File_Name = 'MODIS_Daily_TFA_SouthBrazil'
35 | // var TFA_File_Name = 'MODIS_Daily_TFA_Argentina'
36 | // var TFA_File_Name = 'MODIS_Daily_TFA_Libya'
37 | // var TFA_File_Name = 'MODIS_Daily_TFA_China'
38 | // var TFA_File_Name = 'MODIS_Daily_TFA_SouthAustralia'
39 | // var TFA_File_Name = 'MODIS_Daily_TFA_MidAustralia'
40 | // var TFA_File_Name = 'MODIS_Daily_TFA_Canada'
41 |
42 | var geometry_json = geometry.toGeoJSON();
43 | // The number of cycles per year to model.
44 | var harmonics = 3;
45 |
46 | // Make a list of harmonic frequencies to model.
47 | // These also serve as band name suffixes.
48 | var harmonicFrequencies = ee.List.sequence(1, harmonics);
49 | // Function to get a sequence of band names for harmonic terms.
50 | var getNames = function(base, list) {
51 | return ee.List(list).map(function(i) {
52 | return ee.String(base).cat(ee.Number(i).int());
53 | });
54 | };
55 |
56 | // Construct lists of names for the harmonic terms.
57 | var cosNames = getNames('cos_', harmonicFrequencies);
58 | var sinNames = getNames('sin_', harmonicFrequencies);
59 |
60 | //convert Kelvin to Celsius
61 | var k2celsius = function(image) {
62 | return image.updateMask(image.select(Day_Temperature_Band))
63 | .updateMask(image.select(Night_Temperature_Band))
64 | .reduce( ee.Reducer.mean()).rename(Temperature_Band)
65 | .multiply(ee.Image(0.02))
66 | .subtract(ee.Image(273.15)) //convert Kelvin to Celsius
67 | .set('doy', image.get('doy'));
68 | };
69 | // Add a band with doy to the colection.
70 | function createDoyBand(img) {
71 | var d = ee.Number(img.get('doy'))
72 | return img.addBands(ee.Image(d).rename('t'));
73 | }
74 |
75 | // Function to compute the specified number of harmonics
76 | // and add them as bands.
77 | // for p = 0, Nharmonics-1 do begin
78 | // a[p] = a[p] + 2*TS_t*cos(2*!pi*(p+1)*(t+1)/N)
79 | // b[p] = b[p] + 2*TS_t*sin(2*!pi*(p+1)*(t+1)/N)
80 | var addHarmonics = function(freqs) {
81 | return function(image) {
82 | // Make an image of frequencies.
83 | var frequencies = ee.Image.constant(freqs);
84 | // This band should represent lst.
85 | var lst = ee.Image(image).select(Temperature_Band);
86 | // This band should represent days from start.
87 | var time = ee.Image(image).select('t');
88 | // Get the cosine terms.
89 | var cosines = lst.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).cos())
90 | .rename(cosNames);
91 | // Get the sin terms.
92 | var sines = lst.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).sin())
93 | .rename(sinNames);
94 | return image.addBands(cosines).addBands(sines);
95 | };
96 | };
97 |
98 | var LST_Day = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
99 | return ee.ImageCollection(collection)
100 | .select(Day_Temperature_Band)
101 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
102 | .mean()
103 | .set({doy: doy})
104 | //.addBands(ee.Image(ee.Number(doy)).rename('t'))
105 | }))
106 | var LST_Night = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
107 | return ee.ImageCollection(collection)
108 | .select(Night_Temperature_Band)
109 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
110 | .mean()
111 | .set({doy: doy})
112 | //.addBands(ee.Image(ee.Number(doy)).rename('t'))
113 | }))
114 | print('LST_Day = ', LST_Day)
115 | // // For each day cloudy pixels with no data, insert yearly mean values.
116 | // var LST_Mean
117 | // function BlendWithYearlyMean(img) {
118 | // return img.blend(LST_Mean);
119 | // }
120 | // LST_Mean = LST_Day.mean()
121 | // LST_Day = LST_Day.map(BlendWithYearlyMean)
122 | // LST_Mean = LST_Night.mean()
123 | // LST_Night = LST_Night.map(BlendWithYearlyMean)
124 |
125 | // Use an equals filter to specify how the collections match.
126 | var Filter = ee.Filter.equals({
127 | leftField: 'doy',
128 | rightField: 'doy'
129 | });
130 | // Define the join.
131 | var innerJoin = ee.Join.inner('primary', 'secondary');
132 |
133 | // Join LST_Day with LST_Night by DOY
134 | // Apply the join.
135 | var CFSV2_JoinInner = innerJoin.apply(LST_Day, LST_Night, Filter);
136 |
137 | // Add band
138 | var LST = CFSV2_JoinInner.map(function(f) {
139 | var Night = ee.Image(f.get('secondary'));
140 | var Day = ee.Image(f.get('primary'));
141 |
142 | return Day.addBands(Night);
143 | })
144 |
145 | LST = ee.ImageCollection(LST)
146 | .map(k2celsius)
147 | .map(createDoyBand)
148 | print('LST = ', LST)
149 | LST = LST.map(addHarmonics(harmonicFrequencies));
150 |
151 | // a = a / N_TS
152 | // b = b / N_TS
153 | var num_days = 365;//ee.Date(lastDay).difference(ee.Date(firstDay), 'day');
154 | var a_coef_1 = LST.select('cos_1').sum().divide(num_days);
155 | var a_coef_2 = LST.select('cos_2').sum().divide(num_days);
156 | var a_coef_3 = LST.select('cos_3').sum().divide(num_days);
157 | var b_coef_1 = LST.select('sin_1').sum().divide(num_days);
158 | var b_coef_2 = LST.select('sin_2').sum().divide(num_days);
159 | var b_coef_3 = LST.select('sin_3').sum().divide(num_days);
160 |
161 | // ; ========================================
162 | // ; prepare the first 3 harmonics of the TFA
163 | // ; ========================================
164 | // H0 = total(TS) / N_TS ;mean
165 | // FTA = MAKE_ARRAY(N_TS, /FLOAT, VALUE=0.)
166 | // H = MAKE_ARRAY(Nharmonics, N_TS, /FLOAT, VALUE=0.)
167 | // omega = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
168 | // Phase = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
169 | // Amplitude = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
170 | // for p = 0, Nharmonics-1 do begin
171 | // omega[p] = 2. * !pi * (p+1) / N
172 | // Phase[p] = atan( -b[p], a[p] )
173 | // Amplitude[p] = sqrt( a[p]^2 + b[p]^2 )
174 |
175 | var H0 = LST.select(Temperature_Band).mean();
176 | // Get the omega terms.
177 | var omega_1 = ee.Image(1.0).multiply(2.0 * Math.PI).divide(365.0);
178 | var omega_2 = ee.Image(2.0).multiply(2.0 * Math.PI).divide(365.0);
179 | var omega_3 = ee.Image(3.0).multiply(2.0 * Math.PI).divide(365.0);
180 |
181 | var phase_1 = a_coef_1.atan2(b_coef_1.multiply(ee.Image(-1.0)));
182 | var phase_2 = a_coef_2.atan2(b_coef_2.multiply(ee.Image(-1.0)));
183 | var phase_3 = a_coef_3.atan2(b_coef_3.multiply(ee.Image(-1.0)));
184 |
185 | var amplitude_1 = (a_coef_1.pow(2).add(b_coef_1.pow(2))).sqrt();
186 | var amplitude_2 = (a_coef_2.pow(2).add(b_coef_2.pow(2))).sqrt();
187 | var amplitude_3 = (a_coef_3.pow(2).add(b_coef_3.pow(2))).sqrt();
188 |
189 | // for t = 0, N_TS-1 do begin
190 | // H[p,t] = Amplitude[p] * cos(omega[p]*(t+1) + Phase[p])
191 |
192 | // Function to add a H band.
193 | var addH = function(image) {
194 | var H_1 = amplitude_1.multiply((omega_1.multiply(image.select('t')).add(phase_1)).cos()).rename('H_1');
195 | var H_2 = amplitude_2.multiply((omega_2.multiply(image.select('t')).add(phase_2)).cos()).rename('H_2');
196 | var H_3 = amplitude_3.multiply((omega_3.multiply(image.select('t')).add(phase_3)).cos()).rename('H_3');
197 | // FTA[t] = H0 + H[0,t] + H[1,t] + H[2,t]
198 | var TFA = H0.add(H_1).add(H_2).add(H_3).rename('TFA');
199 |
200 | var Anomalies = TFA.subtract(image.select(Temperature_Band)).rename('Anomalies');
201 | return image.addBands(TFA).addBands(Anomalies);
202 | };
203 |
204 | var LST_TFA = LST.map(addH);
205 |
206 | // Define the visualization parameters.
207 | var vizParams = {
208 | bands: ['mean', 'phase', 'amplitude'],
209 | min: [285.0,2.0,5.0],
210 | max: [295.0,3.0,10.0],
211 | gamma: [1.0, 1.0, 1.0]
212 | };
213 |
214 | //display the image.
215 | var img = ee.Image(H0.addBands(phase_1).addBands(amplitude_1).rename('mean', 'phase', 'amplitude'));
216 | // Map.addLayer(img, vizParams, 'RGB');
217 |
218 | // var modelTFA = LST_TFA.select(['TFA', Temperature_Band, 'Anomalies']);
219 | // var modisTFA = LST_TFA.select(['TFA', Temperature_Band]);
220 |
221 | // print(LST_TFA)
222 | //Iterating over the image collection using this function....
223 | // var geometry = ee.FeatureCollection('ft:19Un8ogYFYTnR9p_VsMQ1tlzbR-bVwZoj7ipKy-bC');
224 | var TFA_Images = LST_TFA.select('TFA')
225 | .sort('t')
226 | .iterate(function(img, all) {
227 | return ee.Image(all).addBands(img);
228 | }, ee.Image().select());
229 |
230 | // print('TFA_Images = ', TFA_Images );
231 | // Map.addLayer(ee.Image(TFA_Images))
232 |
233 | // Export one single file with all the bands
234 | Export.image.toAsset({
235 | image: ee.Image(TFA_Images),
236 | assetId: Assets_path + TFA_File_Name,
237 | region: geometry_json,
238 | crs: ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().crs().getInfo(),
239 | crsTransform: [926.625433056,0,-20015109.354,0,-926.625433055,10007554.677],
240 | description: 'exportToAsset-MODIS-TFA-' + TFA_File_Name,
241 | pyramidingPolicy: {'.default': 'sample'}
242 | });
243 |
--------------------------------------------------------------------------------
/MODIS_TFA_Day_or_Night_Export_2_Assets:
--------------------------------------------------------------------------------
1 | // This code uses Temporal Fourier Analysis to build 365 images, for each day of year,
2 | // of the climatological tempratures based on the day (or night) temperatures.
3 |
4 | // Choose here either day or night band
5 | var Temperature_Band = 'LST_Day_1km';
6 | // var Temperature_Band = 'LST_Night_1km';
7 |
8 | // Insert here the coordinates of the area of interest.
9 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
10 | var geometry_json = geometry.toGeoJSON();
11 |
12 | // Change the path to your own assets folder
13 | var Assets_path = 'users/shilosh/MODIS_LST_TFA'
14 |
15 | var collection = 'MODIS/006/MYD11A1';
16 | // The number of cycles per year to model.
17 | var harmonics = 3;
18 |
19 | // Make a list of harmonic frequencies to model.
20 | // These also serve as band name suffixes.
21 | var harmonicFrequencies = ee.List.sequence(1, harmonics);
22 | // Function to get a sequence of band names for harmonic terms.
23 | var getNames = function(base, list) {
24 | return ee.List(list).map(function(i) {
25 | return ee.String(base).cat(ee.Number(i).int());
26 | });
27 | };
28 |
29 | // Construct lists of names for the harmonic terms.
30 | var cosNames = getNames('cos_', harmonicFrequencies);
31 | var sinNames = getNames('sin_', harmonicFrequencies);
32 |
33 | var k2celsius = function(image) {
34 | return image.multiply(ee.Image(0.02))
35 | .subtract(ee.Image(273.15)) //convert Kelvin to Celsius
36 | .set('system:time_start', image.get('system:time_start'));
37 | };
38 |
39 |
40 | // Function to compute the specified number of harmonics
41 | // and add them as bands.
42 | // for p = 0, Nharmonics-1 do begin
43 | // a[p] = a[p] + 2*TS_t*cos(2*!pi*(p+1)*(t+1)/N)
44 | // b[p] = b[p] + 2*TS_t*sin(2*!pi*(p+1)*(t+1)/N)
45 | var addHarmonics = function(freqs) {
46 | return function(image) {
47 | // Make an image of frequencies.
48 | var frequencies = ee.Image.constant(freqs);
49 | // This band should represent lst.
50 | var lst = ee.Image(image).select(Temperature_Band);
51 | // This band should represent days from start.
52 | var time = ee.Image(image).select('t');
53 | // Get the cosine terms.
54 | var cosines = lst.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).cos())
55 | .rename(cosNames);
56 | // Get the sin terms.
57 | var sines = lst.multiply(2.0).multiply((frequencies.multiply(2.0 * Math.PI).multiply(time).divide(365.0)).sin())
58 | .rename(sinNames);
59 | return image.addBands(cosines).addBands(sines);
60 | };
61 | };
62 |
63 | var LST = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
64 | return ee.ImageCollection(collection)
65 | .select(Temperature_Band)
66 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
67 | // .filter(ee.Filter.eq('start_hour', 12))
68 | .map(k2celsius)
69 | .mean()
70 | .set({doy: doy})
71 | .addBands(ee.Image(ee.Number(doy)).rename('t'))
72 | // .map(addHarmonics(harmonicFrequencies));
73 | }))
74 | print('LST = ', LST)
75 | LST = LST.map(addHarmonics(harmonicFrequencies));
76 |
77 | // a = a / N_TS
78 | // b = b / N_TS
79 | var num_days = 365;//ee.Date(lastDay).difference(ee.Date(firstDay), 'day');
80 | var a_coef_1 = LST.select('cos_1').sum().divide(num_days);
81 | var a_coef_2 = LST.select('cos_2').sum().divide(num_days);
82 | var a_coef_3 = LST.select('cos_3').sum().divide(num_days);
83 | var b_coef_1 = LST.select('sin_1').sum().divide(num_days);
84 | var b_coef_2 = LST.select('sin_2').sum().divide(num_days);
85 | var b_coef_3 = LST.select('sin_3').sum().divide(num_days);
86 |
87 | // ; ========================================
88 | // ; prepare the first 3 harmonics of the TFA
89 | // ; ========================================
90 | // H0 = total(TS) / N_TS ;mean
91 | // FTA = MAKE_ARRAY(N_TS, /FLOAT, VALUE=0.)
92 | // H = MAKE_ARRAY(Nharmonics, N_TS, /FLOAT, VALUE=0.)
93 | // omega = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
94 | // Phase = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
95 | // Amplitude = MAKE_ARRAY(Nharmonics, /FLOAT, VALUE=0.)
96 | // for p = 0, Nharmonics-1 do begin
97 | // omega[p] = 2. * !pi * (p+1) / N
98 | // Phase[p] = atan( -b[p], a[p] )
99 | // Amplitude[p] = sqrt( a[p]^2 + b[p]^2 )
100 |
101 | var H0 = LST.select(Temperature_Band).mean();
102 | // Get the omega terms.
103 | var omega_1 = ee.Image(1.0).multiply(2.0 * Math.PI).divide(365.0);
104 | var omega_2 = ee.Image(2.0).multiply(2.0 * Math.PI).divide(365.0);
105 | var omega_3 = ee.Image(3.0).multiply(2.0 * Math.PI).divide(365.0);
106 |
107 | var phase_1 = a_coef_1.atan2(b_coef_1.multiply(ee.Image(-1.0)));
108 | var phase_2 = a_coef_2.atan2(b_coef_2.multiply(ee.Image(-1.0)));
109 | var phase_3 = a_coef_3.atan2(b_coef_3.multiply(ee.Image(-1.0)));
110 |
111 | var amplitude_1 = (a_coef_1.pow(2).add(b_coef_1.pow(2))).sqrt();
112 | var amplitude_2 = (a_coef_2.pow(2).add(b_coef_2.pow(2))).sqrt();
113 | var amplitude_3 = (a_coef_3.pow(2).add(b_coef_3.pow(2))).sqrt();
114 |
115 | // for t = 0, N_TS-1 do begin
116 | // H[p,t] = Amplitude[p] * cos(omega[p]*(t+1) + Phase[p])
117 |
118 | // Function to add a H band.
119 | var addH = function(image) {
120 | var H_1 = amplitude_1.multiply((omega_1.multiply(image.select('t')).add(phase_1)).cos()).rename('H_1');
121 | var H_2 = amplitude_2.multiply((omega_2.multiply(image.select('t')).add(phase_2)).cos()).rename('H_2');
122 | var H_3 = amplitude_3.multiply((omega_3.multiply(image.select('t')).add(phase_3)).cos()).rename('H_3');
123 | // FTA[t] = H0 + H[0,t] + H[1,t] + H[2,t]
124 | var TFA = H0.add(H_1).add(H_2).add(H_3).rename('TFA');
125 |
126 | var Anomalies = TFA.subtract(image.select(Temperature_Band)).rename('Anomalies');
127 | return image.addBands(TFA).addBands(Anomalies);
128 | };
129 |
130 | var LST_TFA = LST.map(addH);
131 |
132 | // Define the visualization parameters.
133 | var vizParams = {
134 | bands: ['mean', 'phase', 'amplitude'],
135 | min: [285.0,2.0,5.0],
136 | max: [295.0,3.0,10.0],
137 | gamma: [1.0, 1.0, 1.0]
138 | };
139 |
140 | //display the image.
141 | var img = ee.Image(H0.addBands(phase_1).addBands(amplitude_1).rename('mean', 'phase', 'amplitude'));
142 | // Map.addLayer(img, vizParams, 'RGB');
143 |
144 | //Iterating over the image collection using this function....
145 | var TFA_Images = LST_TFA.select('TFA')
146 | .sort('t')
147 | .iterate(function(img, all) {
148 | return ee.Image(all).addBands(img);
149 | }, ee.Image().select());
150 |
151 | print('TFA_Images = ', TFA_Images );
152 |
153 | // Export one single file with all the bands
154 | Export.image.toAsset({
155 | image: ee.Image(TFA_Images),
156 | assetId: Assets_path + Temperature_Band,
157 | region: geometry_json,
158 | crs: ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().crs().getInfo(),
159 | crsTransform: [926.625433056,0,-20015109.354,0,-926.625433055,10007554.677],
160 | description: 'exportToAsset-MODIS-TFA' + Temperature_Band,
161 | pyramidingPolicy: {'.default': 'sample'}
162 | });
163 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ContinuousLST
2 | A continuous dataset of Land Surface Temperature (LST) is vital for climatological and environmental studies. LST can be regarded as a combination of seasonal mean temperature (climatology) and daily anomaly, which is attributed mainly to the synoptic-scale atmospheric circulation (weather). To reproduce LST in cloudy pixels using the code files in this reposetory, time series (2002-today) of cloud-free 1km MODIS Aqua LST images are generated and the pixel-based seasonality (climatology) is calculated using temporal Fourier analysis. To add the anomaly, we are using the NCEP Climate Forecast System Version 2 (CFSv2) model, which provides air surface temperature under both cloudy and clear sky conditions. The combination of the two sources of data enables the estimation of LST in cloudy pixels.
3 | The LSTcont dataset can be used for various applications and studies. Furthermore, datasets for other regions can easily be produced by the GEE platform with the provided code. Due to the significant influence of the temperature seasonality on the algorithm, cautions should be taken when running the code on regions with very low seasonality such as the equatorial regions.
4 | For producing the dataset, one should first run MODIS_TFA_Daily_Mean_Export_2_Assets and MODIS_TFA_Daily_Mean_Export_2_Assets codes to produce the TFAs. Only after both files, MODIS TFA and CFSv2 TFA are ready, Continuous_LST_Daily_Export code file can be used to produce LSTcont. Different code files have been prepared for day, night and daily datasets.
5 |
6 |
7 |
8 | ### How to visualize data using Qgis open source program
9 |
10 |
11 | ## Web application
12 | The LSTcont web application (https://shilosh.users.earthengine.app/view/continuous-lst) is an Earth Engine app. The interface includes a map and a date picker. The user can select a date (July 2002 – present) and visualize LSTcont for that day anywhere on the globe. The web app calculate LSTcont on the fly based on ready-made global climatological files. The LSTcont can be downloaded as a GeoTiff with 5 bands in that order: Mean daily LSTcont , Night original LST, Night LSTcont , Day original LST, Day LSTcont.
13 |
--------------------------------------------------------------------------------
/RMSE Daily LST Vs TFA + cfsv2 anomalies iteration:
--------------------------------------------------------------------------------
1 | // Change the path to your own TFA images
2 | var CFSV2_TFA = ee.Image("users/shilosh/CFSv2_Daily_LST_TFA"),
3 | MODIS_TFA = ee.Image("users/shilosh/MODIS_Daily_LST_TFA");
4 | // Map.setCenter(35,32,8)
5 | var AreaName = 'Israel'
6 | // var AreaName = 'Poland'
7 | // var AreaName = 'France'
8 | // var AreaName = 'Germany'
9 | // var AreaName = 'Maryland'
10 | // var AreaName = 'Iowa'
11 | // var AreaName = 'Brazil'
12 | // var AreaName = 'SouthBrazil'
13 | // var AreaName = 'Argentina'
14 | // var AreaName = 'Libya'
15 | // var AreaName = 'China'
16 | // var AreaName = 'SouthAustralia'
17 | // var AreaName = 'MidAustralia'
18 |
19 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0])//Israel;
20 | // var geometry = ee.Geometry.Rectangle([20,50,25,54]); //Poland
21 | // var geometry = ee.Geometry.Rectangle([43,0,48,4]); //France
22 | // var geometry = ee.Geometry.Rectangle([49,7,54,11]); //Germany
23 | // var geometry = ee.Geometry.Rectangle([-76,36.0,-79,40]); //Maryland (Urban Heat Island)
24 | // var geometry = ee.Geometry.Rectangle([-90,41,-95,44.0]);//Iowa (Corn Belt)
25 | // var geometry = ee.Geometry.Rectangle([-60,-6,-55,-2]); //Brazil
26 | // var geometry = ee.Geometry.Rectangle([-50,-20,-45,-16]); //SouthBrazil
27 | // var geometry = ee.Geometry.Rectangle([-69,-34,-64,-30]); //Argentina
28 | // var geometry = ee.Geometry.Rectangle([12,24,17,28]); //Libya (Sahara)
29 | // var geometry = ee.Geometry.Rectangle([105,30,110,34]); //China
30 | // var geometry = ee.Geometry.Rectangle([145,-37,150,-33]); //SouthAustralia
31 | // var geometry = ee.Geometry.Rectangle([135,-25,140,-20]); //MidAustralia
32 |
33 | var geometry_json = geometry.toGeoJSON();
34 | Map.centerObject(geometry, 8)
35 |
36 | // create list of years over which to iterate
37 | var years = ee.List.sequence(2002, 2019);
38 | // Iterate through years
39 | var correlation_statistics_by_year = years.map(function(year) {
40 | // Comment and uncomment the calculation_state according to the validation test needed
41 | var calculation_state = 'TFA plus anomalies'
42 | // var calculation_state = 'TFA only'
43 | var firstDay = ee.Algorithms.String(ee.Number(year).toInt()).cat('-01-01');
44 | var lastDay = ee.Algorithms.String(ee.Number(year).add(1).toInt()).cat('-01-01');
45 |
46 |
47 | // Reverse the images into imageCollections
48 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
49 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
50 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
51 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
52 | // print('MODIS_TFA_ic = ', MODIS_TFA_ic)
53 |
54 | //convert Kelvin to Celsius
55 | var modis_k2celsius = function(image) {
56 | return image.multiply(ee.Image(0.02))
57 | .subtract(ee.Image(273.15))
58 | .set('system:time_start', image.get('system:time_start'));
59 | };
60 |
61 | // Reproject to CFSv2 projection and reduce resolution
62 | // Get information about the CFSV2 projection.
63 | var Reproject = function(img){
64 | var CFSV2Projection = ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection();
65 | var scale = ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection().nominalScale().getInfo();
66 | // Get the MODIS data at CFSV2 scale and projection.
67 | var mod = img
68 | // Request the data at the scale and projection of the CFSV2 image.
69 | .reproject({
70 | crs: CFSV2Projection,
71 | scale: scale
72 | })
73 | // Force the next reprojection to aggregate instead of resampling.
74 | .reduceResolution({
75 | reducer: ee.Reducer.mean(),
76 | maxPixels: 10000
77 | })
78 | return mod.set('system:DOY', img.get('system:DOY'));
79 | };
80 | // var Reproject = function(img){
81 | // var MODISProjection = ee.Image('MODIS/006/MYD11A1/2018_01_01').projection();
82 | // var scale = ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().nominalScale().getInfo();
83 | // // Get the MODIS data at CFSV2 scale and projection.
84 | // var mod = img
85 | // // Request the data at the scale and projection of the CFSV2 image.
86 | // .reproject({
87 | // crs: MODISProjection,
88 | // scale: scale
89 | // });
90 | // return mod
91 | // .set('system:DOY', img.get('system:DOY'));
92 | // };
93 |
94 | // Add a property with doy to the colection.
95 | function createDoyBand(img) {
96 | var d = ee.Date(img.get('system:time_start'))
97 | .getRelative('day', 'year')
98 | .add(1);
99 | img=img.set('system:DOY', d);
100 | return img;
101 | }
102 |
103 | // Construct image date from 'system:index' and add it to a new 'date' property
104 | var addTimeStampToModis = function(image) {
105 | var start = ee.String(image.get('system:index'));
106 | var y = start.slice(0,4);
107 | var m = start.slice(5,7);
108 | var d = start.slice(8,10);
109 | var date = y.cat('-').cat(m).cat('-').cat(d);
110 | return image.set({'system:time_start': date});
111 | };
112 |
113 | // Construct image date from 'system:index' and add it to a new 'date' property
114 | var addTimeStampToCFSv2 = function(image) {
115 | var start = ee.String(image.get('system:index'));
116 | var y = start.slice(0,4);
117 | var m = start.slice(4,6);
118 | var d = start.slice(6,8);
119 | var date = y.cat('-').cat(m).cat('-').cat(d);
120 | return image.set({'system:time_start': date});
121 | };
122 |
123 | // Mask modis
124 | var mask_good_quality = function(image) {
125 | var QCNight = image.select('QC_Night');
126 | var QC = (QCNight.neq(2)).and(QCNight.neq(3));
127 | return image.updateMask(QC)
128 | .select('LST_Night_1km')
129 | .set('system:time_start', image.get('system:time_start'))
130 | };
131 |
132 | // Load imageCollection of MODIS LST
133 | var MODIS_LST = ee.ImageCollection('MODIS/006/MYD11A1')
134 | .filterDate(firstDay, lastDay)
135 | .select('LST_Day_1km', 'LST_Night_1km')
136 | .map(modis_k2celsius)
137 | .map(addTimeStampToModis)
138 | .map(createDoyBand)
139 | //.map(Reproject)
140 | //.mean()
141 |
142 |
143 | // Map.addLayer(MODIS_LST.first().select('LST_Day_1km'),{},'day')
144 | // Map.addLayer(MODIS_LST.first().select('LST_Night_1km'),{}, 'night')
145 |
146 | // print('MODIS_LST = ', MODIS_LST)
147 |
148 | MODIS_LST = MODIS_LST.map(function (image){
149 | return (image.select(0).add(image.select(1))).divide(ee.Image(2))
150 | .clip(geometry)
151 | // .reduce(ee.Reducer.mean())
152 | .set({'system:DOY': image.get('system:DOY')})
153 | .rename('MODIS_LST')
154 | });
155 | MODIS_LST = MODIS_LST.map(Reproject)
156 | // Map.addLayer(MODIS_LST.first(),{}, 'mean')
157 |
158 | // print('MODIS_LST = ', MODIS_LST)
159 |
160 | // var MODIS_LST = ee.ImageCollection('MODIS/006/MYD11A1')
161 | // .filterDate(firstDay, lastDay)
162 | // .select('LST_Night_1km', 'QC_Night')
163 | // .map(mask_good_quality)
164 | // .map(modis_k2celsius)
165 | // // .map(Reproject)
166 | // .map(addTimeStampToModis)
167 | // .map(createDoyBand);
168 | // var filter_low_values = require('users/shilosh/default:filter_modis_low_values_func');
169 | // MODIS_LST = filter_low_values.filter_modis_low_values(MODIS_LST, -9);
170 |
171 | //convert Kelvin to Celsius
172 | var k2celsius = function(image) {
173 | return image.subtract(ee.Image(273.15))
174 | .set('system:time_start', image.get('system:time_start'));
175 | };
176 |
177 | // Load imageCollection of CFSv2 Temperature over ground
178 | // var CFSV2 = ee.ImageCollection('NOAA/CFSV2/FOR6H')
179 | // .filterDate(firstDay, lastDay)
180 | // .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
181 | // .filter(ee.Filter.eq('start_hour', 00))
182 | // .map(k2celsius)
183 | // // .map(Reproject)
184 | // .map(addTimeStampToCFSv2)
185 | // .map(createDoyBand);
186 | var CFSV2 = ee.ImageCollection(ee.List.sequence(1, 365).map(function (doy){
187 | return ee.ImageCollection('NOAA/CFSV2/FOR6H')
188 | .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
189 | .filterDate(firstDay, lastDay)
190 | .filter(ee.Filter.calendarRange(doy, doy, 'day_of_year'))
191 | // .filter(ee.Filter.eq('start_hour', 12))
192 | .map(Reproject)
193 | .map(k2celsius)
194 | .mean()
195 | .set({'system:DOY': doy})
196 | // .addBands(ee.Image(ee.Number(doy)).rename('t'))
197 | // .map(addHarmonics(harmonicFrequencies));
198 | }))
199 | // print('CFSV2 = ', CFSV2)
200 | CFSV2_TFA_ic = CFSV2_TFA_ic.map(Reproject)
201 | // print('CFSV2_TFA_ic = ', CFSV2_TFA_ic)
202 |
203 | // Use an equals filter to specify how the collections match.
204 | var Filter = ee.Filter.equals({
205 | leftField: 'system:DOY',
206 | rightField: 'system:DOY'
207 | });
208 | // Define the join.
209 | var innerJoin = ee.Join.inner('primary', 'secondary');
210 |
211 | // Join CFSV2 with CFSV2_TFA_ic by DOY
212 | // Apply the join.
213 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
214 |
215 | // Calculate CFSv2 anomalies
216 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
217 | var tfa = ee.Image(f.get('secondary'));
218 | var actual = ee.Image(f.get('primary'));
219 | return actual.subtract(tfa)
220 | .clip(geometry)
221 | .set({'system:DOY': actual.get('system:DOY')});
222 | });
223 |
224 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
225 | // Apply the join.
226 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
227 |
228 | // Calculate MODIS TFA Plus CFSv2 anomalies
229 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
230 | var tfa = ee.Image(f.get('secondary'));
231 | var anomalies = ee.Image(f.get('primary'));
232 | switch(calculation_state){
233 | case 'TFA plus anomalies':
234 | // Anomalies at night do not conribute to the TFA only prediction,
235 | // therefor because we are trying to predict daily mean LST, we only add half of the daily anomalies
236 | return tfa.add(anomalies.divide(ee.Image(2)))
237 | .set({'system:DOY': anomalies.get('system:DOY')})
238 | .rename('mod');
239 | case 'TFA only':
240 | return tfa
241 | .set({'system:DOY': anomalies.get('system:DOY')});
242 | }
243 | });
244 | // print('CFSV2_Anomalies = ', CFSV2_Anomalies)
245 | // print('MODIS_Continuous = ', MODIS_Continuous)
246 | // print('MODIS_LST = ', MODIS_LST)
247 | // Map.addLayer(MODIS_LST.first())
248 |
249 | // Join MODIS_Anomalies with CFSV2_Anomalies by DOY
250 | // Apply the join.
251 | var Continuous_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
252 | // print('Continuous_JoinInner = ', Continuous_JoinInner)
253 |
254 | // Mask CFSv2
255 | var MaskedValues = Continuous_JoinInner.map(function(f) {
256 | var con = ee.Image(f.get('secondary'));
257 | var mod = ee.Image(f.get('primary'));
258 | con = ee.Image(con.float()).updateMask(ee.Image(mod).add(10));
259 | mod = ee.Image(mod.float()).updateMask(ee.Image(con).add(10));
260 | var mod_vs_cfs = ee.Image(mod).addBands(con);
261 | mod_vs_cfs = ee.Image(mod_vs_cfs).select(['MODIS_LST','mod'],['mod','con'])
262 | // mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Temperature_height_above_ground'],['mod','cfs'])
263 | // mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km'],['mod'])
264 | // var image = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Temperature_height_above_ground'],['mod','cfs']).reduceRegion(ee.Reducer.toList());
265 | // var x = image.get('mod');
266 | // var y = image.get('cfs');
267 | return mod_vs_cfs
268 | });
269 | // print('MaskedValues = ', MaskedValues)
270 |
271 | var differences_squared = function(image) {
272 | var differences = ee.Image(image).select('con').subtract(ee.Image(image).select('mod') )
273 | differences = ee.Image(differences).multiply(differences);
274 | return differences;
275 | };
276 |
277 | var mean_of_differences_squared = MaskedValues.map(differences_squared)
278 | mean_of_differences_squared = ee.ImageCollection(mean_of_differences_squared).mean()
279 | // print('mean_of_differences_squared = ', mean_of_differences_squared)
280 | var rmse = mean_of_differences_squared.sqrt()
281 |
282 | var mean_absolut_error = function(image) {
283 | var differences = ee.Image(image).select('con').subtract(ee.Image(image).select('mod') )
284 | differences = ee.Image(differences).abs();
285 | return differences;
286 | };
287 | var MAE = MaskedValues.map(mean_absolut_error)
288 | MAE = ee.ImageCollection(MAE).mean()
289 |
290 | // var Pearson = ee.ImageCollection(MaskedValues).reduce(ee.Reducer.spearmansCorrelation());
291 | var Pearson = ee.ImageCollection(MaskedValues).reduce(ee.Reducer.pearsonsCorrelation());
292 |
293 | var scale = ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().nominalScale().getInfo();
294 | var scale = ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection().nominalScale().getInfo();
295 | var CFSV2Projection = CFSV2_TFA_Israel.projection();
296 | // var scale = CFSV2_TFA.projection().nominalScale().getInfo();
297 | var rmse_val = rmse.reduceRegion(ee.Reducer.mean(), geometry, scale)
298 | var MAE_val = MAE.reduceRegion(ee.Reducer.mean(), geometry_json, scale)
299 | var Pearson_val = Pearson.select('correlation').reduceRegion({
300 | reducer:ee.Reducer.mean(),
301 | geometry:geometry_json,
302 | scale:scale,
303 | crs:CFSV2Projection,
304 | })
305 |
306 | var f = ee.Feature(null,{
307 | 'year' : year,
308 | 'Pearson' : Pearson_val,
309 | 'RMSE' : rmse_val,
310 | 'MAE' : MAE_val,
311 | })
312 | return f;
313 | })
314 | // print('f = ', f)
315 | // print('images_by_year = ', images_by_year)
316 | var fromList = ee.FeatureCollection(correlation_statistics_by_year);
317 | print(fromList);
318 | // Export the FeatureCollection to a CSV file.
319 | Export.table.toDrive({
320 | collection: fromList,
321 | // description:'Daily_TFA_only',
322 | description:'Daily_TFA_plus_anomalies_' + AreaName,
323 | folder: 'gee',
324 | fileFormat: 'CSV'
325 | });
326 |
327 |
--------------------------------------------------------------------------------
/RMSE Day LST Vs TFA + cfsv2 anomalies iteration:
--------------------------------------------------------------------------------
1 | // Change the path to your own TFA images
2 | var CFSV2_TFA = ee.Image("users/shilosh/CFSv2_Day_LST_TFA"),
3 | MODIS_TFA = ee.Image("users/shilosh/MODIS_Day_LST_TFA");
4 | // create list of years over which to iterate
5 | var years = ee.List.sequence(2002, 2019);
6 | // Iterate through years
7 | var correlation_statistics_by_year = years.map(function(year) {
8 | // var year = 2017
9 | var calculation_state = 'TFA plus anomalies'
10 | // var calculation_state = 'TFA only'
11 | var firstDay = ee.Algorithms.String(ee.Number(year).toInt()).cat('-01-01');
12 | var lastDay = ee.Algorithms.String(ee.Number(year).add(1).toInt()).cat('-01-01');
13 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
14 | var geometry_json = geometry.toGeoJSON();
15 |
16 | // Reverse the images into imageCollections
17 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
18 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
19 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
20 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
21 |
22 | //convert Kelvin to Celsius
23 | var modis_k2celsius = function(image) {
24 | return image.multiply(ee.Image(0.02))
25 | .subtract(ee.Image(273.15))
26 | .set('system:time_start', image.get('system:time_start'));
27 | };
28 |
29 | // Reproject to CFSv2 projection and reduce resolution
30 | // Get information about the CFSV2 projection.
31 | var Reproject = function(img){
32 | var CFSV2Projection = CFSV2_TFA.projection();
33 | var scale = CFSV2_TFA.projection().nominalScale().getInfo();
34 | // Get the MODIS data at CFSV2 scale and projection.
35 | var mod = img
36 | // Force the next reprojection to aggregate instead of resampling.
37 | .reduceResolution({
38 | reducer: ee.Reducer.mean(),
39 | maxPixels: 10000
40 | })
41 | // Request the data at the scale and projection of the CFSV2 image.
42 | .reproject({
43 | crs: CFSV2Projection,
44 | scale: scale
45 | });
46 | return mod;
47 | };
48 |
49 | // Add a property with doy to the colection.
50 | function createDoyBand(img) {
51 | var d = ee.Date(img.get('system:time_start'))
52 | .getRelative('day', 'year')
53 | .add(1);
54 | img=img.set('system:DOY', d);
55 | return img;
56 | }
57 |
58 | // Construct image date from 'system:index' and add it to a new 'date' property
59 | var addTimeStampToModis = function(image) {
60 | var start = ee.String(image.get('system:index'));
61 | var y = start.slice(0,4);
62 | var m = start.slice(5,7);
63 | var d = start.slice(8,10);
64 | var date = y.cat('-').cat(m).cat('-').cat(d);
65 | return image.set({'system:time_start': date});
66 | };
67 |
68 | // Construct image date from 'system:index' and add it to a new 'date' property
69 | var addTimeStampToCFSv2 = function(image) {
70 | var start = ee.String(image.get('system:index'));
71 | var y = start.slice(0,4);
72 | var m = start.slice(4,6);
73 | var d = start.slice(6,8);
74 | var date = y.cat('-').cat(m).cat('-').cat(d);
75 | return image.set({'system:time_start': date});
76 | };
77 |
78 | // Mask modis
79 | var mask_good_quality = function(image) {
80 | var QCDay = image.select('QC_Day');
81 | var QC = (QCDay.neq(2)).and(QCDay.neq(3));
82 | return image.updateMask(QC)
83 | .select('LST_Day_1km')
84 | .set('system:time_start', image.get('system:time_start'))
85 | };
86 |
87 | // Load imageCollection of MODIS LST
88 | var MODIS_LST = ee.ImageCollection('MODIS/006/MYD11A1')
89 | .filterDate(firstDay, lastDay)
90 | .select('LST_Day_1km', 'QC_Day')
91 | .map(mask_good_quality)
92 | .map(modis_k2celsius)
93 | // .map(Reproject)
94 | .map(addTimeStampToModis)
95 | .map(createDoyBand);
96 | var filter_low_values = require('users/shilosh/default:filter_modis_low_values_func');
97 | MODIS_LST = filter_low_values.filter_modis_low_values(MODIS_LST, -9);
98 |
99 | //convert Kelvin to Celsius
100 | var k2celsius = function(image) {
101 | return image.subtract(ee.Image(273.15))
102 | .set('system:time_start', image.get('system:time_start'));
103 | };
104 |
105 | // Load imageCollection of CFSv2 Temperature over ground
106 | var CFSV2 = ee.ImageCollection('NOAA/CFSV2/FOR6H')
107 | .filterDate(firstDay, lastDay)
108 | .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
109 | .filter(ee.Filter.stringEndsWith('system:index', '12'))
110 | .map(k2celsius)
111 | // .map(Reproject)
112 | .map(addTimeStampToCFSv2)
113 | .map(createDoyBand);
114 |
115 | // Use an equals filter to specify how the collections match.
116 | var Filter = ee.Filter.equals({
117 | leftField: 'system:DOY',
118 | rightField: 'system:DOY'
119 | });
120 | // Define the join.
121 | var innerJoin = ee.Join.inner('primary', 'secondary');
122 |
123 | // Join CFSV2 with CFSV2_TFA_ic by DOY
124 | // Apply the join.
125 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
126 |
127 | // Calculate CFSv2 anomalies
128 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
129 | var tfa = ee.Image(f.get('secondary'));
130 | var actual = ee.Image(f.get('primary'));
131 | return actual.subtract(tfa);
132 | }).map(addTimeStampToCFSv2)
133 | .map(createDoyBand);
134 |
135 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
136 | // Apply the join.
137 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
138 |
139 | // Calculate MODIS TFA Plus CFSv2 anomalies
140 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
141 | var tfa = ee.Image(f.get('secondary'));
142 | var anomalies = ee.Image(f.get('primary'));
143 | switch(calculation_state){
144 | case 'TFA plus anomalies':
145 | return anomalies.add(tfa);
146 | case 'TFA only':
147 | return anomalies.add(tfa).subtract(anomalies);
148 | }
149 | }).map(addTimeStampToCFSv2)
150 | .map(createDoyBand);
151 |
152 | // Join MODIS_Anomalies with CFSV2_Anomalies by DOY
153 | // Apply the join.
154 | var Continuous_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
155 |
156 | // Mask CFSv2
157 | var MaskedValues = Continuous_JoinInner.map(function(f) {
158 | var con = ee.Image(f.get('secondary'));
159 | var mod = ee.Image(f.get('primary'));
160 | con = ee.Image(con.float()).updateMask(ee.Image(mod).add(10));
161 | mod = ee.Image(mod.float()).updateMask(ee.Image(con).add(10));
162 | var mod_vs_cfs = ee.Image(mod).addBands(con);
163 | mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Maximum_temperature_height_above_ground_6_Hour_Interval'],['mod','con'])
164 | // mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Temperature_height_above_ground'],['mod','cfs'])
165 | // mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km'],['mod'])
166 | // var image = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Temperature_height_above_ground'],['mod','cfs']).reduceRegion(ee.Reducer.toList());
167 | // var x = image.get('mod');
168 | // var y = image.get('cfs');
169 | return mod_vs_cfs
170 | });
171 |
172 | var differences_squared = function(image) {
173 | var differences = ee.Image(image).select('con').subtract(ee.Image(image).select('mod') )
174 | differences = ee.Image(differences).multiply(differences);
175 | return differences;
176 | };
177 | var mean_of_differences_squared = MaskedValues.map(differences_squared)
178 | mean_of_differences_squared = ee.ImageCollection(mean_of_differences_squared).mean()
179 | // print('mean_of_differences_squared = ', mean_of_differences_squared)
180 | var rmse = mean_of_differences_squared.sqrt()
181 |
182 | var mean_absolut_error = function(image) {
183 | var differences = ee.Image(image).select('con').subtract(ee.Image(image).select('mod') )
184 | differences = ee.Image(differences).abs();
185 | return differences;
186 | };
187 | var MAE = MaskedValues.map(mean_absolut_error)
188 | MAE = ee.ImageCollection(MAE).mean()
189 |
190 | var Pearson = ee.ImageCollection(MaskedValues).reduce(ee.Reducer.pearsonsCorrelation());
191 |
192 | var scale = ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().nominalScale().getInfo();
193 | var scale = ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection().nominalScale().getInfo();
194 | var CFSV2Projection = CFSV2_TFA.projection();
195 | // var scale = CFSV2_TFA.projection().nominalScale().getInfo();
196 | var rmse_val = rmse.reduceRegion(ee.Reducer.mean(), geometry, scale)
197 | var MAE_val = MAE.reduceRegion(ee.Reducer.mean(), geometry_json, scale)
198 | var Pearson_val = Pearson.select('correlation').reduceRegion({
199 | reducer:ee.Reducer.mean(),
200 | geometry:geometry_json,
201 | scale:scale,
202 | crs:CFSV2Projection,
203 | })
204 |
205 | // print('RMSE = ', rmse_val)
206 | var f = ee.Feature(null,{
207 | 'year' : year,
208 | 'Pearson' : Pearson_val,
209 | 'RMSE' : rmse_val,
210 | 'MAE' : MAE_val,
211 | })
212 | return f;
213 | })
214 |
215 | var fromList = ee.FeatureCollection(correlation_statistics_by_year);
216 | print(fromList);
217 | // Export the FeatureCollection to a CSV file.
218 | Export.table.toDrive({
219 | collection: fromList,
220 | // description:'Day_TFA_only',
221 | description:'Day_TFA_plus_anomalies',
222 | folder: 'gee',
223 | fileFormat: 'CSV'
224 | });
225 |
--------------------------------------------------------------------------------
/RMSE Night LST Vs TFA + cfsv2 anomalies iteration:
--------------------------------------------------------------------------------
1 | // Change the path to your own TFA images
2 | var MODIS_TFA = ee.Image("users/shilosh/MODIS_LST_TFA_Night"),
3 | CFSV2_TFA = ee.Image("users/shilosh/CFSv2_LST_TFA_Night");
4 |
5 | // create list of years over which to iterate
6 | var years = ee.List.sequence(2002, 2019);
7 | // Iterate through years
8 | var correlation_statistics_by_year = years.map(function(year) {
9 | // var year = 2017
10 | var calculation_state = 'TFA plus anomalies'
11 | // var calculation_state = 'TFA only'
12 | var firstDay = ee.Algorithms.String(ee.Number(year).toInt()).cat('-01-01');
13 | var lastDay = ee.Algorithms.String(ee.Number(year).add(1).toInt()).cat('-01-01');
14 | var geometry = ee.Geometry.Rectangle([33.2,29.0,36.6,34.0]);
15 | var geometry_json = geometry.toGeoJSON();
16 |
17 | // Reverse the images into imageCollections
18 | var MODIS_TFA_ic = ee.ImageCollection(MODIS_TFA.bandNames().map(function(name) {
19 | return MODIS_TFA.select([ee.Algorithms.String(name)],['mod']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
20 | var CFSV2_TFA_ic = ee.ImageCollection(CFSV2_TFA.bandNames().map(function(name) {
21 | return CFSV2_TFA.select([ee.Algorithms.String(name)],['cfs']).set('system:DOY', ee.Number.parse(ee.Algorithms.String(name).replace('TFA','0').replace('_','')).add(1)) }))
22 |
23 | //convert Kelvin to Celsius
24 | var modis_k2celsius = function(image) {
25 | return image.multiply(ee.Image(0.02))
26 | .subtract(ee.Image(273.15))
27 | .set('system:time_start', image.get('system:time_start'));
28 | };
29 |
30 | // Reproject to CFSv2 projection and reduce resolution
31 | // Get information about the CFSV2 projection.
32 | var Reproject = function(img){
33 | var CFSV2Projection = CFSV2_TFA.projection();
34 | var scale = CFSV2_TFA.projection().nominalScale().getInfo();
35 | // Get the MODIS data at CFSV2 scale and projection.
36 | var mod = img
37 | // Force the next reprojection to aggregate instead of resampling.
38 | .reduceResolution({
39 | reducer: ee.Reducer.mean(),
40 | maxPixels: 10000
41 | })
42 | // Request the data at the scale and projection of the CFSV2 image.
43 | .reproject({
44 | crs: CFSV2Projection,
45 | scale: scale
46 | });
47 | return mod;
48 | };
49 |
50 | // Add a property with doy to the colection.
51 | function createDoyBand(img) {
52 | var d = ee.Date(img.get('system:time_start'))
53 | .getRelative('day', 'year')
54 | .add(1);
55 | img=img.set('system:DOY', d);
56 | return img;
57 | }
58 |
59 | // Construct image date from 'system:index' and add it to a new 'date' property
60 | var addTimeStampToModis = function(image) {
61 | var start = ee.String(image.get('system:index'));
62 | var y = start.slice(0,4);
63 | var m = start.slice(5,7);
64 | var d = start.slice(8,10);
65 | var date = y.cat('-').cat(m).cat('-').cat(d);
66 | return image.set({'system:time_start': date});
67 | };
68 |
69 | // Construct image date from 'system:index' and add it to a new 'date' property
70 | var addTimeStampToCFSv2 = function(image) {
71 | var start = ee.String(image.get('system:index'));
72 | var y = start.slice(0,4);
73 | var m = start.slice(4,6);
74 | var d = start.slice(6,8);
75 | var date = y.cat('-').cat(m).cat('-').cat(d);
76 | return image.set({'system:time_start': date});
77 | };
78 |
79 | // Mask modis
80 | var mask_good_quality = function(image) {
81 | var QCNight = image.select('QC_Night');
82 | var QC = (QCNight.neq(2)).and(QCNight.neq(3));
83 | return image.updateMask(QC)
84 | .select('LST_Night_1km')
85 | .set('system:time_start', image.get('system:time_start'))
86 | };
87 |
88 | // Load imageCollection of MODIS LST
89 | var MODIS_LST = ee.ImageCollection('MODIS/006/MYD11A1')
90 | .filterDate(firstDay, lastDay)
91 | .select('LST_Night_1km', 'QC_Night')
92 | .map(mask_good_quality)
93 | .map(modis_k2celsius)
94 | // .map(Reproject)
95 | .map(addTimeStampToModis)
96 | .map(createDoyBand);
97 | // var filter_low_values = require('users/shilosh/default:filter_modis_low_values_func');
98 | // MODIS_LST = filter_low_values.filter_modis_low_values(MODIS_LST, -9);
99 |
100 | //convert Kelvin to Celsius
101 | var k2celsius = function(image) {
102 | return image.subtract(ee.Image(273.15))
103 | .set('system:time_start', image.get('system:time_start'));
104 | };
105 |
106 | // Load imageCollection of CFSv2 Temperature over ground
107 | var CFSV2 = ee.ImageCollection('NOAA/CFSV2/FOR6H')
108 | .filterDate(firstDay, lastDay)
109 | .select('Maximum_temperature_height_above_ground_6_Hour_Interval')
110 | .filter(ee.Filter.stringEndsWith('system:index', '00'))
111 | .map(k2celsius)
112 | // .map(Reproject)
113 | .map(addTimeStampToCFSv2)
114 | .map(createDoyBand);
115 |
116 | // Use an equals filter to specify how the collections match.
117 | var Filter = ee.Filter.equals({
118 | leftField: 'system:DOY',
119 | rightField: 'system:DOY'
120 | });
121 | // Define the join.
122 | var innerJoin = ee.Join.inner('primary', 'secondary');
123 |
124 | // Join CFSV2 with CFSV2_TFA_ic by DOY
125 | // Apply the join.
126 | var CFSV2_JoinInner = innerJoin.apply(CFSV2, CFSV2_TFA_ic, Filter);
127 |
128 | // Calculate CFSv2 anomalies
129 | var CFSV2_Anomalies = CFSV2_JoinInner.map(function(f) {
130 | var tfa = ee.Image(f.get('secondary'));
131 | var actual = ee.Image(f.get('primary'));
132 | return actual.subtract(tfa);
133 | }).map(addTimeStampToCFSv2)
134 | .map(createDoyBand);
135 |
136 | // Join MODIS_TFA_ic with CFSV2_Anomalies by DOY
137 | // Apply the join.
138 | var MODIS_JoinInner = innerJoin.apply(CFSV2_Anomalies, MODIS_TFA_ic, Filter);
139 |
140 | // Calculate MODIS TFA Plus CFSv2 anomalies
141 | var MODIS_Continuous = MODIS_JoinInner.map(function(f) {
142 | var tfa = ee.Image(f.get('secondary'));
143 | var anomalies = ee.Image(f.get('primary'));
144 | switch(calculation_state){
145 | case 'TFA plus anomalies':
146 | return anomalies.add(tfa);
147 | case 'TFA only':
148 | return anomalies.add(tfa).subtract(anomalies);
149 | }
150 | }).map(addTimeStampToCFSv2)
151 | .map(createDoyBand);
152 |
153 | // Join MODIS_Anomalies with CFSV2_Anomalies by DOY
154 | // Apply the join.
155 | var Continuous_JoinInner = innerJoin.apply(MODIS_LST, MODIS_Continuous, Filter);
156 |
157 | // Mask CFSv2
158 | var MaskedValues = Continuous_JoinInner.map(function(f) {
159 | var con = ee.Image(f.get('secondary'));
160 | var mod = ee.Image(f.get('primary'));
161 | con = ee.Image(con.float()).updateMask(ee.Image(mod).add(10));
162 | mod = ee.Image(mod.float()).updateMask(ee.Image(con).add(10));
163 | var mod_vs_cfs = ee.Image(mod).addBands(con);
164 | mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Night_1km','Maximum_temperature_height_above_ground_6_Hour_Interval'],['mod','con'])
165 | // mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Temperature_height_above_ground'],['mod','cfs'])
166 | // mod_vs_cfs = ee.Image(mod_vs_cfs).select(['LST_Day_1km'],['mod'])
167 | // var image = ee.Image(mod_vs_cfs).select(['LST_Day_1km','Temperature_height_above_ground'],['mod','cfs']).reduceRegion(ee.Reducer.toList());
168 | // var x = image.get('mod');
169 | // var y = image.get('cfs');
170 | return mod_vs_cfs
171 | });
172 |
173 | var differences_squared = function(image) {
174 | var differences = ee.Image(image).select('con').subtract(ee.Image(image).select('mod') )
175 | differences = ee.Image(differences).multiply(differences);
176 | return differences;
177 | };
178 | var mean_of_differences_squared = MaskedValues.map(differences_squared)
179 | mean_of_differences_squared = ee.ImageCollection(mean_of_differences_squared).mean()
180 | // print('mean_of_differences_squared = ', mean_of_differences_squared)
181 | var rmse = mean_of_differences_squared.sqrt()
182 |
183 | var mean_absolut_error = function(image) {
184 | var differences = ee.Image(image).select('con').subtract(ee.Image(image).select('mod') )
185 | differences = ee.Image(differences).abs();
186 | return differences;
187 | };
188 | var MAE = MaskedValues.map(mean_absolut_error)
189 | MAE = ee.ImageCollection(MAE).mean()
190 |
191 | var Pearson = ee.ImageCollection(MaskedValues).reduce(ee.Reducer.pearsonsCorrelation());
192 |
193 | var scale = ee.Image('MODIS/006/MYD11A1/2018_01_01').projection().nominalScale().getInfo();
194 | var scale = ee.Image('NOAA/CFSV2/FOR6H/2018010112').projection().nominalScale().getInfo();
195 | var CFSV2Projection = CFSV2_TFA.projection();
196 | // var scale = CFSV2_TFA.projection().nominalScale().getInfo();
197 | var rmse_val = rmse.reduceRegion(ee.Reducer.mean(), geometry, scale)
198 | var MAE_val = MAE.reduceRegion(ee.Reducer.mean(), geometry_json, scale)
199 | var Pearson_val = Pearson.select('correlation').reduceRegion({
200 | reducer:ee.Reducer.mean(),
201 | geometry:geometry_json,
202 | scale:scale,
203 | crs:CFSV2Projection,
204 | })
205 |
206 | // print('RMSE = ', rmse_val)
207 | var f = ee.Feature(null,{
208 | 'year' : year,
209 | 'Pearson' : Pearson_val,
210 | 'RMSE' : rmse_val,
211 | 'MAE' : MAE_val,
212 | })
213 | return f;
214 | })
215 |
216 | var fromList = ee.FeatureCollection(correlation_statistics_by_year);
217 | print(fromList);
218 | // Export the FeatureCollection to a CSV file.
219 | Export.table.toDrive({
220 | collection: fromList,
221 | // description:'Night_TFA_only',
222 | description:'Night_TFA_plus_anomalies',
223 | folder: 'gee',
224 | fileFormat: 'CSV'
225 | });
226 |
--------------------------------------------------------------------------------