Skip to main content

MODIS NDSI snow cover processing for Google Earth Engine

Project description

SnowMapPy

PyPI version Python 3.11+ License: MIT

A high-performance Python package for processing MODIS NDSI (Normalized Difference Snow Index) snow cover data from Google Earth Engine. SnowMapPy implements a scientifically validated 6-day moving window gap-filling algorithm for accurate Snow Cover Area (SCA) estimation.


Table of Contents


Features

Feature Description
Cloud Processing Direct integration with Google Earth Engine for MODIS data access
Sensor Fusion Combines Terra (MOD10A1) and Aqua (MYD10A1) observations
Gap-Filling 6-day moving window with quality-controlled interpolation
Elevation Correction DEM-based snow detection for high-altitude gaps (>1000m)
Memory Efficient Dask lazy loading with server-side GEE reprojection
Optimized Storage Zarr format with ZSTD compression (level 3)
Float16 Output 50% memory reduction while preserving NDSI precision
Interactive CLI User-friendly command-line interface with guided prompts
Progress Tracking Real-time progress bar during time series processing

Installation

Requirements

  • Python: 3.11 or higher
  • Memory: 8 GB RAM minimum (16 GB recommended for large regions)
  • Internet: Required for Google Earth Engine data access

Install from PyPI

pip install SnowMapPy

Install from Source

git clone https://github.com/haytamelyo/SnowMapPy.git
cd SnowMapPy
pip install -e .

Google Earth Engine Setup

  1. Create a GEE account at earthengine.google.com

  2. Create a Cloud Project in Google Cloud Console

  3. Authenticate:

earthengine authenticate
  1. Verify:
import ee
ee.Initialize(project='your-project-name')
print("Authentication successful")

Quick Start

Python API

from SnowMapPy import process_modis_ndsi_cloud

result, counters = process_modis_ndsi_cloud(
    project_name="your-gee-project",
    shapefile_path="study_area.shp",
    start_date="2020-01-01",
    end_date="2020-12-31",
    output_path="./output",
    crs="EPSG:32629",                        # Target CRS (server-side reprojection)
    interpolation_method="nearest",           # Options: nearest, linear, cubic
    spatial_correction_method="elevation_mean", # Options: elevation_mean, neighbor_based, none
    save_pixel_counters=True                  # Save gap-filling statistics
)

print(f"Processed {len(result.time)} days")

Output Structure

output/
├── study_area_NDSI.zarr/           # Gap-filled NDSI time series
│   ├── NDSI_Snow_Cover/            # Values 0-100 (float16)
│   ├── lat/                        # Coordinates
│   ├── lon/
│   └── time/
├── study_area_NDSI_pixel_counters.csv  # Gap-filling statistics
├── MOD.zarr/                       # Original Terra data (optional)
├── MYD.zarr/                       # Original Aqua data (optional)
└── DEM.zarr/                       # Elevation data (optional)

Command-Line Interface

Interactive Mode

snowmappy

The wizard guides you through all configuration options.

Command-Line Arguments

snowmappy \
    -p your-gee-project \
    -s study_area.shp \
    --start 2020-01-01 \
    --end 2020-12-31 \
    -o ./output
Option Description Default
-p, --project GEE project name Required
-s, --shapefile Study area shapefile Required
--start Start date (YYYY-MM-DD) Required
--end End date (YYYY-MM-DD) Required
-o, --output Output directory Required
-n, --name Output filename <shapefile>_NDSI
-i, --interpolation Interpolation method nearest
--spatial-correction Spatial correction method elevation_mean
--crs Coordinate reference system EPSG:4326
--save-counters Save pixel counters False

Algorithm

6-Day Moving Window

SnowMapPy processes each day using a 6-day temporal window:

Day Index:    -3    -2    -1     0    +1    +2
              ├─────┼─────┼─────┼─────┼─────┤
              │  3 days before  │  2 days after │
                         Current Day

The window configuration (3 days before + current + 2 days after) optimizes temporal coverage while preserving computational efficiency.

Processing Pipeline

Terra MOD10A1  ──┐
                 ├──► Quality Control ──► Sensor Fusion ──► 6-Day Window
Aqua MYD10A1  ───┘                              │
                                                ▼
SRTM DEM ────────────────────────────► Spatial Correction
                                                │
                                                ▼
                                      Temporal Interpolation
                                                │
                                                ▼
                                         Zarr Output

Quality Control

Invalid MODIS classes are masked before processing:

Class Description Action
50 Cloud Masked
37 Lake ice Masked
39 Inland water Masked
255 Ocean/Fill Masked

Spatial Correction Methods

Method Description
elevation_mean Fill gaps above mean snow elevation with NDSI=100 (recommended)
neighbor_based Fill based on snow presence in surrounding pixels above 1000m
none No spatial correction

Interpolation Methods

Method Speed Description
nearest Fastest Forward/backward fill (preserves extremes)
linear Medium Linear interpolation between valid observations
cubic Slower Cubic spline (smoothest transitions)

Technical Specifications

