Changelog

Contents

Changelog#

All notable changes to the ndvi2gif package will be documented in this file.


All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.5.0] - 2026-08-24#

Added#

  • 🎨 Raw reflectance bands as selectable indices: the standardized bands can now be requested directly through index=, on Sentinel-2, Landsat and MODIS:

    • index='blue', 'green', 'red', 'nir', 'swir1', 'swir2', plus 'red_edge1', 'red_edge2' and 'red_edge3' on Sentinel-2.

    • Values come back as surface reflectance in 0-1 on every sensor. Sentinel-2 and MODIS store reflectance as integers multiplied by 10000 and are rescaled on the fly (self.reflectance_scale); Landsat is already rescaled by scale_OLI / scale_ETM. The same numeric threshold therefore means the same thing whichever sensor produced it.

    • Not available on Sentinel-3, whose bands are top-of-atmosphere radiances with a different band set, nor on Sentinel-1, which already exposes vv and vh.

    Spectral indices are ratios and cancel out multiplicative changes in brightness, so a pixel can keep exactly the same NDVI while its reflectance drifts. Combined with the dispersion reducers added in 1.4.0, the bands map how radiometrically invariant each pixel is over a time series, which is how pseudo-invariant features (PIFs) are selected for relative radiometric normalization.

  • πŸ”’ key='count': number of valid (non-masked) observations per pixel in each period. Not a value statistic but a quality layer: a standard deviation computed from three observations means very little, so count tells which parts of a dispersion map can be trusted. With periods=1 it gives the yearly observation count per pixel, which also exposes the extra coverage in Sentinel-2 tile overlaps.

Fixed#

  • SpatialTrendAnalyzer.calculate_pixel_trends() dropped the last year of every trend map. It iterated range(start_year, end_year) while get_year_composite() treats end_year as inclusive, so a 2018-2025 request was fitted on 2018-2024. The magnitude band was wrong on top of that: the slope was multiplied by end_year - start_year while the series only spanned one year less, overestimating the accumulated change by a full year.

  • method='mann_kendall' was documented but never implemented β€” it fell through to the else branch and raised ValueError. It now returns Sen’s slope, intercept and magnitude plus tau, Kendall’s rank correlation with time, which is scale-free and so comparable across bands and sensors. ee.Reducer.kendallsCorrelation() also offers a p-value band, deliberately not returned: it comes back fully masked at every series length tested (n = 8 to 60, including trends scipy.stats.kendalltau scores below 1e-20), and a fully masked band silently masks whatever it is combined with. The ValueError for an unknown method now lists the valid ones.

Changed#

  • book/reference/indices.md: the overview table now matches the code (110 variables, not 88) and documents the new bands. The per-section counts and a few listed-but-unimplemented indices further down that page are still out of sync and pending a separate revision.

  • Dropped pycrs from the dependencies: it was declared but never imported anywhere in the package. Removed the unused import fiona from ndvi2gif.py as well, though fiona stays in the dependencies because geopandas uses it as a file engine.

[1.4.0] - 2026-08-22#

