3

I have used the codes below to calculate the total annual for the image collection based on Calendar Year. Now I want to calculate the sum again using a water year, from 8/1/2018 to 8/31/2019 as one year for example.

How do I make my own annual range filter in Google Earth Engine?

> // Set start and end of time series

var startYear = 1981;

var endYear = 2019;

var regions = "municipio";

// Create a list of years by generating a sequence from start and end years 

var years = ee.List.sequence(startYear, endYear);


// Generate annual summed image mosaics 

var annualPrecip = ee.ImageCollection.fromImages(
  years.map(function (year) {
    var annual = chirps
        .filter(ee.Filter.calendarRange(year, year, 'year'))
        .sum();
    return annual
        .set('year', year)
        .set('system:time_start', ee.Date.fromYMD(year, 1, 1).format("YYYY_MM_dd"));
}));
1
  • Just change the second year to ee.Number(year).add(1) link
    – Kuik
    Commented Dec 4, 2019 at 19:51

2 Answers 2

5

Create two dates from ee.Date.fromYMD that represent the start and end of the water year in your mapped function. Add vars for water year start/end month and day; year is determined from the map-provided year. Use the given year for the start date and add 1 to year for the end date.

var startYear = 1981;
var endYear = 2019;
var regions = "municipio";
var startWaterMonth = 8;
var startWaterDay = 1;
var endWaterMonth = 8;
var endWaterDay = 31;

// Create a list of years by generating a sequence from start and end years 
var years = ee.List.sequence(startYear, endYear);

// Generate annual summed image mosaics 
var annualPrecip = ee.ImageCollection.fromImages(
  years.map(function (year) {
    var startDate = ee.Date.fromYMD(year, startWaterMonth, startWaterDay);
    var endDate = ee.Date.fromYMD(ee.Number(year).add(1), endWaterMonth, endWaterDay);
    var annual = chirps
      .filterDate(startDate, endDate)
      .sum();
    return annual
      .set('year', year)
      .set('system:time_start', ee.Date.fromYMD(year, 1, 1).format("YYYY_MM_dd"));
}));
6
  • Make it server-side operation: code.earthengine.google.com/d441ab37d55f41da2e080bef7148ee9c
    – Kuik
    Commented Dec 4, 2019 at 21:33
  • Thanks Kuik. I edited the script. Commented Dec 4, 2019 at 21:47
  • Thanks Justin! I have tried this, but it generates a water year for 1981, and low value for 2019. The output should not have 1981 since the data start from 1981...so it would start with 1982 (8/1/1981-8/31/1982). any idea why?
    – Effrain Mu
    Commented Dec 7, 2019 at 23:10
  • The year is being set by ee.Date.fromYMD(year, 1, 1) so it is valid to have 1981 in your collection because the first year in the years list is 1981. If you want the composite year set to the later year in a water year, use: ee.Date.fromYMD(ee.Number(year).add(1), 1, 1) Commented Dec 8, 2019 at 0:18
  • Using this, my last year for the output has changed to 2020. Since the CHIRPS data are available from 1981/1/1 - present, how would I make the code only calculate my 1982 water year (1981/8/1-1982/8/31) etc? Currently, I am not sure which calculated value is for which year...
    – Effrain Mu
    Commented Dec 8, 2019 at 0:53
0

Please include a link to a working script in your questions. It makes it easier to help you. You can do something like this:

var startYear = 1981;
var endYear = 2019;
var regions = "municipio";
var years = ee.List.sequence(startYear, endYear);
var chirps = ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
var annualPercip = ee.ImageCollection(
  years.iterate(function (year, collection) {
    year = ee.Number(year)
    var percip = chirps
      .filterDate(
        ee.Date.fromYMD(year, 1, 1), 
        ee.Date.fromYMD(year.add(1), 1, 1)
      )
      .sum()
    return ee.ImageCollection(collection).merge(ee.ImageCollection([percip]))
      .set('year', year)
      .set('system:time_start', ee.Date.fromYMD(year, 1, 1).format("YYYY_MM_dd"));
  }, ee.ImageCollection([]))
)
print(annualPercip)
Map.addLayer(annualPercip.first(), {min: 600, max: 900}, 'First year')

https://code.earthengine.google.com/f434c6c922b3730da2a5f155604508b3

2
  • It's best to avoid iterate if you can. First try using joins, then mapping over a list, then iterate. Some operations are truly iterative and depend on the previous result to produce current result, but this is often not the case for collection building. Commented Dec 4, 2019 at 20:38
  • Right - Justin's solution is definitely better Commented Dec 4, 2019 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.