Trying to detrend MODIS MOD13Q1 NDVI time series using a tutorial from Ozzy Campos (@ghidora77). This tutorial was for Landsat NDVI LANDSAT/LC08/C02/T1_L2 but I am trying to modify it for MODIS.
Successfully imported the data, parse it for quality control, masked, scaled and plotted the initial time series with a trend line. See the code in help3. Link to the asset: Oban.
Independent ('constant', 't') and dependent variables ('NDVI') have also been set. However, when trying to detrend the time series, I get the error below (see attached image). Because detrending doesn't work properly, I don't trust the resultant harmonic model.
Error generating chart: Projection error: Unable to compute
intersection of geometries in projections and
.
// List of the independent variable names.
var independents = ee.List(['constant', 't']);
// Name of the dependent variable.
var dependent = ee.String('NDVI');
// Compute a linear trend. This will have two bands: 'residuals' and
// a 2x1 band called 'coefficients' (columns are for dependent variables).
var trend = newndvi.select(independents.add(dependent))
.reduce(ee.Reducer.linearRegression(independents.length(), 1));
Map.addLayer(trend, {}, 'Trend Array Image');
/////////////////////////////////////////////////
// **************** HELP!!!!!!! ***************
// Flatten the coefficients into a 2-band image.
var coefficients = trend.select('coefficients')
.arrayProject([0])
.arrayFlatten([independents]);
Compute a detrended series.
var detrended = newndvi.map(function(image) {
return image.select(dependent).subtract(
image.select(independents).multiply(coefficients).reduce('sum'))
.rename(dependent)
.copyProperties(image, ['system:time_start']);
});
var detrendedChart = ui.Chart.image.series(detrended, Oban, null, 250)
.setOptions({
title: 'Detrended MODIS Time Series at Oban',
lineWidth: 1,
pointSize: 3,
});
print(detrendedChart);
Use these independent variables in the harmonic regression.
var harmonicIndependents = ee.List(['constant', 't', 'cos', 'sin']);
// Add harmonic terms as new image bands.
var harmonicLandsat = newndvi.map(function(image) {
var timeRadians = image.select('t').multiply(2 * Math.PI);
return image
.addBands(timeRadians.cos().rename('cos'))
.addBands(timeRadians.sin().rename('sin'));
});
var harmonicTrend = harmonicLandsat
.select(harmonicIndependents.add(dependent))
// The output of this reducer is a 4x1 array image.
.reduce(ee.Reducer.linearRegression({
numX: harmonicIndependents.length(),
numY: 1
}));
Turn the array image into a multi-band image of coefficients.
var harmonicTrendCoefficients = harmonicTrend.select('coefficients')
.arrayProject([0])
.arrayFlatten([harmonicIndependents]);
// Compute fitted values.
var fittedHarmonic = harmonicLandsat.map(function(image) {
return image.addBands(
image.select(harmonicIndependents)
.multiply(harmonicTrendCoefficients)
.reduce('sum')
.rename('fitted'));
});
// Plot the fitted model and the original data at the Oban.
print(ui.Chart.image.series(fittedHarmonic.select(['fitted', 'NDVI']), Oban,
ee.Reducer.mean(), 250)
.setSeriesNames(['NDVI', 'fitted'])
.setOptions({
title: 'Harmonic Model: Original and Fitted Values',
lineWidth: 1,
pointSize: 3
})
);
Compute phase and amplitude.
var phase = harmonicTrendCoefficients.select('sin')
.atan2(harmonicTrendCoefficients.select('cos'))
// Scale to [0, 1] from radians.
.unitScale(-Math.PI, Math.PI);
var amplitude = harmonicTrendCoefficients.select('sin')
.hypot(harmonicTrendCoefficients.select('cos'))
// Add a scale factor for visualization.
.multiply(5);
// Compute the mean NDVI.
var meanNdvi = newndvi.select('NDVI').mean();
// Use the HSV to RGB transformation to display phase and amplitude.
var rgb = ee.Image.cat([phase, amplitude, meanNdvi]).hsvToRgb();
Map.addLayer(rgb, {}, 'Phase (hue), Amplitude (sat), NDVI (val)');
Best Answer
You're hitting a bug related to a recent change. To work around it until the bug is fixed, assign a default projection to your reduced composites (e.g.: line 111).