├── 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 | "\"Open" 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 | DOI 7 | 8 | ### How to visualize data using Qgis open source program 9 | LST in Qgis 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 | --------------------------------------------------------------------------------