Following GEE code determines relative humidity (RH) in a point of land surface by using considerations exposed in this question and 'NASA/GLDAS/V20/NOAH/G025/T3H' products. Some individual values for pressure, temperature and specific humidity, also obtained from 'NASA/GLDAS/V20/NOAH/G025/T3H' products, were used for calculating relative humidity in a spreadsheet, with Clausius-Clapeyron formula, and results were identical to obtained with GEE (link to script).
var startDate = ee.Date('1981-01-01');
var endDate = ee.Date('1981-01-03');
var dataset = ee.ImageCollection('NASA/GLDAS/V20/NOAH/G025/T3H')
.filterDate(startDate, endDate);
var imageScale = ee.Image(dataset
.first())
.projection().nominalScale();
print('Scale:', imageScale);
var count = dataset.size();
print("count original", count);
var days = endDate.difference(startDate, 'days');
var daysStep = 1;
var timeSeries = ee.ImageCollection(
ee.List.sequence(0, days.subtract(1), daysStep)
.map(function (offsetDays) {
var start = startDate.advance(offsetDays, 'days');
var end = start.advance(daysStep, 'days');
var composite = dataset // former lst
.filterDate(start, end)
.min(); // You need to decide how to combine the images
return composite
.reproject('EPSG:4326', null, 27829.87269831839)
.set('system:time_start', start.millis())
.set('empty', composite.bandNames().size().eq(0));
})
).filterMetadata('empty', 'equals', 0);
print("count composite", timeSeries.size());
print("New Scale", timeSeries.first().projection().nominalScale());
var p = ee.Geometry.Point(-70.2166985,-38.5275513); //p18
var getDateHumidity = function(image) {
// Reducing region and getting value
var value_hum = ee.Image(image)
.reduceRegion(ee.Reducer.first(), p)
.get('Qair_f_inst');
var value_pres = ee.Image(image)
.reduceRegion(ee.Reducer.first(), p)
.get('Psurf_f_inst');
var value_temp = ee.Image(image)
.reduceRegion(ee.Reducer.first(), p)
.get('Tair_f_inst');
var f = ee.Number(0.00263)
.multiply(ee.Number(value_hum))
.multiply(ee.Number(value_pres));
var g = ee.Number(17.67)
.multiply(ee.Number(value_temp)
.subtract(ee.Number(273.16))
.divide(ee.Number(value_temp).subtract(ee.Number(29.65))))
.exp();
var h = f.divide(g);
var time = ee.Image(image).get('system:time_start');
// Return the time (in milliseconds since Jan 1, 1970) as a Date
var humidity_list = ee.Date(time)
.format()
.slice(0,10)
.split('-')
.add(h);
return humidity_list;
};
var humidity_list1 = dataset.toList(count).map(getDateHumidity);
var myFeatures1 = ee.FeatureCollection(humidity_list1.map(function(el){
el = ee.List(el); // cast every element of the list
var geom = p;
return ee.Feature(geom, {
'year':ee.Number(el.get(0)),
'month':ee.Number(el.get(1)),
'day':ee.Number(el.get(2)),
'value':ee.Number(el.get(3))
});
}));
//print(myFeatures1);
var humidity_list2 = timeSeries.toList(count).map(getDateHumidity);
//print(humidity_list);
var myFeatures2 = ee.FeatureCollection(humidity_list2.map(function(el){
el = ee.List(el); // cast every element of the list
var geom = p;
return ee.Feature(geom, {
'year':ee.Number(el.get(0)),
'month':ee.Number(el.get(1)),
'day':ee.Number(el.get(2)),
'value':ee.Number(el.get(3))
});
}));
//Map.addLayer(myFeatures); // see the result
//Map.centerObject(myFeatures, 8);
//print(myFeatures2);
// Export features, specifying corresponding names.
Export.table.toDrive({
collection: myFeatures1,
folder: "GEE_Folder", //my export folder
description: 'daily_humidity', //file name
fileFormat: "CSV"});
// Export features, specifying corresponding names.
Export.table.toDrive({
collection: myFeatures2,
folder: "GEE_Folder", //my export folder
description: 'daily_humidity', //file name
fileFormat: "CSV"});
Above script determines RH for an Image Collection with 8 images per day (each 3 hours) and RH for a composite of these eight daily images. Obtained values are exported to Google Drive and, in above example with used dates, were printed 16 values in first case and only 2 with composite function. Results are as follows:
16 values
1,1,1981,0.541049210101378
1,1,1981,0.612131423086637
1,1,1981,0.712494530538605
1,1,1981,0.732241931627969
1,1,1981,0.675578926045453
1,1,1981,0.582798200402885
1,1,1981,0.451271023830914
1,1,1981,0.400543900671863
2,1,1981,0.430912988431544
2,1,1981,0.513416664811639
2,1,1981,0.646455860743016
2,1,1981,0.727504186156708
2,1,1981,0.753175972018466
2,1,1981,0.681819169670857
2,1,1981,0.511359249899844
2,1,1981,0.428261514810568
2 values
1,1,1981,0.709153505818986
2,1,1981,0.537754061477617
As it can be observed in the script, I used a 'min' method in composite function for selecting RH values. However, above obtained values are very different from following two expected values:
1,1,1981,0.400543900671863
2,1,1981,0.428261514810568
I searched for the reason of this unexpected result and I found out that composite images are produced in GEE with the default projection; which is WGS84 with 1-degree scale. This is very different from original nominal scale of 'NASA/GLDAS/V20/NOAH/G025/T3H': 27829.87269831839 meters (0.25 arc degrees). So, I had to use following reproject method (.reproject('EPSG:4326', null, 27829.87269831839)) in composite function for finally run my script and to get that nominal scale.
On the other hand, only for curiosity, I changed 'min' method for 'max' and I also got following weird results:
1,1,1981,0.46162372954395
2,1,1981,0.640986494579716
So, is it necessary to use another (or other) complementary method with 'reproject', in a composite function, for obtaining expected result of true minimum values and preserve original resolution of 0.25 arc degrees?
Editing Note:
@Nicholas Clinton pointed out in his answer that the affirmation of "composite images are produced in GEE with the default projection" is not entirely right. It was simply found here. However, without following instruction in composite function:
.reproject('EPSG:4326', null, 27829.87269831839)
when I tried to print Feature Collection obtained with Image Collection in composite function, without any "reprojection", it was displayed the error message of following image where it pointed out: "The WGS84 projection is invalid for aggregations. Specify a scale or crs & crs_transform". Similar message was obtained when I tried to run the task. On the other hand, it can be also observed that scale of aggregated Image Collection is 111319.49079327357 m (equivalent to 1 arc degree); as mentioned in the previous link.
On the other hand, after reading link in Nicholas Clinton's answer, I adapted code for my ImageCollection:
var p = ee.Geometry.Point(-70.2166985,-38.5275513); //p18
var image = ee.ImageCollection('NASA/GLDAS/V20/NOAH/G025/T3H')
.first()
.select("Qair_f_inst");
print(image);
var printAtScale = function(scale) {
print('Pixel value at ' + scale + ' meters scale',
image.reduceRegion({
reducer: ee.Reducer.first(),
geometry: p,
// The scale determines the pyramid level from which to pull the input
scale: scale
}).get("Qair_f_inst"));
};
printAtScale(100); // 8883
printAtScale(1000); // 9215
printAtScale(10000); // 8775
printAtScale(100000); // 8300
printAtScale(1000000); // 8300
and result evidences a scale issue:
The problem is increasing by errors propagating because relative humidity is the combination of other bands and constants in the Clausius-Clapeyron equation. So, it seems that I need one way for retrieving former scale in composite series.