Added#

  • πŸ“Š Dispersion reducers: four new key options in NdviSeasonality that describe how much an index varies inside each period, instead of its typical level:

    • key='std' β€” standard deviation of the observations in the period.

    • key='variance' β€” variance of the observations in the period.

    • key='range' β€” maximum minus minimum (within-period amplitude).

    • key='cv' β€” coefficient of variation (std / mean).

    They work with every sensor and index, and the resulting composites keep the usual period band names (winter, spring, summer, autumn, january…december, …), so they can be exported, animated and analysed exactly like the existing max/median/mean composites. Useful to map phenological change, disturbances and unstable surfaces such as flooded areas.

    cv divides by the mean, so it is only meaningful for indices that stay positive; a warning is printed when it is used with Sentinel-1 backscatter in dB.

  • πŸ’§ Water mask download in HydroperiodAnalyzer: the per-date binary water masks can now be exported alongside the hydroperiod bands.

    • get_water_masks_stack() flattens the mask collection into a single uint8 ee.Image with one band per acquisition date (water_YYYY_MM_DD), encoded as 0 = dry, 1 = water, 2 = observed but discarded as cloud/shadow, 255 = no scene covered the pixel or outside the ROI. Both no-value codes are configurable (masked_value, nodata).

    • export_water_masks_to_drive() and export_water_masks_to_asset() send that stack to Google Drive or to an Earth Engine asset.

    • export_to_drive(..., include_masks=True) and export_to_asset(..., include_masks=True) launch both exports at once and return a (hydroperiod_task, masks_task) tuple. The index, threshold and cycle are read from the 'index'/'threshold'/'hyd_year_start' properties of the image being exported, so the masks always match it even if compute_hydroperiod() has since been called with other settings; the cached values are used only for images that carry no such metadata. The asset version accepts masks_asset_id and otherwise derives it from asset_id with a _water_masks suffix.

    • get_water_masks() gained an add_footprint flag adding a 'footprint' band (1 inside the acquisition footprint of that date). This is what separates β€œcloudy” from β€œnever observed” β€” the footprint survives the cloud mask, so the slanted edges of Landsat scenes and the gaps between orbits are identified as real no-data instead of being lumped in with clouds. Off by default, so get_water_masks() keeps returning a single-band collection.

    The masks go to a separate file on purpose: a GeoTIFF holds a single data type, so bundling them with the int16 hydroperiod bands would promote them to int16 and cancel out the saving. Earth Engine does not write a nodata tag into the GeoTIFF header, so 255 must be declared as nodata when reading the file.

Fixed#

  • tests/test_basic.py no longer asserts the old silent fallback for invalid sat/key values (both raise ValueError since v1.2), and passes each sensor an index it actually supports.

  • tests/conftest.py now initializes Earth Engine before collecting the tests. Building an NdviSeasonality already talks to the EE client, so the tests that make no EE calls of their own were failing anyway; a bare ee.Initialize() only works when the credentials carry a Cloud project, so EARTHENGINE_PROJECT/GOOGLE_CLOUD_PROJECT is used as a fallback. Without a session those tests are skipped with an explanatory message instead of erroring out.

[1.3.1] - 2026-07-07#

