Google Earth Engine – How to Reduce Image Collection for Daily Sum from Hourly Precipitation

google-earth-apigoogle-earth-enginejaxaprecipitation

I'm using GSMaP image collection in Google Earth Engine, which has hourly precipitation data from 2000 to present. I have a script which helps getting mean pcp data (as a table) from polygon from each available image in given period. Could anyone please assist me on how to make the function that it will sum the values of hourly data to daily then calculate mean value for each polygon. Please, find the script which should be improved below

var roi = /* color: #d63000 */ee.Geometry.Polygon(
        [[[61.20140075683594, 54.50124974644097],
          [64.93675231933594, 37.57329031970196],
          [78.12824249267578, 39.1411116861207],
          [74.65106964111328, 55.83455401161834]]], null, false);

// Load imagery.
var gsmap = ee.ImageCollection('JAXA/GPM_L3/GSMaP/v6/reanalysis')
    .filterBounds(roi)
    .filterDate('2015-01-01', '2016-01-01');

print('Number of gsmap images', gsmap.size()); // 365

// Load an Earth Engine table.
var blocks = ee.FeatureCollection('ft:1PwfP5L2saLWX5Hp-qr1LxGxxrwr5E_CDohogd9PF');
var subset = blocks.filterBounds(roi);
print('Number of provinces', subset.size()); // 3

Map.centerObject(roi, 5);
Map.addLayer(blocks, {color: 'gray'}, 'blocks');
Map.addLayer(subset, {}, 'subset');

// Collect block, image, value triplets.
var triplets = gsmap.map(function(image) {
  return image.select('precipitation').reduceRegions({
    collection: subset.select(['NAME_1']), 
    reducer: ee.Reducer.mean() 
  }).filter(ee.Filter.neq('mean', null))
    .map(function(f) { 
      return f.set('imageId', image.id());
    });
}).flatten();
print(triplets.first());

// Format a table of triplets into a 2D table of rowId x colId.
var format = function(table, rowId, colId) {
  // Get a FeatureCollection with unique row IDs.
  var rows = table.distinct(rowId);
  // Join the table to the unique IDs to get a collection in which
  // each feature stores a list of all features having a common row ID. 
  var joined = ee.Join.saveAll('matches').apply({
    primary: rows, 
    secondary: table, 
    condition: ee.Filter.equals({
      leftField: rowId, 
      rightField: rowId
    })
  });

  return joined.map(function(row) {
      // Get the list of all features with a unique row ID.
      var values = ee.List(row.get('matches'))
        // Map a function over the list of rows to return a list of
        // column ID and value.
        .map(function(feature) {
          feature = ee.Feature(feature);
          return [feature.get(colId), feature.get('mean')];
        });
      // Return the row with its ID property and properties for
      // all matching columns IDs storing the output of the reducer.
      // The Dictionary constructor is using a list of key, value pairs.
      return row.select([rowId]).set(ee.Dictionary(values.flatten()));
    });
};


var table1 = format(triplets, 'imageId', 'NAME_1');

var desc1 = 'gsmap_mean_province_15-16'; 
Export.table.toDrive({
  collection: table1, 
  description: desc1, 
  fileNamePrefix: desc1,
  fileFormat: 'CSV'
});

Will the below script give what I want?

// Collection of point
var pts = ee.FeatureCollection('ft:1edhBxjUJdfHf8EBTYzoKi2qwYMHN-tvyuVeXavp5')

// Start and End Dates
var inidate = ee.Date.fromYMD(2001,3,1)
var enddate = ee.Date.fromYMD(2001,4,1)

// Difference between start and end in days 
var difdate = enddate.difference(inidate, 'day')

// Import GSMaP data
var gsmap = ee.ImageCollection('JAXA/GPM_L3/GSMaP/v6/reanalysis')
.filterDate(inidate, enddate)
.select('hourlyPrecipRateGC');

// Time lapse
var lapse = ee.List.sequence(0, difdate.subtract(1))
var inidate = ee.Date('2001-03-01')
var listdates = lapse.map(function(day){
  return inidate.advance(day, 'day')
})

// Iterate over the list of dates
var newft = ee.FeatureCollection(listdates.iterate(function(day, ft) {
  // Cast
  ft = ee.FeatureCollection(ft)
  day = ee.Date(day)

  // Filter the collection in one day (24 images)
  var day_collection = gsmap.filterDate(day, day.advance(1, 'day'))

  // Get the sum of all 24 images into one Image
  var sum = ee.Image(day_collection.sum())

  // map over the ft to set a property over each feature
  var temp_ft = ft.map(function(feat){
    var geom = feat.geometry()
    var value = sum.reduceRegion(ee.Reducer.mean(), geom, 30).get('hourlyPrecipRateGC')
    return feat.set(day.format('YYYY-MM-dd'), value)
  })

  // Return the FeatureCollection with the new properties set
  return temp_ft
}, pts))


// Export
Export.table.toDrive(newft,
"CA_GSMaP_mean_temp",
"CA_GSMaP_mean_temp",
"CA_GSMaP_mean_temp")

Best Answer

This post explains how to do that for months. Here it is adapted for days:

var gsmap = ee.ImageCollection('JAXA/GPM_L3/GSMaP/v6/operational')
    .select(['hourlyPrecipRate'])
    .filterDate('2015-01-01', '2016-01-01');

var days = ee.List.sequence(1, 365);

var composites = ee.ImageCollection.fromImages(days.map(function(d) {
  var filtered = gsmap.filter(ee.Filter.calendarRange({
    start: d,
    field: 'day_of_year'
  }));
  return filtered.mean().multiply(24).set('day', d);
}));
print(composites);

var check = ee.Image(composites.first());
Map.addLayer(check, {min: 0, max: 1}, 'check');

Note that you've got another problem, which is using the wrong image collection for your date range. You need the 'operational' product. Finally, the data are in mm/hour, so this snippet takes the mean and multiplies it by 24.

To plug this in to your script, you'd do

var triplets = composites.map(function(image) {...});

Related Question