Contributing to Ndvi2Gif#
First off, thanks for taking the time to contribute! 🎉
This project grew from a small NDVI-to-GIF helper into a remote sensing analytics suite. We warmly welcome contributions of all sizes—from typo fixes to new indices, datasets, and examples.
How Can I Contribute?#
Fix bugs or improve error messages.
Add a new index (optical or SAR) — the easiest and most impactful contribution.
Add a new dataset (an Earth Engine ImageCollection properly integrated into the pipeline).
Improve documentation (README, tutorials, notebooks).
Add tests or simplify existing code.
Share use-case notebooks in
examples_notebooks/.
Contribution Workflow#
We follow the standard GitHub fork → branch → pull request model. You do not need write access to the main repository.
Fork the repository to your own GitHub account (click Fork at the top right of the repo page).
Clone your fork and add the original repo as an
upstreamremote so you can keep your fork in sync:git clone https://github.com/<your-username>/Ndvi2Gif.git cd Ndvi2Gif git remote add upstream https://github.com/Digdgeo/Ndvi2Gif.git
Create a feature branch off
master(never commit directly tomaster):git checkout -b my-new-index # e.g. add-savi-index, fix-export-crs
Make your changes, then commit them with a clear message:
git add . git commit -m "Add SAVI index for S2 and Landsat"
Keep your branch up to date with upstream before opening the PR:
git fetch upstream git rebase upstream/master
Push the branch to your fork and open a Pull Request against
Digdgeo/Ndvi2Gif:master:git push origin my-new-index
Then open the PR from GitHub and describe what you changed and why.
Development Setup#
Set up a development environment inside your cloned fork:
conda create -n ndvi2gif-dev python=3.11 -y
conda activate ndvi2gif-dev
pip install -e ".[dev]"
Authenticate Earth Engine (a Google Cloud project ID is required):
import ee
ee.Authenticate()
ee.Initialize(project='your-project-id')
Project Structure#
ndvi2gif.py→ NdviSeasonality: core seasonal/statistical engine.s1_ard.py→ S1ARDProcessor: Sentinel-1 preprocessing (ARD, speckle filters, terrain correction).timeseries.py→ TimeSeriesAnalyzer: time series extraction, trend analysis, phenology.examples_notebooks/→ contributed notebooks and tutorials.
Adding a New Index#
Add the index name to the correct set (
optical_indices,s1_indices, etc.).Implement the function in
NdviSeasonalityorS1ARDProcessor.Register it in the
self.ddispatch dictionary.Map it to the appropriate sensor in
self.sensor_indices.Add a minimal test and a short example (README or notebook).
Minimal example:
def get_myindex(self, image):
num = image.select("Nir").subtract(image.select("Red"))
den = image.select("Nir").add(image.select("Red"))
return num.divide(den).rename("MYINDEX")
# Register it
self.optical_indices.add("myindex")
self.d["myindex"] = self.get_myindex
self.sensor_indices["S2"].add("myindex")
self.sensor_indices["Landsat"].add("myindex")
Adding a New Dataset#
Contributing new Earth Engine datasets is one of the most useful ways to expand Ndvi2Gif.
Find the dataset in the Earth Engine catalog.
Example:COPERNICUS/S5P/NRTI/L3_NO2orNASA/ORNL/DAYMET_V4.Define its ImageCollection inside
_setup_satellite_collections()inNdviSeasonality.Give it a short, clear
satcode (e.g.,"S3","L8","MOD09").Apply standard filters (
date,bounds).
Standardize bands so that indices can use them.
Rename bands consistently:
Red,Nir,Green,Swir1,Blue, etc.Apply scale factors if the dataset requires (see Sentinel-2 or MODIS examples).
Register the dataset in
sensor_indicesto tell the system which indices it supports.Document it:
Add to README under Supported Datasets.
Include the Earth Engine catalog link.
Optionally add a short example in a notebook.
Test it:
Run a quick seasonal composite with a small ROI and check that it executes.
Add a smoke test in
tests/if possible.
Tip: use existing datasets (Sentinel-2 SR, MODIS SR, Landsat C2 L2) as templates — they show the correct pattern for scaling, band mapping, and validation.
Example: Adding a New Dataset (MODIS MOD13Q1)#
Suppose you want to add the MOD13Q1 dataset (16-day NDVI/EVI, 250m).
Locate the dataset in the Earth Engine catalog:
ID:MODIS/061/MOD13Q1
Bands:NDVI,EVI,sur_refl_b01,sur_refl_b02,sur_refl_b03, etc.Create a scaling helper (if needed):
def _scale_mod13(self, img): # MODIS scale factor = 0.0001 return img.multiply(0.0001).copyProperties(img, ["system:time_start"])
Update
_setup_satellite_collections()inNdviSeasonality:elif self.sat == "MOD13": col = ee.ImageCollection("MODIS/061/MOD13Q1") \ .filterDate(self.start_date, self.end_date) \ .filterBounds(self.roi) col = col.map(self._scale_mod13) # Standardize band names col = col.select( ["sur_refl_b01", "sur_refl_b02", "sur_refl_b03", "sur_refl_b07"], ["Red", "Nir", "Blue", "Swir2"] ) self.collection = col
Register it in
sensor_indices(at class init):self.sensor_indices["MOD13"] = {"ndvi", "evi", "ndwi", "msi"}
Test it quickly in a notebook:
proc = NdviSeasonality( roi=ee.Geometry.Point([-3.7, 40.4]).buffer(5000), # Madrid area sat="MOD13", periods=12, start_year=2020, end_year=2021, index="ndvi" ) img = proc.get_year_composite(2020) print(img.bandNames().getInfo())
Document it:
Add MOD13Q1 to README’s Supported Datasets table with the EE link.
Add a short notebook in
examples_notebooks/showing usage.
Testing#
We use pytest. Add lightweight smoke tests:
def test_ndvi_smoke():
proc = NdviSeasonality(roi=ee.Geometry.Point([0,0]).buffer(1000),
periods=12, start_year=2023, end_year=2024,
sat='S2', index='ndvi')
img = proc.get_period_composite(2023, 0)
assert isinstance(img, ee.Image)
Run tests with:
pytest -q
Pull Request Checklist#
Before opening the PR (see Contribution Workflow above), make sure you have:
Formatted with
black+isort.Linted with
rufforflake8.Added/updated docstrings and a
CHANGELOGentry.Added or updated a notebook if your change introduces a new feature.
Run the test suite (
pytest -q) and confirmed it passes.
Issues#
Please include:
Code snippet (or notebook cell).
Dataset/index/parameters used.
Expected vs. actual behavior.
Environment (Python version, OS, Earth Engine version).
Labels used: bug, index, dataset, docs, enhancement.
✨ Thanks for contributing to Ndvi2Gif! ✨