diff --git a/ecoscope/analysis/seasons.py b/ecoscope/analysis/seasons.py index 2ef062ee..15b8a929 100644 --- a/ecoscope/analysis/seasons.py +++ b/ecoscope/analysis/seasons.py @@ -20,23 +20,32 @@ def _min_max_scaler(x): return x_std -def std_ndvi_vals(aoi=None, start=None, end=None): - coll = ee.ImageCollection("MODIS/MCD43A4_006_NDVI").select("NDVI").filterDate(start, end) - - ndvi_vals = ( - coll.toBands() - .reduceRegion("mean", ee.Feature(shapely.geometry.mapping(aoi)).geometry(), bestEffort=True) - .values() - .getInfo() +def std_ndvi_vals(aoi=None, img_coll=None, band=None, img_scale=1, start=None, end=None): + + coll = ( + ee.ImageCollection(img_coll) + .select(band) + .filterDate(start, end) + .map(lambda x: x.multiply(ee.Image(img_scale)).set("system:time_start", x.get("system:time_start"))) ) - ndvi_vals_std = _min_max_scaler(ndvi_vals) - return pd.DataFrame( + + if aoi: + geo = ee.Feature(shapely.geometry.mapping(aoi)).geometry() + else: + geo = None + + ndvi_vals = coll.toBands().reduceRegion("mean", geo, bestEffort=True).values().getInfo() + + df = pd.DataFrame( { "img_date": pd.to_datetime(coll.aggregate_array("system:time_start").getInfo(), unit="ms", utc=True), - "NDVI": ndvi_vals_std, + "NDVI": ndvi_vals, } ).dropna(axis=0) + df["NDVI"] = _min_max_scaler(df["NDVI"]) + return df + def val_cuts(vals, num_seasons=2): distr = sklearn.mixture.GaussianMixture(n_components=num_seasons, max_iter=500) diff --git a/ecoscope/version.py b/ecoscope/version.py index c0f285b0..56dadec6 100644 --- a/ecoscope/version.py +++ b/ecoscope/version.py @@ -1 +1 @@ -__version__ = "1.4.4" +__version__ = "1.4.5" diff --git a/notebooks/05. Environmental Analyses/Seasonal Calculation.ipynb b/notebooks/05. Environmental Analyses/Seasonal Calculation.ipynb index a2820147..5ed4d8d3 100644 --- a/notebooks/05. Environmental Analyses/Seasonal Calculation.ipynb +++ b/notebooks/05. Environmental Analyses/Seasonal Calculation.ipynb @@ -29,7 +29,7 @@ "source": [ "ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n", "\n", - "# !pip install ecoscope" + "%pip install ecoscope &> /dev/null" ] }, { @@ -154,8 +154,26 @@ "metadata": {}, "outputs": [], "source": [ - "# Extract the standardized NDVI ndvi_vals within the AOI\n", - "ndvi_vals = seasons.std_ndvi_vals(aoi, start=\"2010-01-01\", end=\"2022-06-18\")\n", + "img_coll = \"MODIS/061/MOD13A1\"\n", + "band = \"NDVI\"\n", + "img_scale = 0.0001\n", + "since_filter = \"2010-01-01\"\n", + "until_filter = \"2022-06-18\"\n", + "\n", + "ndvi_vals = seasons.std_ndvi_vals(\n", + " img_coll=img_coll,\n", + " band=band,\n", + " img_scale=img_scale,\n", + " aoi=aoi,\n", + " start=since_filter,\n", + " end=until_filter,\n", + ")\n", + "\n", + "# Calculate the seasonal transition point\n", + "cuts = seasons.val_cuts(ndvi_vals, 2)\n", + "\n", + "# Determine the seasonal time windows\n", + "windows = seasons.seasonal_windows(ndvi_vals, cuts, season_labels=[\"dry\", \"wet\"])\n", "\n", "# Calculate the seasonal transition point\n", "cuts = seasons.val_cuts(ndvi_vals, 2)\n", @@ -247,7 +265,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.12" + "version": "3.8.10" } }, "nbformat": 4,