Storage Format

SnowMapPy uses Zarr v3 with ZSTD compression (level 3) for optimal storage:

  • Chunked storage for efficient partial reads
  • ZSTD provides ~60% compression ratio with fast decompression
  • Cloud-optimized format compatible with Dask parallel computing

Memory Optimization

Technique Benefit
Server-side reprojection Eliminates ~10GB local memory allocation
Dask lazy loading Only 6-day window materialized in RAM
Float16 output 50% memory reduction (sufficient for NDSI 0-100 range)
Streaming to Zarr Original data saved without full materialization

Data Types

Output uses float16 by default:

  • Preserves NaN values for missing data
  • Sufficient precision for NDSI range (0-100)
  • 50% smaller than float32, 75% smaller than float64

API Reference

process_modis_ndsi_cloud

Main processing function for MODIS NDSI data.

def process_modis_ndsi_cloud(
    project_name: str,
    shapefile_path: str,
    start_date: str,
    end_date: str,
    output_path: str,
    file_name: Optional[str] = None,
    crs: str = "EPSG:4326",
    save_original_data: bool = False,
    interpolation_method: str = "nearest",
    spatial_correction_method: str = "elevation_mean",
    save_pixel_counters: bool = False,
    verbose: bool = True,
    output_dtype: str = "float16"
) -> Tuple[xr.Dataset, dict]

Parameters:

Parameter Type Description
project_name str GEE project name
shapefile_path str Path to study area shapefile
start_date str Start date (YYYY-MM-DD)
end_date str End date (YYYY-MM-DD)
output_path str Output directory
file_name str Output filename (default: <shapefile>_NDSI)
crs str Target CRS (default: EPSG:4326)
save_original_data bool Save Terra/Aqua/DEM data
interpolation_method str nearest, linear, or cubic
spatial_correction_method str elevation_mean, neighbor_based, or none
save_pixel_counters bool Save statistics to CSV
output_dtype str float16, float32, or float64

Returns: Tuple of (xr.Dataset, dict) containing processed data and counters.


Configuration

Date Range

MODIS data availability:

  • Terra: February 24, 2000 - present
  • Aqua: July 4, 2002 - present

Dates outside availability are automatically adjusted.

Performance Recommendations

For large study areas, process in yearly segments:

for year in range(2010, 2021):
    process_modis_ndsi_cloud(
        project_name="your-project",
        shapefile_path="large_area.shp",
        start_date=f"{year}-01-01",
        end_date=f"{year}-12-31",
        output_path=f"./output/{year}"
    )

Troubleshooting

Authentication Error

# Re-authenticate with GEE
earthengine authenticate

Memory Issues

  • Process smaller time ranges (monthly instead of yearly)
  • Reduce study area extent
  • The package automatically uses memory-efficient processing

Slow Downloads

Data download time scales with:

  • Study area size
  • Time range length
  • GEE server load

CRS Issues

Ensure shapefile has valid CRS:

import geopandas as gpd
gdf = gpd.read_file("input.shp")
gdf = gdf.to_crs("EPSG:4326")
gdf.to_file("output.shp")

Citation

@software{snowmappy2025,
  author       = {Elyoussfi, Haytam and Bechri, Hatim and Bousbaa, Mostafa},
  title        = {SnowMapPy: MODIS Snow Cover Processing for Google Earth Engine},
  year         = {2025},
  version      = {0.0.1},
  publisher    = {GitHub},
  url          = {https://github.com/haytamelyo/SnowMapPy}
}

Related Publication

Bousbaa, M., et al. (2024). An accurate snow cover product for the Moroccan Atlas Mountains. International Journal of Applied Earth Observation and Geoinformation, 129, 103851. https://doi.org/10.1016/j.jag.2024.103851


License

MIT License - see LICENSE for details.


Authors


SnowMapPy - Precision Snow Cover Mapping

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snowmappy-0.0.1.tar.gz (56.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snowmappy-0.0.1-py3-none-any.whl (58.4 kB view details)

Uploaded Python 3

File details

Details for the file snowmappy-0.0.1.tar.gz.

File metadata

  • Download URL: snowmappy-0.0.1.tar.gz
  • Upload date:
  • Size: 56.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for snowmappy-0.0.1.tar.gz
Algorithm Hash digest
SHA256 05e6430baa2fdc922447ac612c034fe85c34a70756459f63c0146bff74a7ed91
MD5 7950af521b5ef6f3757421c12fede5ac
BLAKE2b-256 c96499725734d519aa65ef186193fbcc9fd4b680339ed47ad146e01545f1ecc6

See more details on using hashes here.

File details

Details for the file snowmappy-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: snowmappy-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 58.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for snowmappy-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1e83846fe7bbb3a32406b6dcdfe6cd0565e8de15614671a9129fb4b438d60fc9
MD5 3aeaccdf7c47363fc66924c3b4db7cef
BLAKE2b-256 73f420b7cba79f5d4dcc7a22fc632a0f284ad359840b31ff4cb89c8456ddf46e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page