Fixed#

  • Sensor status messages during collection setup are now printed only for the selected satellite, instead of for every supported sensor, reducing console verbosity (JOSS review, davemlz #4).

No Breaking Changes#

Full backward compatibility with v1.3.0.

[1.3.0] - 2026-06-14#

Added#

  • 🌱 SpatialPhenologyAnalyzer: New GEE-native module that produces per-pixel phenology rasters (Start/Peak/End of Season and derived metrics) for the whole ROI, entirely server-side. Complements the point-based phenology of TimeSeriesAnalyzer.

    • Output bands: sos, pos, eos, los, amplitude, peak_value, baseline, growth_rate, senescence_rate (SOS/POS/EOS/LOS in day-of-year).

    • Three server-side methods: threshold (amplitude crossing), derivative (steepest rate of change) and harmonic (per-pixel Fourier regression β†’ smooth curve β†’ threshold extraction). The harmonic method is the Earth Engine-native replacement for the client-side double-logistic fit, which relies on scipy.optimize.curve_fit and cannot run server-side.

    • Two outputs: extract_phenology_rasters() returns one image per year (ee.ImageCollection); phenology_summary() returns a single multi-year aggregate (ee.Image).

    • Export to local GeoTIFF (band names embedded via rasterio) or Google Drive (batch task, band names preserved by Earth Engine) through export_target='local'|'drive'.

  • New documentation section β€œPer-pixel spatial phenology” in book/advanced/time_series.md and example notebook examples_notebooks/Spatial_Phenology.ipynb.

Changed#

  • Added rasterio to the runtime dependencies (used to embed band names in locally exported GeoTIFFs).

No Breaking Changes#

Full backward compatibility with v1.2.x.


[1.2.0] - 2026-04-12#

Added#

  • πŸ’§ HydroperiodAnalyzer: New GEE-native module for wetland and floodplain hydroperiod analysis.

    • Computes flood duration per pixel (days/year) entirely server-side using the midpoint temporal weighting method, based on the methodology of phydroperiod.

    • Output bands: hydroperiod, valid_days, normalized, first_flood_doy, last_flood_doy.

    • Multi-year support: compute_all_cycles() and compute_anomalies().

    • IRT (Irreplaceable Resource Taxonomy) metrics: global (compute_irt_global()) and per-pixel (compute_irt_image()).

    • Export to Google Drive and Earth Engine Assets.

  • SCL cloud masking for Sentinel-2: New scl_mask=True parameter in NdviSeasonality and mask_s2_scl() method. Uses the Scene Classification Layer for more accurate cloud, shadow and cirrus detection. Set scl_mask=False to restore legacy QA60 behaviour.

Fixed#

  • Removed numpy<2.0 pin β€” numpy 2.x is now fully supported (numpy>=1.24).

No Breaking Changes#

Full backward compatibility with v1.1.0. scl_mask=True is the new default for Sentinel-2 cloud masking; set scl_mask=False to restore previous behaviour.


[1.0.0] - 2025-12-28#

πŸŽ‰ FIRST STABLE RELEASE - JOSS PUBLICATION#

This milestone release marks ndvi2gif as production-ready with comprehensive climate reanalysis data support (ERA5-Land and CHIRPS), expanding the library beyond vegetation monitoring into integrated climate-vegetation analysis. The library now supports 88 variables across 7 different satellite/reanalysis platforms, with intelligent handling of climate vs. vegetation data in time series analysis.

NEW in 1.0.0: Complete Jupyter Book documentation for JOSS (Journal of Open Source Software) submission, including comprehensive API reference, dataset guides, and usage tutorials.


✨ New Features#

🌑️ ERA5-Land Climate Reanalysis Support (NEW)#

  • NEW DATASET: Complete integration with ECMWF ERA5-Land Daily Aggregated dataset

  • NEW: 47 climate variables spanning 1950-present at ~11km resolution:

    • Temperature (24 variables):

      • Basic: temperature_2m, dewpoint_temperature_2m, skin_temperature, soil_temperature_level_1

      • Daily min/max variants (8 variables with _min and _max suffixes)

      • Celsius conversions (12 variables with _celsius suffix)

    • Precipitation & Water Balance (11 variables):

      • Meters: total_precipitation_sum, total_evaporation_sum, potential_evaporation_sum, runoff_sum, surface_runoff_sum

      • L/mΒ² conversions (6 variables with _lm2 suffix for intuitive units)

    • Soil Moisture (4 variables): volumetric_soil_water_layer_1 through layer_4

    • Radiation (3 variables): Solar radiation and heat flux measurements

    • Wind & Pressure (3 variables): Wind components and surface pressure

    • Snow (2 variables): Snow depth and snowfall

  • NEW: Unit conversion functions for user-friendly values:

    • Temperature: Kelvin to Celsius (K - 273.15)

    • Precipitation: Meters to L/mΒ² (m Γ— 1000)

  • NEW: Support for daily aggregated statistics (mean, min, max, sum, median, percentile)

🌧️ CHIRPS Precipitation Dataset (NEW)#

  • NEW DATASET: Integration with UCSB Climate Hazards Group CHIRPS Daily precipitation

  • NEW: High-resolution precipitation monitoring (1981-present, ~5.5km resolution)

  • NEW: Global coverage from 50Β°S to 50Β°N latitude

  • NEW: Combines satellite imagery with in-situ station data for improved accuracy

  • NEW: Ideal for drought monitoring, precipitation climatology, and trend analysis

πŸ“Š Enhanced Statistical Methods#

  • NEW: sum statistic for temporal aggregation (essential for precipitation totals)

  • NEW: min statistic for minimum value extraction (temperature minimums, etc.)

  • IMPROVED: All statistical reducers now work with climate variables

πŸ”§ Time Series Analysis Improvements#

  • NEW: Intelligent climate data detection in TimeSeriesAnalyzer

  • NEW: Climate-specific summary statistics panel (replaces vegetation phenology for ERA5/CHIRPS)

  • NEW: Seasonal climate statistics (winter, spring, summer, autumn averages)

  • NEW: Annual mean and range calculations for climate variables

  • IMPROVED: Dashboard automatically adapts display based on data type (vegetation vs. climate)


πŸ› Bug Fixes#

πŸ“… Critical: Inclusive Year Range#

  • FIXED: end_year parameter is now inclusive instead of exclusive

    • Before: start_year=2023, end_year=2023 would return NO data

    • After: start_year=2023, end_year=2023 correctly includes all of 2023

  • FIXED: Updated all year range calculations throughout the codebase

  • FIXED: Corrected documentation to reflect inclusive behavior

  • IMPACT: This is a breaking change for users who worked around the old exclusive behavior

πŸ—ΊοΈ Geometry Operations#

  • FIXED: ROI centroid calculation now includes maxError=1 parameter to prevent geometry operation errors

  • FIXED: Improved error handling for centroid-based extractions in time series analysis

πŸ›°οΈ Sentinel-3 Band Naming#

  • FIXED: Corrected uppercase/lowercase inconsistency in Sentinel-3 band names

  • FIXED: Changed 'NIR' to 'Nir' for consistency with index calculations

  • IMPACT: Sentinel-3 indices now work correctly without band selection errors


πŸ“š Documentation Updates#

πŸ“– README Enhancements#

  • ADDED: Complete ERA5-Land variable documentation with units and descriptions

  • ADDED: CHIRPS dataset documentation with coverage and use cases

  • ADDED: Unit conversion examples (Celsius, L/mΒ²)

  • UPDATED: Supported datasets section with climate reanalysis platforms

  • UPDATED: Project statistics reflecting 7 sensors and 88 total variables

πŸ§ͺ Testing#

  • ADDED: Unit tests for ERA5 variable availability

  • ADDED: Unit tests for CHIRPS precipitation integration

  • ADDED: Tests for CHIRPS in satellite validation suite

  • UPDATED: Satellite options tests to include ERA5 and CHIRPS


πŸ“Š Project Statistics (v1.0.0)#

  • Supported Sensors: 7 (S1, S2, S3, Landsat, MODIS, ERA5-Land, CHIRPS)

  • Total Variables: 88

    • 40+ vegetation and environmental indices

    • 47 ERA5-Land climate variables

    • 1 CHIRPS precipitation variable

  • Temporal Coverage: 1950-present (ERA5) and 1981-present (CHIRPS)

  • Spatial Resolutions: 10m (S2) to ~11km (ERA5) to ~5.5km (CHIRPS)

  • ML Algorithms: 8 (5 supervised, 3 unsupervised)


πŸ”„ API Changes#

Breaking Changes#

⚠️ BREAKING: end_year parameter behavior changed from exclusive to inclusive

# Before v1.0.0 (exclusive)
NdviSeasonality(start_year=2020, end_year=2023)  # Processed 2020, 2021, 2022

# After v1.0.0 (inclusive)
NdviSeasonality(start_year=2020, end_year=2023)  # Processes 2020, 2021, 2022, 2023

New Parameters#

# ERA5 climate data
processor = NdviSeasonality(
    sat='ERA5',
    index='temperature_2m_celsius',  # or any of 47 ERA5 variables
    key='mean',  # or 'min', 'max', 'sum', 'median', 'percentile'
    start_year=2020,
    end_year=2023  # Now inclusive!
)

# CHIRPS precipitation
chirps = NdviSeasonality(
    sat='CHIRPS',
    index='precipitation',
    key='sum',  # Monthly/seasonal totals
    start_year=2020,
    end_year=2023
)

πŸš€ Example Use Cases#

Climate Analysis with ERA5#

import ee
from ndvi2gif import NdviSeasonality
from ndvi2gif.timeseries import TimeSeriesAnalyzer

ee.Initialize()

# Temperature analysis
temp = NdviSeasonality(
    roi=ee.Geometry.Point([-6.48, 37.13]).buffer(5000),
    sat='ERA5',
    index='temperature_2m_celsius',
    periods=12,
    start_year=2020,
    end_year=2023,
    key='mean'
)

# Extract time series and analyze trends
analyzer = TimeSeriesAnalyzer(temp)
df = analyzer.extract_time_series()
trends = analyzer.analyze_trend(df=df)
fig = analyzer.plot_comprehensive_analysis()  # Shows climate stats, not phenology

Precipitation Monitoring with CHIRPS#

# Monthly precipitation totals
precip = NdviSeasonality(
    roi=roi,
    sat='CHIRPS',
    index='precipitation',
    periods=12,
    start_year=2020,
    end_year=2023,
    key='sum'  # Sum for monthly totals
)

# Analyze drought patterns
analyzer = TimeSeriesAnalyzer(precip)
df = analyzer.extract_time_series()
trends = analyzer.analyze_trend(df=df, method='mann_kendall')

πŸ™ Acknowledgments#


[0.6.0] - 2025-09-15#

🧠 MACHINE LEARNING & CLASSIFICATION RELEASE#

This release introduces comprehensive land cover classification capabilities and enhanced export functionality, positioning ndvi2gif as a complete remote sensing analysis suite. The library continues to mature toward v1.0.0 with advanced documentation and expanded analytical capabilities.


✨ New Features#

🧠 Land Cover Classification Module (NEW)#

  • NEW MODULE: Complete LandCoverClassifier class for supervised and unsupervised classification

  • NEW: Cloud masking options for Sentinel-2 and Landsat collections

  • NEW: Multi-temporal feature stack generation with automatic normalization

  • NEW: Support for multiple classification algorithms:

    • Random Forest (with feature importance)

    • Support Vector Machine (SVM)

    • Classification and Regression Trees (CART)

    • Naive Bayes

    • Gradient Tree Boost

  • NEW: Unsupervised clustering algorithms:

    • K-means

    • Cascade K-means

    • Latent Dirichlet Allocation (LDA)

  • NEW: Comprehensive accuracy assessment with confusion matrices

  • NEW: Training data support from shapefiles, GeoJSON, and point/polygon sampling

  • NEW: Feature importance analysis for Random Forest models

  • NEW: Visualization tools for confusion matrices and accuracy reports

πŸš€ Enhanced Export Capabilities#

  • NEW: export_to_drive() - Batch export to Google Drive with full parameter control

  • NEW: export_to_asset() - Export to Earth Engine Assets with pyramiding policies

  • NEW: _default_scale_for_sat() - Automatic scale selection based on sensor

  • NEW: Advanced export options including:

    • Custom pyramiding policies for classification data

    • Overwrite protection for assets

    • Format-specific options (compression, file per band)

    • Maximum pixel limits and CRS control

πŸ“Š Time Series Analysis Enhancements (Updated)#

  • IMPROVED: Enhanced documentation with complete examples

  • IMPROVED: Better error handling and user feedback

  • IMPROVED: More robust phenology extraction methods

  • IMPROVED: Advanced visualization capabilities with publication-ready plots


πŸ”§ Major Improvements#

πŸ“š Documentation Overhaul#

  • IMPROVED: Complete Sphinx-style docstrings for all classes and methods

  • IMPROVED: Comprehensive parameter documentation with types and examples

  • IMPROVED: Scientific references added to all spectral indices

  • IMPROVED: Detailed usage examples in docstrings

  • IMPROVED: Better error descriptions with suggested solutions

  • IMPROVED: Cross-references between related methods

πŸ›°οΈ SAR Processing Enhancements#

  • IMPROVED: Enhanced error handling in S1ARDProcessor

  • IMPROVED: Better documentation for terrain correction parameters

  • IMPROVED: More detailed method descriptions with scientific references

  • IMPROVED: Improved parameter validation and user feedback

🌍 API Consistency#

  • IMPROVED: Consistent parameter naming across all modules

  • IMPROVED: Standardized return types and error handling

  • IMPROVED: Better integration between NdviSeasonality and new modules

  • IMPROVED: More informative console output and progress tracking


πŸ”„ API Changes & Enhancements#

πŸ“¦ Module Structure#

# NEW imports available in v0.6.0
from ndvi2gif import (
    NdviSeasonality,        # Core functionality (enhanced)
    S1ARDProcessor,         # SAR preprocessing (improved docs)
    TimeSeriesAnalyzer,     # Time series analysis (enhanced)
    SpatialTrendAnalyzer,   # Spatial analysis (enhanced)
    LandCoverClassifier,    # NEW: Classification workflows
)

πŸ†• New Method Signatures#

# NEW: Enhanced export methods
processor.export_to_drive(
    image=classified_map,
    description="landcover_2023",
    folder="ndvi2gif_results",
    scale=30,
    crs="EPSG:4326"
)

processor.export_to_asset(
    image=classification,
    asset_id="users/yourname/landcover_2023",
    pyramiding_policy={"class": "mode"},
    overwrite=True
)

# NEW: Classification workflow
classifier = LandCoverClassifier(processor)
features = classifier.create_feature_stack(
    indices=['ndvi', 'evi', 'ndwi'],
    include_statistics=True,
    normalize=True
)
classifier.add_training_data('training_points.shp')
result = classifier.classify_supervised('random_forest')

πŸ› οΈ Under the Hood#

πŸ”§ Code Quality#

  • IMPROVED: Consistent error handling with informative messages

  • IMPROVED: Better type hints throughout the codebase

  • IMPROVED: More robust parameter validation

  • IMPROVED: Enhanced memory efficiency in large-area processing

  • IMPROVED: Better handling of edge cases and invalid inputs

πŸ“ˆ Performance#

  • OPTIMIZED: Feature stack generation for classification

  • OPTIMIZED: Memory usage in multi-temporal processing

  • OPTIMIZED: Export operations with better chunking strategies


πŸ› Bug Fixes#

  • FIXED: Improved error handling when no satellite data is available

  • FIXED: Better validation of ROI inputs and coordinate systems

  • FIXED: Enhanced handling of edge cases in temporal compositing

  • FIXED: More robust processing of incomplete time series

  • FIXED: Better handling of mixed sensor collections


πŸ“– Examples & Use Cases#

🌾 Agricultural Monitoring#

# Multi-temporal crop classification
processor = NdviSeasonality(
    roi='farm_boundaries.shp',
    sat='S2', periods=12,
    start_year=2022, end_year=2024
)

classifier = LandCoverClassifier(processor)
features = classifier.create_feature_stack(['ndvi', 'evi', 'ndre'])
classifier.add_training_data('crop_samples.shp')
crop_map = classifier.classify_supervised('random_forest')

🌊 Water Quality Assessment#

# Sentinel-3 water quality with export to Drive
processor = NdviSeasonality(
    roi='lake_boundary.shp',
    sat='S3', index='turbidity',
    periods=24  # Bi-monthly
)

composites = processor.get_year_composite()
processor.export_to_drive(
    image=composites.first(),
    description="lake_turbidity_2024",
    folder="water_quality"
)

πŸ”οΈ SAR Forest Monitoring#

# Advanced SAR processing with classification
processor = NdviSeasonality(
    sat='S1', index='rvi',
    use_sar_ard=True,
    sar_speckle_filter='REFINED_LEE',
    sar_terrain_correction=True
)

classifier = LandCoverClassifier(processor)
forest_map = classifier.classify_unsupervised('kmeans', n_clusters=5)

⚠️ No Breaking Changes#

Full backward compatibility maintained with v0.5.x. All existing code continues to work unchanged.


πŸ”„ Migration Guide#

From v0.5.x to v0.6.0#

No breaking changes! All existing code will continue to work. New features are additive:

# v0.5.x code continues to work unchanged
processor = NdviSeasonality(sat='S2', index='ndvi')
processor.get_gif('animation.gif')

# v0.6.0 adds new capabilities
classifier = LandCoverClassifier(processor)  # NEW
processor.export_to_drive(image, "export")   # NEW

🎯 Future Roadmap#

v1.0.0 (Planned) - Complete Climate Analysis Platform#

  • πŸ“š Jupyter Book: Interactive documentation with comprehensive tutorials and examples

  • 🌑️ Climate Datasets: Integration with ERA5, CHIRPS, TerraClimate, and other climate model datasets

  • 🌍 Climate Analysis: Advanced tools for climate change impact assessment and adaptation planning


πŸ“Š Statistics#

  • New classes: 1 (LandCoverClassifier)

  • New methods: 15+ (classification, enhanced exports, utilities)

  • Enhanced methods: 20+ (improved documentation and error handling)

  • Lines of code: ~3,500 β†’ ~4,800 (+37%)

  • Documentation coverage: 95%+ (comprehensive docstrings)


πŸ™ Acknowledgments#

Special thanks to the Google Earth Engine team and the open-source remote sensing community for their continued support and feedback that made this release possible.


πŸ“š Documentation#

Complete documentation with tutorials available at: GitHub Repository


Full Changelog: https://github.com/Digdgeo/Ndvi2Gif/compare/v0.5.0…v0.6.0

[0.5.0] - 2025-08-28#

Added#

  • πŸ›°οΈ Sentinel-1 ARD Processor: New S1ARDProcessor module for advanced SAR preprocessing:

    • Radiometric terrain correction (angular method, Vollrath et al. 2020).

    • Configurable speckle filters: Boxcar, Lee, Refined Lee, Gamma-MAP, Lee Sigma.

    • Flexible DEM options (Copernicus 30/90, SRTM 30/90).

  • πŸ“ˆ TimeSeriesAnalyzer: New module for time series and phenological analysis:

    • Robust extraction of temporal profiles from points or polygons.

    • Trend analysis (Mann-Kendall, Linear regression, Sen’s slope).

    • Comprehensive dashboards (trend, seasonality, autocorrelation, quality).

    • Phenological metrics (SOS, EOS, POS, LOS, amplitude, growth/senescence rates).

  • 🌱 NdviSeasonality improvements:

    • Extended ROI handling: DEIMS sites, Sentinel-2 MGRS tiles, Landsat WRS path/row, shapefiles, GeoJSON.

    • Flexible temporal periods (4, 12, 24, or custom definitions).

    • Optional SAR normalization and enhanced orbit handling.

    • More robust sensor-index validation.

Changed#

  • Visualization: Unified plotting style with Seaborn/Matplotlib, clearer layouts.

  • Documentation: Updated examples covering SAR and time series analysis.

Fixed#

  • More robust handling of null/NaN values in temporal extraction.

  • Minor bug fixes in period generation and export routines.

[0.4.1] - 2025-07-21#

Added#

[0.4.0] - 2025-07-21#

Added#

  • πŸ›°οΈ Sentinel-3 OLCI Support: Revolutionary addition with 21 spectral bands and daily global coverage

  • 🌊 Advanced Water Quality Indices: 10 specialized aquatic indices including OCI, TSI, CDOM, turbidity, SPM, KD490, floating algae detection

  • πŸ”¬ Enhanced Sentinel-2: Complete Red Edge implementation with Surface Reflectance for superior data quality

  • πŸ’§ Cyanobacteria Detection: New NDCI index for harmful algal bloom monitoring and water quality assessment

  • βš™οΈ SAR Orbit Control: Precise control over Sentinel-1 ascending/descending orbits for geometric consistency

  • 🎯 40+ Specialized Indices: Comprehensive coverage with intelligent sensor-index validation

  • πŸ“Š Professional Architecture: Clean, extensible design with enhanced error handling and documentation

New Sentinel-3 Indices#

  • OCI - OLCI Chlorophyll Index (optimized for S3)

  • TSI - Trophic State Index (water quality assessment)

  • CDOM - Colored Dissolved Organic Matter Index

  • Turbidity - Water Turbidity Index (sediment monitoring)

  • SPM - Suspended Particulate Matter Index

  • KD490 - Diffuse Attenuation Coefficient at 490nm

  • Floating Algae - Floating Algae Index (bloom detection)

  • Red Edge Position - OLCI-optimized red edge position

  • Fluorescence Height - Chlorophyll fluorescence detection

  • Water Leaving Reflectance - Aquatic reflectance analysis

New SAR Indices#

  • RFDI - Radar Forest Degradation Index (deforestation monitoring)

  • VSDI - Vegetation Scattering Diversity Index (structural diversity)

Enhanced Features#

  • Intelligent Validation: Smart index-sensor compatibility checking prevents invalid combinations

  • Orbit Parameter: Fine control over Sentinel-1 orbit selection (BOTH/ASCENDING/DESCENDING)

  • Advanced Use Cases: Support for pseudo-invariant area radiometric normalization workflows

Changed#

  • Sentinel-2 to Surface Reflectance: Upgraded from TOA to Surface Reflectance for better scientific quality

  • Simplified Architecture: Removed unnecessary complexity while maintaining full functionality

  • Enhanced Documentation: Professional-grade docstrings and examples

Technical Improvements#

  • Modular sensor setup with clean separation of concerns

  • Comprehensive sensor-index mapping and validation

  • Enhanced error messages for better user experience

  • Support for advanced radiometric normalization workflows


[0.3.0] - 2025-07-17#

Added#

  • New SAR Indices: RVI (Radar Vegetation Index), VV/VH ratio, VH, VV, DPSVI for Sentinel-1

  • Flexible Percentiles: Support for any percentile value (1-99) instead of fixed 90/95

  • Enhanced Sentinel-1: VV+VH dual polarization with speckle filtering

  • Robust ROI Handling: Support for drawn features, lists of features, and improved geometry conversion

  • Incomplete Year Support: Automatic detection and processing of available periods for current/incomplete years

  • Enhanced Dependencies: Added pycrs and deims as core dependencies (now available in conda)

  • Example Notebooks: Comprehensive examples in examples_notebooks/ folder

Fixed#

  • ROI conversion for drawn geometries and feature lists from geemap

  • Speckle filter now preserves temporal properties (system:time_start)

  • Band naming consistency for SAR indices

  • Error handling for missing data periods

  • Dependency issues with pycrs and deims

Improved#

  • More robust error handling throughout the library

  • Better documentation and examples

  • Enhanced support for agricultural monitoring workflows

  • Simplified installation process

[0.2.0] - 2025-01-27#

Added#

  • Dynamic period generation: Support for any number of temporal periods (4, 6, 8, 12, 24, 52, or any custom number).

  • Flexible temporal analysis: Easy configuration from traditional 4 seasons to 52 weekly periods or any custom division.

  • Enhanced extensibility: Adding new satellites and datasets is now trivial with the unified architecture.

Changed#

  • Major code refactoring: Eliminated over 90% of code duplication by replacing 40+ individual period functions with a single dynamic system.

  • Improved maintainability: Reduced codebase from ~3,000 lines to ~400 lines while maintaining all functionality.

  • Enhanced performance: Streamlined period generation and composite creation.

Technical Details#

  • Replaced hardcoded period definitions with dynamic _generate_periods() method.

  • Consolidated all get_winter(), get_january(), get_p1() through get_p24() functions into a single get_period_composite() method.

  • Maintained full backward compatibility - all existing code works without changes.

  • Added comprehensive leap year handling to prevent date-related errors.

Breaking Changes#

  • None - this release maintains 100% backward compatibility.


[0.1.5] - 2025-05-26#

Fixed#

  • Fixing bug with MNDWI index.


[0.1.4] - 2025-05-25#

Fixed#

  • Nothing really changes, just a f* problem with release version management.


[0.1.3] - 2025-05-25#

Fixed#

  • Nothing really changes, just a f* problem with release version management.


[0.1.2] - 2025-05-25#

Added#

  • Complete rework and translation of the README into Markdown format.

  • Included new seasonal/statistical methods and updated docstrings in English.

  • Added support for region input via Sentinel-2 tiles and Landsat path/row.

  • Added rich ROI input documentation with tabular summary.

  • Added deims dependency as optional to avoid conda forge problems

Changed#

  • Clarified the purpose of the library as a broader seasonal analysis tool, not just for GIF generation.

  • Cleaned and validated setup.cfg and pyproject.toml.

  • Added extra requirements group for deims.


[0.1.1] - 2025-05-21#

Fixed#

  • Fixed rendering issue in README.rst that caused PyPI upload failure.

  • Rebuilt and republished the package with correct long description format.


[0.1.0] - 2025-05-21#

Added#

  • Compatibility with Conda packaging and conda-forge ecosystem.

  • Included MANIFEST.in to ensure LICENSE and README.rst are bundled in source distribution.

  • Improved README.rst formatting to comply with PyPI rendering rules.

Changed#

  • Switched versioning to semantic 0.x.y style for future compatibility.

  • Cleaned and validated metadata to allow upload to both PyPI and Conda Forge.

Note#

  • This is a technical release β€” no changes to the core functionality.


[0.0.9] - 2025-05-20#

Changed#

  • Version bump to align setup.cfg, PyPI and GitHub release.

  • No functional changes from version 0.0.7.


[0.0.7] - 2025-05-20#

Added#

  • New method get_ndmi() to compute the Normalized Difference Moisture Index (NDMI).

  • New (old) method get_gif() to download a gif for the selected index/bands.

  • Package structure modernized:

    • Added setup.cfg and pyproject.toml (PEP 517/518 compliant).

    • Optional removal of legacy setup.py.

  • Updated dependencies:

    • geemap pinned to version 0.29.5.

    • numpy constrained to <2.0 for compatibility.

Fixed#

  • Compatibility issues with recent versions of geemap, xarray, and numpy.

  • Resolved import error caused by the removal of np.unicode_ in NumPy 2.0.


[0.0.6] - 2023-03-10#

Added#

  • Initial public release of the ndvi2gif package.

  • Generate seasonal composites and extract statistical summaries from several remote sensing index using Google Earth Engine and geemap.

  • Export to animated GIF and GeoTIFF format.