API Reference

Contents

API Reference#

This page documents the public API of ndvi2gif. It is generated directly from the source-code docstrings, so it always matches the installed version of the package.

The library exposes seven main classes plus a couple of helper functions:

Object

Module

Purpose

NdviSeasonality

ndvi2gif.ndvi2gif

Temporal compositing, indices, ROI handling, export and GIFs

S1ARDProcessor

ndvi2gif.s1_ard

Sentinel-1 Analysis Ready Data preprocessing

TimeSeriesAnalyzer

ndvi2gif.timeseries

Point/region time series, trends and phenology

SpatialTrendAnalyzer

ndvi2gif.timeseries

Per-pixel trend rasters (server-side)

SpatialPhenologyAnalyzer

ndvi2gif.timeseries

Per-pixel phenology rasters (server-side)

LandCoverClassifier

ndvi2gif.clasification

Supervised/unsupervised land cover classification

HydroperiodAnalyzer

ndvi2gif.hydroperiod

Surface water / flooding metrics

Note

All classes and helper functions can be imported directly from the top-level package, e.g. from ndvi2gif import NdviSeasonality, HydroperiodAnalyzer.

NdviSeasonality#

class ndvi2gif.NdviSeasonality(roi=None, periods=4, start_year=2016, end_year=2020, sat='S2', key='max', index='ndvi', percentile=90, orbit='BOTH', normalize_sar=False, use_sar_ard=True, sar_speckle_filter='REFINED_LEE', sar_terrain_correction=True, sar_terrain_model='VOLUME', cloud_filter=True, max_cloud_cover=20, scl_mask=True)#

Bases: object

Generate remote sensing index seasonal composition GIFs and images.

Comprehensive framework for creating temporal composites from multiple satellite data sources. Supports 40+ spectral and radar indices with configurable temporal periods and statistical reducers.

Parameters:
  • roi (ee.Geometry, str, list, or None, optional) –

    Region of interest specification:

    • None : Default region (Andalusia, Spain)

    • ee.Geometry : Direct Earth Engine geometry

    • strPath or special format
      • '*.shp' : Shapefile path

      • '*.geojson' : GeoJSON file path

      • 'deimsid/XXXXX' : DEIMS.org site ID

      • 'wrs:path,row' : Landsat WRS-2 tile (e.g., ‘wrs:200,32’)

      • 's2:XXXXX' : Sentinel-2 MGRS tile (e.g., ‘s2:30TXN’)

    • list : Feature collection from Map.draw_features

  • periods (int, optional) –

    Number of temporal periods per year:

    • 4 : Seasonal (winter, spring, summer, autumn)

    • 12 : Monthly (january through december)

    • 24 : Bi-monthly (~15 days each, p1 through p24)

    • Other : Custom equal division (p1 through pN)

    Default is 4.

  • start_year (int, optional) – Starting year for analysis (inclusive). Must be within satellite data availability. Default is 2016.

  • end_year (int, optional) – Ending year for analysis (inclusive). Analysis includes years from start_year to end_year. Default is 2020.

  • sat ({'S2', 'S1', 'Landsat', 'MODIS', 'S3'}, optional) –

    Satellite sensor selection:

    • 'S2' : Sentinel-2 MSI (optical, 10-20m, 2015-present)

    • 'S1' : Sentinel-1 SAR (radar, 10m, 2014-present)

    • 'Landsat' : Merged L4-5-7-8-9 (optical, 30m, 1982-present)

    • 'MODIS' : Terra/Aqua (optical, 500m, 2000-present)

    • 'S3' : Sentinel-3 OLCI (ocean/land, 300m, 2016-present)

    Default is ‘S2’.

  • key ({'max', 'median', 'mean', 'sum', 'percentile'}, optional) –

    Statistical reducer for temporal aggregation:

    • 'max' : Maximum value (vegetation peak detection)

    • 'median' : Median value (robust to outliers)

    • 'mean' : Mean value (smooth temporal profiles)

    • 'sum' : Total sum (ideal for precipitation, accumulation)

    • 'percentile' : Custom percentile (set with percentile param)

    Default is ‘max’.

  • index (str, optional) –

    Spectral or radar index to compute. Available indices depend on satellite. See get_available_indices() for full list. Common indices:

    • Vegetation: 'ndvi', 'evi', 'savi', 'gndvi'

    • Water: 'ndwi', 'mndwi', 'awei'

    • Burn/Fire: 'nbr', 'nbri'

    • SAR: 'vh', 'vv', 'rvi', 'vv_vh_ratio'

    Default is ‘ndvi’.

  • percentile (int, optional) –

    Percentile value when key=’percentile’. Range: 0-100. Common values:

    • 10-25: Lower percentiles (minimum-like)

    • 50: Median equivalent

    • 75-95: Upper percentiles (maximum-like)

    Default is 90.

  • orbit ({'BOTH', 'ASCENDING', 'DESCENDING'}, optional) –

    Sentinel-1 orbit direction (only for sat=’S1’):

    • 'BOTH' : All orbits (maximum temporal coverage)

    • 'ASCENDING' : Single orbit (geometric consistency)

    • 'DESCENDING' : Single orbit (geometric consistency)

    Default is ‘BOTH’.

  • normalize_sar (bool, optional) – If True, applies Z-score normalization to SAR indices for better comparability with optical indices. Only applies when sat=’S1’. Default is False.

  • use_sar_ard (bool, optional) – If True, applies advanced SAR preprocessing (ARD pipeline) including terrain correction and sophisticated speckle filtering. Recommended for mountainous areas. Default is True.

  • sar_speckle_filter (str or None, optional) –

    Speckle filter algorithm for SAR (when use_sar_ard=True):

    • 'REFINED_LEE' : Refined Lee with edge preservation

    • 'LEE' : Standard Lee filter

    • 'GAMMA_MAP' : Gamma Maximum A Posteriori

    • 'LEE_SIGMA' : Lee Sigma filter

    • 'BOXCAR' : Simple mean filter

    • None : No speckle filtering

    Default is ‘REFINED_LEE’.

  • sar_terrain_correction (bool, optional) – Enable radiometric terrain correction for SAR data. Essential for mountainous regions. Default is True.

  • sar_terrain_model ({'VOLUME', 'SURFACE'}, optional) –

    Scattering model for terrain correction:

    • 'VOLUME' : Volume scattering (vegetation, crops)

    • 'SURFACE' : Surface scattering (bare soil, water)

    Default is ‘VOLUME’.

roi#

Processed region of interest geometry

Type:

ee.Geometry

periods#

Number of temporal periods per year

Type:

int

start_year#

First year of analysis

Type:

int

end_year#

Last year of analysis (inclusive)

Type:

int

sat#

Selected satellite sensor

Type:

str

index#

Selected spectral/radar index

Type:

str

key#

Statistical reducer method

Type:

str

percentile#

Percentile value for percentile reducer

Type:

int

period_dates#

Date ranges for each period [[start, end], …]

Type:

list of list

period_names#

Names for each temporal period

Type:

list of str

ndvi_col#

Configured satellite image collection

Type:

ee.ImageCollection

imagelist#

Processed composite images

Type:

list of ee.Image

Examples

Basic seasonal NDVI analysis:

>>> processor = NdviSeasonality(
...     roi='study_area.shp',
...     periods=4,
...     start_year=2020,
...     end_year=2023,
...     sat='S2',
...     index='ndvi'
... )
>>> processor.get_gif('seasonal_ndvi.gif')

Monthly SAR analysis with percentile:

>>> sar_processor = NdviSeasonality(
...     periods=12,
...     sat='S1',
...     index='vh',
...     key='percentile',
...     percentile=90,
...     orbit='DESCENDING'
... )
>>> collection = sar_processor.get_year_composite()

Using DEIMS site with custom periods:

>>> deims_processor = NdviSeasonality(
...     roi='deimsid/11696159-444f-4e06-b537-d4c5c0a4e97d',
...     periods=8,  # 8 periods per year
...     sat='MODIS',
...     index='evi'
... )
Raises:
  • ValueError – If satellite not supported, index not available for satellite, orbit parameter invalid, or ROI cannot be processed.

  • ImportError – If required dependencies missing (e.g., deims package).

See also

get_available_indices

Query available indices for satellites

get_year_composite

Generate temporal composite images

get_gif

Create animated visualization

get_export

Export composites to GeoTIFF files

Notes

The class automatically validates index-satellite compatibility during initialization. Default ROI covers part of Andalusia, Spain for testing. Temporal periods are generated dynamically to support flexible analysis.

References

export_to_asset(image, asset_id: str, *, description: str | None = None, region=None, scale: int | None = None, crs: str | None = None, crs_transform: list | None = None, pyramiding_policy: dict | None = None, max_pixels: int = 10000000000000, overwrite: bool = False, clip_region: bool = True)#

Export an ee.Image to an Earth Engine Asset (batch task).

Parameters:
  • image (ee.Image) – Earth Engine image to export.

  • asset_id (str) – Full asset path, e.g., “users/yourname/ndvi2gif/landcover_2022”.

  • description (str, optional) – Task name. If None, a name is derived from asset_id.

  • region (ee.Geometry, optional) – Export region. If None, uses self.roi.

  • scale (int, optional) – Pixel resolution in meters. If None, inferred from the sensor via _default_scale_for_sat().

  • crs (str, optional) – Target projection. If None, uses the image’s default.

  • crs_transform (list, optional) – Affine transform (6 or 9 numbers) instead of scale. Mutually exclusive with scale.

  • pyramiding_policy (dict, optional) – Dict mapping band name to policy (e.g., {“class”: “mode”}).

  • max_pixels (int, optional) – Maximum number of pixels allowed by Earth Engine. Default 1e13.

  • overwrite (bool, optional) – If True, tries to delete any existing asset with the same ID first.

  • clip_region (bool, optional) – If True, the image is clipped to region (or self.roi) before export.

Returns:

The started Earth Engine export task.

Return type:

ee.batch.Task

export_to_drive(image, description: str, *, region=None, scale: int | None = None, crs: str = 'EPSG:4326', folder: str | None = None, file_format: str = 'GeoTIFF', format_options: dict | None = None, max_pixels: int = 10000000000000, file_dimensions: int | None = None, clip_region: bool = True)#

Export an ee.Image to Google Drive as a GeoTIFF (batch task).

Parameters:
  • image (ee.Image) – Earth Engine image to export (e.g., a classified map or a composite).

  • description (str) – Export task name shown in the Earth Engine Tasks panel.

  • region (ee.Geometry, optional) – Export region. If None, uses self.roi.

  • scale (int, optional) – Pixel resolution in meters. If None, inferred from the sensor via _default_scale_for_sat().

  • crs (str, optional) – Target projection (e.g., "EPSG:4326"). Default is WGS84.

  • folder (str, optional) – Google Drive folder name. If None, uses the Drive root.

  • file_format (str, optional) – Output format (e.g., "GeoTIFF"). Default "GeoTIFF".

  • format_options (dict, optional) – Additional format options for the exporter (e.g., compression). Example: {"cloudOptimized": True, "compression": "LZW"}.

  • max_pixels (int, optional) – Maximum number of pixels allowed by Earth Engine. Default 1e13.

  • file_dimensions (int, optional) – Maximum pixel dimension per side for each output tile. If provided, large exports are split into multiple files (e.g., 8192 or 10000).

  • clip_region (bool, optional) – If True, image is clipped to region before exporting.

Returns:

The started Earth Engine export task.

Return type:

ee.batch.Task

Raises:
  • ValueError – If image is not provided.

  • ee.EEException – If Earth Engine fails to create the export task.

Notes

  • This is a batch export: monitor progress in the Earth Engine Tasks panel.

  • Use clip_region=True and/or file_dimensions to keep file sizes manageable.

  • For large regions, consider compression via format_options.

export_with_fishnet(image, name_prefix='composite', scale=10, crs='EPSG:4326')#

Export large images using a tiled fishnet approach to overcome memory limitations.

Divides the ROI into regular grid tiles and exports each tile separately. Useful for very large spatial extents that exceed Earth Engine’s single-image export limits.

Parameters:
  • image (ee.Image) – Earth Engine image to export (typically from get_year_composite()).

  • name_prefix (str, optional) – Prefix for output filenames. Files named as ‘{prefix}_tile_{id}.tif’. Default is ‘composite’.

  • scale (int, optional) – Output pixel resolution in meters. Default is 10.

  • crs (str, optional) – Coordinate reference system. Default is ‘EPSG:4326’.

Notes

Tile size: 50km × 50km for scale ≥ 30m, 25km × 25km for finer scales. Only exports tiles that intersect with the ROI geometry.

References

Adapted from Earth Engine large-area export strategies.

get_all_available_indices()#

Get all available indices organized by satellite sensor.

Returns a comprehensive dictionary mapping each supported satellite to its available spectral or radar indices. This method provides a complete overview of the library’s capabilities across all supported sensors.

Returns:

Dictionary with satellite names as keys and sorted lists of available indices as values. Structure:

{'satellite_name': ['index1', 'index2', ...], ...}

Return type:

dict

Examples

>>> processor = NdviSeasonality()
>>> all_indices = processor.get_all_available_indices()
>>> print(all_indices.keys())
dict_keys(['S2', 'Landsat', 'MODIS', 'S1', 'S3'])
>>> # Check capabilities of each sensor
>>> for sensor, indices in all_indices.items():
...     print(f"{sensor}: {len(indices)} indices")
S2: 29 indices      # Most comprehensive (basic + Red Edge)
Landsat: 20 indices # Basic optical only
MODIS: 20 indices   # Basic optical only
S1: 7 indices       # SAR only
S3: 30 indices      # Basic optical + ocean/coastal
>>> # Find common indices across optical sensors
>>> optical_sensors = ['S2', 'Landsat', 'MODIS']
>>> common_indices = set(all_indices[optical_sensors[0]])
>>> for sensor in optical_sensors[1:]:
...     common_indices &= set(all_indices[sensor])
>>> print(f"Common optical indices: {len(common_indices)}")
Common optical indices: 20
>>> # Check sensor-specific capabilities
>>> s2_only = set(all_indices['S2']) - set(all_indices['Landsat'])
>>> print(f"S2-only indices: {sorted(s2_only)}")
S2-only indices: ['cire', 'ireci', 'mcari', 'mtci', 'ndci', 'ndre', 'psri', 'reip', 's2rep']
>>> # Validate index availability before processing
>>> target_index = 'ndre'
>>> compatible_sensors = [sensor for sensor, indices in all_indices.items()
...                      if target_index in indices]
>>> print(f"'{target_index}' available on: {compatible_sensors}")
'ndre' available on: ['S2']

Notes

Sensor Capabilities Summary:

  • Sentinel-2 (S2): Most versatile optical sensor with Red Edge bands enabling advanced vegetation analysis and chlorophyll estimation

  • Landsat: Long-term optical observations (1982-present) with consistent band configuration across missions, ideal for time series analysis

  • MODIS: Global daily coverage at coarser resolution, excellent for large-scale monitoring and climate studies

  • Sentinel-1 (S1): All-weather SAR observations, unique for detecting structural changes, crop monitoring, and flood mapping

  • Sentinel-3 (S3): Specialized ocean and coastal monitoring with many spectral bands optimized for water quality assessment

This method is particularly useful for:

  • Sensor capability comparison

  • Multi-sensor analysis planning

  • Index availability validation

  • Documentation and tutorial purposes

See also

get_available_indices

Get indices for a specific satellite

__init__

Where sensor-index mappings are defined

get_available_indices(satellite=None)#

Get list of available spectral/radar indices for a specific satellite.

Parameters:

satellite (str or None, optional) – Satellite sensor: ‘S2’, ‘S1’, ‘Landsat’, ‘MODIS’, ‘S3’. If None, uses current satellite (self.sat).

Returns:

Sorted list of available index names.

Return type:

list of str

Examples

>>> processor = NdviSeasonality(sat='S2')
>>> indices = processor.get_available_indices()
>>> print(len(indices))  # S2 has most indices 29
>>> # Check for different satellite
>>> landsat_indices = processor.get_available_indices('Landsat')

See also

get_all_available_indices

Get indices for all satellites

get_avi(image, L=0.428)#

Advanced Vegetation Index - Non-linear vegetation index for dense vegetation.

References

Bannari, A., Asalhi, H., Teillet, P.M. (2002). Transformed difference vegetation index (TDVI) for vegetation cover mapping. IEEE International Geoscience and Remote Sensing Symposium, 5, 3053-3055.

get_awei(image)#

Automated Water Extraction Index - Water detection with shadow consideration.

References

Feyisa, G.L., Meilby, H., Fensholt, R., Proud, S.R. (2014). Automated Water Extraction Index: A new technique for surface water mapping using Landsat imagery. Remote Sensing of Environment, 140, 23-35.

get_aweinsh(image)#

Automated Water Extraction Index (no shadow) - Water detection without shadow pixels.

References

Feyisa, G.L., Meilby, H., Fensholt, R., Proud, S.R. (2014). Automated Water Extraction Index: A new technique for surface water mapping using Landsat imagery. Remote Sensing of Environment, 140, 23-35.

get_cdom(image)#

Colored Dissolved Organic Matter Index - CDOM absorption assessment in water bodies.

References

Mannino, A., Russ, M.E., Hooker, S.B. (2008). Algorithm development and validation for satellite‐derived distributions of DOC and CDOM in the U.S. Middle Atlantic Bight. Journal of Geophysical Research: Oceans, 113(C7), C07051.

get_chirps_precipitation(image)#

Daily precipitation from CHIRPS dataset.

Climate Hazards Group InfraRed Precipitation with Station data (CHIRPS) is a quasi-global rainfall dataset combining satellite imagery with in-situ station data.

Units: millimeters per day (mm/d) Temporal resolution: Daily (1981-present) Spatial resolution: ~5.5 km (0.05°) Coverage: 50°S to 50°N latitude

Use with key=’sum’ for monthly/seasonal precipitation totals. Use with key=’mean’ for average daily precipitation rates.

References

Funk, C., Peterson, P., Landsfeld, M. et al. (2015). The climate hazards infrared precipitation with stations—a new environmental record for monitoring extremes. Scientific Data, 2, 150066. https://doi.org/10.1038/sdata.2015.66

UCSB Climate Hazards Center https://developers.google.com/earth-engine/datasets/catalog/UCSB-CHG_CHIRPS_DAILY

get_cig(image)#

Chlorophyll Index Green - Chlorophyll content estimation using green band.

References

Gitelson, A.A., Gritz, Y., Merzlyak, M.N. (2003). Relationships between leaf chlorophyll content and spectral reflectance and algorithms for non-destructive chlorophyll assessment in higher plant leaves. Journal of Plant Physiology, 160(3), 271-282.

get_cire(image)#

Chlorophyll Index Red Edge - Chlorophyll content estimation using red-edge band.

References

Gitelson, A.A., Gritz, Y., Merzlyak, M.N. (2003). Relationships between leaf chlorophyll content and spectral reflectance and algorithms for non-destructive chlorophyll assessment in higher plant leaves. Journal of Plant Physiology, 160(3), 271-282.

get_cri1(image)#

Carotenoid Reflectance Index 1 - Carotenoid pigment detection.

References

Gitelson, A.A., Zur, Y., Chivkunova, O.B., Merzlyak, M.N. (2002). Assessing carotenoid content in plant leaves with reflectance spectroscopy. Photochemistry and Photobiology, 75(3), 272-281.

get_cri2(image)#

Carotenoid Reflectance Index 2 - Alternative carotenoid assessment.

References

Gitelson, A.A., Zur, Y., Chivkunova, O.B., Merzlyak, M.N. (2002). Assessing carotenoid content in plant leaves with reflectance spectroscopy. Photochemistry and Photobiology, 75(3), 272-281.

get_dpsvi(image, normalize=False)#

Dual-pol SAR Vegetation Index - Optimized for dense vegetation canopy analysis.

Parameters:
  • image (ee.Image) – Input SAR image with VV and VH bands

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Mandal, D., Kumar, V., Ratha, D., Dey, S., Bhattacharya, A., Lopez‐Sanchez, J.M., … Rao, Y.S. (2020). Dual polarimetric radar vegetation index for crop growth monitoring using sentinel‐1 SAR data. Remote Sensing of Environment, 247, 111954.

get_era5_dewpoint_temperature_2m(image)#

Dewpoint temperature at 2 meters height.

Temperature at which air becomes saturated with water vapor. Units: Kelvin

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_dewpoint_temperature_2m_celsius(image)#

Dewpoint temperature at 2 meters height in Celsius.

Temperature at which air becomes saturated with water vapor. Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_dewpoint_temperature_2m_max(image)#

Daily maximum dewpoint temperature at 2 meters height.

Units: Kelvin (K) For Celsius use dewpoint_temperature_2m_max_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_dewpoint_temperature_2m_max_celsius(image)#

Daily maximum dewpoint temperature at 2 meters height in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_dewpoint_temperature_2m_min(image)#

Daily minimum dewpoint temperature at 2 meters height.

Units: Kelvin (K) For Celsius use dewpoint_temperature_2m_min_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_dewpoint_temperature_2m_min_celsius(image)#

Daily minimum dewpoint temperature at 2 meters height in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_potential_evaporation_sum(image)#

Potential evapotranspiration.

Maximum evaporation that would occur with unlimited water availability. Units: meters Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_potential_evaporation_sum_lm2(image)#

Potential evapotranspiration in liters per square meter (L/m²).

Maximum evaporation with unlimited water availability. Converted from meters to L/m² (m × 1000).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_runoff_sum(image)#

Total runoff (surface + sub-surface).

Units: meters Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_runoff_sum_lm2(image)#

Total runoff (surface + sub-surface) in liters per square meter (L/m²).

Converted from meters to L/m² (m × 1000).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_skin_temperature(image)#

Skin temperature - Earth surface temperature.

Temperature of the Earth’s surface (land or water). Units: Kelvin

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_skin_temperature_celsius(image)#

Skin temperature (Earth surface) in Celsius.

Temperature of the Earth’s surface (land or water). Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_skin_temperature_max(image)#

Daily maximum skin temperature (Earth surface).

Units: Kelvin (K) For Celsius use skin_temperature_max_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_skin_temperature_max_celsius(image)#

Daily maximum skin temperature (Earth surface) in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_skin_temperature_min(image)#

Daily minimum skin temperature (Earth surface).

Units: Kelvin (K) For Celsius use skin_temperature_min_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_skin_temperature_min_celsius(image)#

Daily minimum skin temperature (Earth surface) in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_snow_depth_water_equivalent(image)#

Snow depth in water equivalent.

Amount of water that would result from melting the snow. Units: meters of water equivalent

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_snowfall_sum(image)#

Snowfall amount.

Units: meters of water equivalent Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_snowfall_sum_lm2(image)#

Snowfall amount in liters per square meter (L/m²).

Converted from meters of water equivalent to L/m² (m × 1000).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_soil_temperature_level_1(image)#

Soil temperature at level 1 (0-7 cm depth).

Temperature in the topmost soil layer. Units: Kelvin

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_soil_temperature_level_1_celsius(image)#

Soil temperature at level 1 (0-7 cm depth) in Celsius.

Temperature in the topmost soil layer. Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_soil_temperature_level_1_max(image)#

Daily maximum soil temperature at level 1 (0-7 cm depth).

Units: Kelvin (K) For Celsius use soil_temperature_level_1_max_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_soil_temperature_level_1_max_celsius(image)#

Daily maximum soil temperature at level 1 (0-7 cm depth) in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_soil_temperature_level_1_min(image)#

Daily minimum soil temperature at level 1 (0-7 cm depth).

Units: Kelvin (K) For Celsius use soil_temperature_level_1_min_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_soil_temperature_level_1_min_celsius(image)#

Daily minimum soil temperature at level 1 (0-7 cm depth) in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_surface_latent_heat_flux_sum(image)#

Surface latent heat flux.

Energy used for evaporation/condensation. Units: J/m² Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_surface_net_solar_radiation_sum(image)#

Net solar radiation at the surface.

Incoming minus reflected solar radiation. Units: J/m² Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_surface_pressure(image)#

Atmospheric pressure at the surface.

Units: Pascals (Pa)

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_surface_runoff_sum(image)#

Surface runoff only.

Water that flows over the land surface. Units: meters Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_surface_runoff_sum_lm2(image)#

Surface runoff in liters per square meter (L/m²).

Water that flows over the land surface. Converted from meters to L/m² (m × 1000).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_surface_solar_radiation_downwards_sum(image)#

Downward solar radiation at the surface.

Total incoming shortwave radiation. Units: J/m² Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_temperature_2m(image)#

Air temperature at 2 meters height.

Returns temperature in Kelvin. For Celsius: subtract 273.15

References

ERA5-Land: ECMWF Climate Reanalysis https://developers.google.com/earth-engine/datasets/catalog/ECMWF_ERA5_LAND_DAILY_AGGR

get_era5_temperature_2m_celsius(image)#

Air temperature at 2 meters height in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis https://developers.google.com/earth-engine/datasets/catalog/ECMWF_ERA5_LAND_DAILY_AGGR

get_era5_temperature_2m_max(image)#

Daily maximum air temperature at 2 meters height.

Units: Kelvin (K) For Celsius use temperature_2m_max_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_temperature_2m_max_celsius(image)#

Daily maximum air temperature at 2 meters height in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_temperature_2m_min(image)#

Daily minimum air temperature at 2 meters height.

Units: Kelvin (K) For Celsius use temperature_2m_min_celsius

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_temperature_2m_min_celsius(image)#

Daily minimum air temperature at 2 meters height in Celsius.

Converted from Kelvin to Celsius (K - 273.15).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_total_evaporation_sum(image)#

Total evapotranspiration from land surface.

Includes evaporation from soil, vegetation, and water bodies. Units: meters of water equivalent Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_total_evaporation_sum_lm2(image)#

Total evapotranspiration in liters per square meter (L/m²).

Includes evaporation from soil, vegetation, and water bodies. Converted from meters to L/m² (m × 1000).

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_total_precipitation_sum(image)#

Total daily precipitation (rain + snow combined).

Units: meters of water equivalent Note: Flow band - accumulated daily sum

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_total_precipitation_sum_lm2(image)#

Total daily precipitation in liters per square meter (L/m²).

Rain + snow combined. Converted from meters to L/m² (m × 1000). Note: 1 mm = 1 L/m²

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_u_component_of_wind_10m(image)#

Eastward wind component at 10 meters height.

Positive values indicate wind from west to east. Units: m/s

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_v_component_of_wind_10m(image)#

Northward wind component at 10 meters height.

Positive values indicate wind from south to north. Units: m/s

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_volumetric_soil_water_layer_1(image)#

Volumetric soil water content at layer 1 (0-7 cm depth).

Volume fraction of water in soil (0-1). Units: m³/m³

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_volumetric_soil_water_layer_2(image)#

Volumetric soil water content at layer 2 (7-28 cm depth).

Volume fraction of water in soil (0-1). Units: m³/m³

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_volumetric_soil_water_layer_3(image)#

Volumetric soil water content at layer 3 (28-100 cm depth).

Volume fraction of water in soil (0-1). Units: m³/m³

References

ERA5-Land: ECMWF Climate Reanalysis

get_era5_volumetric_soil_water_layer_4(image)#

Volumetric soil water content at layer 4 (100-289 cm depth).

Volume fraction of water in soil (0-1). Units: m³/m³

References

ERA5-Land: ECMWF Climate Reanalysis

get_evi(image)#

Enhanced Vegetation Index - Improved vegetation monitoring with reduced atmospheric influence.

References

Huete, A., Didan, K., Miura, T., Rodriguez, E.P., Gao, X., Ferreira, L.G. (2002). Overview of the radiometric and biophysical performance of the MODIS vegetation indices. Remote Sensing of Environment, 83(1-2), 195-213.

get_export(crs='EPSG:4326', scale=10)#

Export all temporal composite images to individual GeoTIFF files with descriptive names.

Processes the complete time series analysis and exports each year’s composite as a separate multi-band GeoTIFF file. Filenames are automatically generated using a descriptive pattern that includes the index, statistical method, and year.

This method orchestrates the entire workflow: generates temporal composites, creates meaningful filenames, and exports all results in a single operation.

Parameters:
  • crs (str, optional) – Coordinate Reference System for output rasters in EPSG format. Applied to all exported files. Common options: - ‘EPSG:4326’: WGS84 Geographic (lat/lon) - universal compatibility - ‘EPSG:3857’: Web Mercator - web mapping applications - ‘EPSG:32633’: UTM Zone 33N - metric measurements (example) Default is ‘EPSG:4326’.

  • scale (int or float, optional) – Output pixel resolution in meters for all exports. Should be appropriate for the satellite sensor: - Sentinel-2: 10-20m (native resolution) - Landsat: 30m (native resolution) - MODIS: 500m (native resolution) - Sentinel-1: 10m (native resolution) - Sentinel-3: 300m (native resolution) Default is 10.

Returns:

Files are saved to disk with progress information printed to console.

Return type:

None

Notes

Automatic Filename Generation: Filenames follow the pattern: {sat}_{index}_{statistic}_{year}.tif

Examples: - ‘ndvi_max_2020.tif’ (NDVI with maximum reducer) - ‘evi_median_2021.tif’ (EVI with median reducer) - ‘vh_p90_2022.tif’ (VH SAR with 90th percentile) - ‘rvi_mean_2019.tif’ (RVI SAR with mean reducer)

Statistical Method Naming: - ‘max’: Maximum value reducer - ‘median’: Median value reducer - ‘mean’: Mean value reducer - ‘p{N}’: Percentile reducer (e.g., ‘p90’ for 90th percentile)

Multi-band Structure: Each exported file contains multiple bands representing temporal periods: - 4 periods: [‘winter’, ‘spring’, ‘summer’, ‘autumn’] - 12 periods: [‘january’, ‘february’, …, ‘december’] - 24 periods: [‘p1’, ‘p2’, …, ‘p24’] - Custom: [‘p1’, ‘p2’, …, ‘pN’]

Processing Workflow: 1. Clear previous results and initialize processing 2. Generate temporal composites using get_year_composite() 3. For each successful year: a. Generate descriptive filename b. Export multi-band composite to GeoTIFF c. Provide progress feedback 4. Report completion summary

Examples

>>> # Basic export with default settings
>>> processor = NdviSeasonality(
...     sat='S2',
...     index='ndvi',
...     start_year=2020,
...     end_year=2023,
...     key='max'
... )
>>> processor.get_export()
# Exports: ndvi_max_2020.tif, ndvi_max_2021.tif, ndvi_max_2022.tif
>>> # SAR analysis with percentile statistics
>>> sar_processor = NdviSeasonality(
...     sat='S1',
...     index='vh',
...     key='percentile',
...     percentile=90,
...     periods=12
... )
>>> sar_processor.get_export(scale=20)
# Exports: vh_p90_2020.tif, vh_p90_2021.tif, etc.
>>> # Monthly analysis with UTM projection
>>> monthly_processor = NdviSeasonality(
...     sat='Landsat',
...     index='evi',
...     periods=12,
...     key='median'
... )
>>> monthly_processor.get_export(crs='EPSG:32633', scale=30)
# Exports: evi_median_2020.tif, evi_median_2021.tif, etc.
>>> # Multi-sensor comparison workflow
>>> sensors = ['S2', 'Landsat', 'MODIS']
>>> for sat in sensors:
...     proc = NdviSeasonality(sat=sat, index='ndvi', start_year=2020, end_year=2022)
...     proc.get_export()
# Creates separate files for each sensor-year combination

Performance Notes#

Processing Time Factors: - Time range: (end_year - start_year + 1) × periods - Spatial extent: ROI area × scale resolution - Sensor complexity: SAR < Optical (due to preprocessing) - Statistical method: max ≈ median < mean < percentile

Optimization Strategies: - Use appropriate scale for sensor (avoid unnecessary upsampling) - Consider seasonal periods (4) vs monthly (12) for time vs detail trade-off - For very large areas, use export_with_fishnet() instead - Process smaller time ranges for iterative analysis

Output File Characteristics: - Format: GeoTIFF with embedded georeferencing - Compression: Default LZW compression for smaller files - Data type: Float32 for index values, preserving fractional precision - NoData handling: Masked pixels preserved from input data

raises ee.EEException:

If Earth Engine processing fails due to memory limits, timeout, authentication issues, or invalid parameters.

raises OSError:

If local file system issues occur (insufficient disk space, permission errors, invalid file paths).

raises RuntimeError:

If no valid temporal composites can be generated (e.g., no satellite data available for specified time range and region).

Warning

  • Years with insufficient data are automatically skipped with console warnings

  • Large time ranges or high-resolution analyses may approach computation limits

  • Existing files with same names will be overwritten without warning

See also

get_export_single : Export individual images with custom names get_year_composite : Generate the temporal composites that are exported export_with_fishnet : Alternative for very large spatial extents get_gif : Create animated visualizations instead of static exports

>>> # Load exported files for further analysis
>>> import rasterio
>>> with rasterio.open('ndvi_max_2020.tif') as src:
...     data = src.read()  # Shape: (bands, height, width)
...     summer_data = src.read(3)  # Read summer band specifically
>>> # Multi-temporal analysis
>>> import numpy as np
>>> years = range(2020, 2023)
>>> summer_trend = []
>>> for year in years:
...     with rasterio.open(f'ndvi_max_{year}.tif') as src:
...         summer_trend.append(src.read(3))  # Summer band
>>> trend = np.array(summer_trend)
>>> mean_summer = np.mean(trend, axis=0)
get_export_single(image, name='mycomposition.tif', crs='EPSG:4326', scale=10)#

Export a single Earth Engine image to a GeoTIFF file.

Exports a specific composite image or any Earth Engine image to the local file system as a GeoTIFF raster. This method is useful for exporting individual images, statistical summaries, or custom analyses derived from the temporal composites.

Parameters:
  • image (ee.Image) – Earth Engine image to export. Can be any single or multi-band image, including temporal composites, statistical summaries, or processed derivatives from get_year_composite().

  • name (str, optional) – Output filename including extension. Should end with ‘.tif’ for GeoTIFF format. The file will be saved in the current working directory. Default is ‘mycomposition.tif’.

  • crs (str, optional) – Coordinate Reference System for the output raster in EPSG format. Common options: - ‘EPSG:4326’: WGS84 Geographic (lat/lon) - ‘EPSG:3857’: Web Mercator - ‘EPSG:32633’: UTM Zone 33N (example) Default is ‘EPSG:4326’.

  • scale (int or float, optional) – Output pixel resolution in meters. Should match or be appropriate for the input satellite data: - Sentinel-2: 10-20m - Landsat: 30m - MODIS: 500m - Sentinel-1: 10m - Sentinel-3: 300m Default is 10.

Examples

>>> # Export a single year composite
>>> processor = NdviSeasonality(sat='S2', index='ndvi', periods=4)
>>> collection = processor.get_year_composite()
>>> single_image = collection.first()
>>> processor.get_export_single(single_image, 'ndvi_2020_seasonal.tif')
>>> # Export temporal statistics
>>> mean_composite = collection.mean()
>>> processor.get_export_single(mean_composite, 'ndvi_multiyear_mean.tif', scale=20)
>>> # Export specific band or analysis
>>> summer_only = single_image.select('summer')
>>> processor.get_export_single(summer_only, 'summer_ndvi_2020.tif')
>>> # Export with custom CRS and higher resolution
>>> processor.get_export_single(
...     image=single_image,
...     name='high_res_composite.tif',
...     crs='EPSG:32633',  # UTM projection
...     scale=10
... )
>>> # Export derived analysis
>>> seasonal_range = single_image.select('summer').subtract(single_image.select('winter'))
>>> processor.get_export_single(seasonal_range, 'seasonal_amplitude.tif')

Notes

File Output: - Files are saved to the current working directory (os.getcwd()) - GeoTIFF format with embedded CRS and geotransform information - Multi-band images preserve all bands in a single file - Pixel values maintain original data type and scaling

Performance Considerations: - Export time depends on: image size × number of bands × scale resolution - Large regions or high resolutions may approach Earth Engine limits - Consider using export_with_fishnet() for very large areas - Processing occurs on Earth Engine servers, then downloads locally

Common Use Cases: - Single image export from temporal analysis - Statistical summaries (mean, max, std) across time series - Specific band extraction for focused analysis - Custom mathematical operations on composites - Quality control and validation sample export

Raises:
  • ee.EEException – If Earth Engine encounters processing errors, authentication issues, or export limitations (memory, timeout, etc.).

  • OSError – If there are local file system issues (permissions, disk space, etc.).

  • ValueError – If parameters are invalid (unsupported CRS, negative scale, etc.).

See also

get_export

Export entire time series automatically

get_year_composite

Generate temporal composites for export

export_with_fishnet

Export large areas using tiled approach

References

Earth Engine Export Documentation: https://developers.google.com/earth-engine/guides/exporting

get_fai(image)#

Floating Algae Index (FAI) - Detection of floating algae and cyanobacterial blooms in water bodies.

Computes a NIR baseline by linear interpolation between the Red and SWIR2 bands at the NIR wavelength, then subtracts it from the observed NIR reflectance. Positive FAI values indicate floating algae or cyanobacterial surface accumulations; negative values correspond to open water.

Works with surface reflectance (SR) data. Compatible with Sentinel-2, Landsat, and MODIS. Not applicable to Sentinel-3 OLCI (no SWIR band available).

Formula#

FAI = NIR - NIR_baseline NIR_baseline = Red + (SWIR2 - Red) * (lambda_NIR - lambda_red) / (lambda_SWIR2 - lambda_red)

Sensor-specific center wavelengths (nm) and resulting interpolation factors:

Sentinel-2 MSI : lambda_NIR=835.1, lambda_red=664.5, lambda_SWIR2=2202.4 -> factor=0.1109 Landsat 8/9 OLI : lambda_NIR=864.7, lambda_red=654.6, lambda_SWIR2=2201.2 -> factor=0.1359 MODIS Terra/Aqua : lambda_NIR=858.5, lambda_red=645.0, lambda_SWIR2=2130.0 -> factor=0.1438

Note: The Landsat collection in ndvi2gif merges OLI (L8/9) and TM/ETM+ (L4-7). OLI wavelengths are used as representative values. The interpolation factor for TM/ETM+ (~0.113) differs slightly but the impact on FAI is minor.

References

Hu, C. (2009). A novel ocean color index to detect floating algae in the global oceans. Remote Sensing of Environment, 113(10), 2118-2129. https://doi.org/10.1016/j.rse.2009.05.012

get_floating_algae(image)#

Floating Algae Index - Detection of floating algae and surface algal blooms.

References

Hu, C. (2009). A novel ocean color index to detect floating algae in the global oceans. Remote Sensing of Environment, 113(10), 2118-2129.

get_fluorescence_height(image)#

Chlorophyll Fluorescence Line Height - Natural chlorophyll fluorescence detection.

References

Gower, J., King, S., Borstad, G., Brown, L. (2005). Detection of intense plankton blooms using the 709 nm band of the MERIS imaging spectrometer. International Journal of Remote Sensing, 26(9), 2005-2012.

get_gif(name='mygif.gif', bands=None)#

Create an animated GIF showing the temporal evolution of period composites.

Generates a video animation (downloaded as GIF) where each frame corresponds to one year and each RGB image uses selected period composites (e.g., winter-spring-summer). Internally calls get_year_composite() and exports the video using geemap.download_ee_video(). Optionally, an annotated version is created with year labels and a progress bar using geemap.add_text_to_gif().

Parameters:
  • name (str, optional) – Name of the output file (.gif). Saved in the current working directory. Default: 'mygif.gif'.

  • bands (list of str or None, optional) – Band names to use as [R, G, B] in the animation. Must be valid periods (e.g., 'winter', 'spring' or 'p1', 'p2'). If None, the first three period names are used (self.period_names[:3]).

Notes

  • SAR sensors (S1): a typical dB scale is applied (min=-25, max=0).

  • Optical sensors: a typical vegetation index range is applied (min=0.15, max=0.85).

  • Output video is set to dimensions=768 pixels and framesPerSecond=10 for a balance between clarity and file size.

Raises:
  • ee.EEException – If processing or export fails (memory limits, runtime errors, authentication issues).

  • ValueError – If bands does not contain exactly 3 valid periods present in self.period_names.

  • OSError – If a file system error occurs when writing the GIF locally.

See also

get_year_composite

Generates yearly composites used in the animation.

get_export

Exports static multi-band images instead of an animation.

geemap.download_ee_video

Handles Earth Engine video export.

geemap.add_text_to_gif

Adds annotations (year and progress bar).

Examples

>>> # Seasonal composite with Sentinel-2 (RGB = winter, spring, summer)
>>> NdviSeasonality(sat='S2', index='ndvi', periods=4, start_year=2020, end_year=2023).get_gif('ndvi_seasons.gif')
>>> # Monthly SAR composite (using specific months as RGB)
>>> proc = NdviSeasonality(sat='S1', index='vh', periods=12)
>>> proc.get_gif('vh_monthly.gif', bands=['march', 'june', 'september'])
get_gndvi(image)#

Green Normalized Difference Vegetation Index - Sensitive to chlorophyll content.

References

Gitelson, A.A., Kaufman, Y.J., Merzlyak, M.N. (1996). Use of a green channel in remote sensing of global vegetation from EOS-MODIS. Remote Sensing of Environment, 58(3), 289-298.

get_ireci(image)#

Inverted Red-Edge Chlorophyll Index - Highly sensitive to chlorophyll content.

References

Frampton, W.J., Dash, J., Watmough, G., Milton, E.J. (2013). Evaluating the capabilities of Sentinel-2 for quantitative estimation of biophysical variables in vegetation. ISPRS Journal of Photogrammetry and Remote Sensing, 82, 83-92.

get_kd490(image)#

Diffuse Attenuation Coefficient at 490nm - Water transparency and optical depth assessment.

References

Mueller, J.L. (2000). SeaWiFS algorithm for the diffuse attenuation coefficient K(490) using water-leaving radiances at 490 and 555 nm. SeaWiFS Postlaunch Calibration and Validation Analyses, Part 3, 11, 24-27.

get_lai(image)#

Leaf Area Index approximation - Estimate of leaf area per unit ground area.

References

Boegh, E., Soegaard, H., Broge, N., Hasager, C.B., Jensen, N.O., Schelde, K., Thomsen, A. (2002). Airborne multispectral data for quantifying leaf area index, nitrogen concentration, and photosynthetic efficiency in agriculture. Remote Sensing of Environment, 81(2-3), 179-193.

get_lst(image)#

Land Surface Temperature (LST) - Multi-sensor implementation with robust error handling Automatically detects sensor and applies appropriate scaling and conversion

Supported sensors and bands: - Landsat 8/9 (OLI/TIRS): ST_B10 (Band 10 - thermal infrared) - Landsat 7 (ETM+): ST_B6 (Band 6 - thermal infrared) - Landsat 4/5 (TM): ST_B6 (Band 6 - thermal infrared) - MODIS Terra/Aqua: LST_Day_1km (Land Surface Temperature)

Note: Sentinel-3 LST is not available in Google Earth Engine as it requires SLSTR instrument data, but only OLCI is available in GEE.

Returns temperature in Celsius degrees with quality control

get_mcari(image)#

Modified Chlorophyll Absorption Ratio Index - Chlorophyll content with reduced soil influence.

References

Daughtry, C.S.T., Walthall, C.L., Kim, M.S., de Colstoun, E.B., McMurtrey, J.E. (2000). Estimating corn leaf chlorophyll concentration from leaf and canopy reflectance. Remote Sensing of Environment, 74(2), 229-239.

get_mndwi(image)#

Modified Normalized Difference Water Index - Enhanced water detection, reduces built-up noise.

References

Xu, H. (2006). Modification of normalised difference water index (NDWI) to enhance open water features in remotely sensed imagery. International Journal of Remote Sensing, 27(14), 3025-3033.

get_msi(image)#

Moisture Stress Index - Plant water stress detection.

References

Rock, B.N., Vogelmann, J.E., Williams, D.L., Vogelmann, A.F., Hoshizaki, T. (1986). Remote detection of forest damage. BioScience, 36(7), 439-445.

get_mtci(image)#

MERIS Terrestrial Chlorophyll Index - Chlorophyll content adapted for terrestrial vegetation.

References

Dash, J., Curran, P.J. (2004). The MERIS terrestrial chlorophyll index. International Journal of Remote Sensing, 25(23), 5403-5413.

get_nbr(image)#

Normalized Burn Ratio (NBR) - Ratio Normalizado de Quemadura

Detecta áreas quemadas usando la diferencia entre NIR y SWIR2. NBR = (NIR - SWIR2) / (NIR + SWIR2)

Valores típicos: - > 0.27: Vegetación densa no quemada - 0.1 - 0.27: Vegetación moderada - -0.1 - 0.1: Área quemada reciente - < -0.1: Quemadura severa

Para detectar cambios: dNBR = NBR_prefire - NBR_postfire

Referencias#

Key, C.H., Benson, N.C. (2006). Landscape Assessment: Ground measure of severity, the Composite Burn Index. FIREMON: Fire effects monitoring and inventory framework. USDA Forest Service.

get_nbri(image)#

Normalized Burn Ratio Index - Fire damage and burn severity assessment.

References

Key, C., Benson, N. (2006). Landscape Assessment: Ground measure of severity, the Composite Burn Index; and Remote sensing of severity, the Normalized Burn Ratio. FIREMON: Fire Effects Monitoring and Inventory System, RMRS-GTR-164-CD.

get_ndbi(image)#

Normalized Difference Built-up Index (NDBI) - Índice Normalizado de Construcción

Detecta áreas urbanas y construidas usando la diferencia entre SWIR1 y NIR. NDBI = (SWIR1 - NIR) / (SWIR1 + NIR)

Valores: - > 0: Área construida (más alto = más urbano) - < 0: Vegetación/agua - 0.1 - 0.5: Área urbana típica - > 0.5: Área densamente construida

Referencias#

Zha, Y., Gao, J., Ni, S. (2003). Use of normalized difference built-up index in automatically mapping urban areas from TM imagery. International Journal of Remote Sensing, 24(3), 583-594.

get_ndci(image)#

Normalized Difference Chlorophyll Index - Optimized for cyanobacteria and chlorophyll-a detection in water.

Formula: (Red_Edge1 - Red) / (Red_Edge1 + Red) Uses Red Edge 1 (B5) and Red (B4) - optimized for Sentinel-2.

References

Mishra, S., Mishra, D.R. (2012). Normalized difference chlorophyll index: A novel model for remote estimation of chlorophyll-a concentration in turbid productive waters. Remote Sensing of Environment, 117, 394-406.

Gitelson, A.A., Dall’Olmo, G., Moses, W., Rundquist, D.C., Barrow, T., Fisher, T.R., … Holz, J. (2008). A simple semi-analytical model for remote estimation of chlorophyll-a in turbid waters: Validation. Remote Sensing of Environment, 112(9), 3582-3593.

get_ndmi(image)#

Normalized Difference Moisture Index - Vegetation water content assessment.

References

Hardisky, M.A., Klemas, V., Smart, R.M. (1983). The influence of soil salinity, growth form, and leaf moisture on the spectral radiance of Spartina alterniflora canopies. Photogrammetric Engineering and Remote Sensing, 49(1), 77-83.

get_ndre(image)#

Normalized Difference Red Edge - Sensitive to chlorophyll content variations.

References

Gitelson, A., Merzlyak, M.N. (1994). Spectral reflectance changes associated with autumn senescence of Aesculus hippocastanum L. and Acer platanoides L. leaves. Journal of Plant Physiology, 143(3), 286-292.

get_ndsi(image)#

Normalized Difference Snow Index - Snow cover detection and monitoring.

References

Dozier, J. (1989). Spectral signature of alpine snow cover from the Landsat Thematic Mapper. Remote Sensing of Environment, 28, 9-22.

get_ndti(image)#

Normalized Difference Tillage Index - Agricultural tillage and residue detection.

References

Van Deventer, A.P., Ward, A.D., Gowda, P.H., Lyon, J.G. (1997). Using thematic mapper data to identify contrasting soil plains and tillage practices. Photogrammetric Engineering and Remote Sensing, 63(1), 87-93.

get_ndvi(image)#

Normalized Difference Vegetation Index - Most widely used vegetation index.

References

Rouse, J.W., Haas, R.H., Schell, J.A., Deering, D.W. (1974). Monitoring vegetation systems in the Great Plains with ERTS. Third ERTS Symposium, NASA SP-351 I: 309-317.

get_ndwi(image)#

Normalized Difference Water Index - Water body detection and monitoring.

References

Gao, B. (1996). NDWI - A normalized difference water index for remote sensing of vegetation liquid water from space. Remote Sensing of Environment, 58(3), 257-266.

get_nmi(image)#

Normalized Multi-band Drought Index - Multi-spectral drought assessment.

References

Wang, L., Qu, J.J. (2007). NMDI: A normalized multi‐band drought index for monitoring soil and vegetation moisture with satellite remote sensing. Geophysical Research Letters, 34(20), L20405.

get_oci(image)#

OLCI Chlorophyll Index - Custom chlorophyll index using OLCI L1B radiance data.

References

Hu, C., Lee, Z., Franz, B. (2012). Chlorophyll a algorithms for oligotrophic oceans: A novel approach based on three‐band reflectance difference. Journal of Geophysical Research: Oceans, 117(C1), C01011.

get_period_composite(year, period_idx)#

Generate composite image for a specific temporal period within a year.

Creates a single composite by applying the configured statistical reducer to all satellite images within the defined temporal period. Core processing function for temporal composite generation.

Parameters:
  • year (int) – Target year for composite generation. Must be within satellite data availability range.

  • period_idx (int) – Zero-based index of temporal period within the year. Must be less than self.periods.

Returns:

Single-band composite image with the selected index values. Band name depends on reducer type.

Return type:

ee.Image

Notes

Processing workflow:

  1. Extract date range from self.period_dates[period_idx]

  2. Filter satellite collection to date range

  3. Apply index calculation (self.d[self.index])

  4. Apply statistical reducer (max/median/mean/percentile)

  5. Return composite image

The method assumes valid inputs as validation occurs during initialization. Empty images may result if no data is available.

Examples

Generate winter composite for 2020:

>>> processor = NdviSeasonality(periods=4, start_year=2020)
>>> winter_2020 = processor.get_period_composite(2020, 0)  # 0=winter

Generate July composite for monthly analysis:

>>> monthly = NdviSeasonality(periods=12, sat='S2')
>>> july_2021 = monthly.get_period_composite(2021, 6)  # 6=July (0-based)

See also

get_year_composite

Calls this method for all periods

_generate_periods

Defines period date ranges

get_pri(image)#

Photochemical Reflectance Index - Plant stress and photosynthetic efficiency.

References

Gamon, J.A., Peñuelas, J., Field, C.B. (1992). A narrow-waveband spectral index that tracks diurnal changes in photosynthetic efficiency. Remote Sensing of Environment, 41(1), 35-44.

get_psri(image)#

Plant Senescence Reflectance Index - Plant senescence and carotenoid/chlorophyll ratio.

References

Merzlyak, M.N., Gitelson, A.A., Chivkunova, O.B., Rakitin, V.Y. (1999). Non‐destructive optical detection of pigment changes during leaf senescence and fruit ripening. Physiologia Plantarum, 106(1), 135-141.

get_red_edge_position(image)#

Red Edge Position optimized for OLCI - Chlorophyll-sensitive wavelength position indicator.

References

Gower, J., King, S., Borstad, G., Brown, L. (2005). Detection of intense plankton blooms using the 709 nm band of the MERIS imaging spectrometer. International Journal of Remote Sensing, 26(9), 2005-2012.

get_reip(image)#

Red Edge Inflection Point - Wavelength position of maximum slope in red-edge region.

References

Guyot, G., Baret, F. (1988). Utilisation de la haute resolution spectrale pour suivre l’etat des couverts vegetaux. Proceedings of the 4th International Colloquium on Spectral Signatures of Objects in Remote Sensing, 279-286.

get_rfdi(image, normalize=False)#

Radar Forest Degradation Index - Forest disturbance and degradation monitoring.

Parameters:
  • image (ee.Image) – Input SAR image with VV and VH bands

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Ningthoujam, R.K., Balzter, H., Tansey, K., Feldpausch, T.R., Mitchard, E.T., Wani, A.A., Joshi, P.K. (2018). Relationships of S-1 C-band SAR backscatter with forest cover, height and aboveground biomass at multiple spatial scales across four forest types. Remote Sensing, 10(9), 1442.

get_rvi(image, normalize=False)#

Radar Vegetation Index - More robust vegetation indicator than individual polarizations.

Parameters:
  • image (ee.Image) – Input SAR image with VV and VH bands

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Kim, Y., Jackson, T., Bindlish, R., Lee, H., Hong, S. (2012). Radar vegetation index for estimating the vegetation water content of rice and soybean. IEEE Geoscience and Remote Sensing Letters, 9(4), 564-568.

get_s2rep(image)#

Sentinel-2 Red Edge Position - Simplified red-edge position estimation for Sentinel-2.

References

Frampton, W.J., Dash, J., Watmough, G., Milton, E.J. (2013). Evaluating the capabilities of Sentinel-2 for quantitative estimation of biophysical variables in vegetation. ISPRS Journal of Photogrammetry and Remote Sensing, 82, 83-92.

get_savi(image, L=0.428)#

Soil Adjusted Vegetation Index - Reduces soil background influence on vegetation indices.

References

Huete, A.R. (1988). A soil-adjusted vegetation index (SAVI). Remote Sensing of Environment, 25(3), 295-309.

get_spm(image)#

Suspended Particulate Matter Index - Quantification of suspended particles in water.

References

Binding, C.E., Bowers, D.G., Mitchelson‐Jacob, E.G. (2005). Estimating suspended sediment concentrations from ocean colour measurements in moderately turbid waters; the impact of variable particle scattering properties. Remote Sensing of Environment, 94(3), 373-383.

get_stats(image=None, geom=None, name=None, stat='MEDIAN', scale=10, to_file=False)#

Compute zonal statistics for temporal composites within specified geometries.

Automatically processes all years in the time series, computing statistics for each year separately. If a single image is provided, processes only that image.

Parameters:
  • image (ee.Image, ee.ImageCollection, or None, optional) – Input for statistical analysis. Can be: - None: Uses get_year_composite() to process entire time series (default) - ee.Image: Single image (e.g., one year composite) - ee.ImageCollection: Custom collection to process

  • geom (ee.Geometry, str, or None, optional) – Geometry defining zones for statistics. Can be: - None: Use self.roi (default) - str: Path to shapefile (.shp) or GeoJSON (.geojson) - ee.Geometry: Earth Engine geometry object

  • name (str or None, optional) – Output filename prefix. If None, uses ‘zonal_stats’. For multi-year: creates ‘{name}_{year}.shp’ files.

  • stat (str, optional) – Statistical method: ‘MEAN’, ‘MEDIAN’, ‘MAX’, ‘MIN’, ‘STDDEV’. Default is ‘MEDIAN’.

  • scale (int, optional) – Pixel resolution for analysis in meters. Default is 10.

  • to_file (bool, optional) – If True, saves results as shapefile(s). Default is False.

Returns:

  • Single image: Returns GeoDataFrame with statistics

  • Multiple years: Returns dict {year: GeoDataFrame} with results per year

Return type:

dict or geopandas.GeoDataFrame

get_tsi(image)#

Trophic State Index - Water trophic state classification for eutrophication assessment.

References

Carlson, R.E. (1977). A trophic state index for lakes. Limnology and Oceanography, 22(2), 361-369.

Kratzer, S., Håkansson, B., Sahlin, C. (2003). Assessing Secchi and photic zone depth in the Baltic Sea from satellite data. AMBIO: A Journal of the Human Environment, 32(8), 577-585.

get_turbidity(image)#

Water Turbidity Index - Suspended sediment and water clarity assessment using OLCI bands.

References

Nechad, B., Ruddick, K.G., Park, Y. (2010). Calibration and validation of a generic multisensor algorithm for mapping of total suspended matter in turbid waters. Remote Sensing of Environment, 114(4), 854-866.

get_utfvi(image)#

Urban Thermal Field Variance Index (UTFVI) - Versión corregida y simplificada

Fórmula simplificada basada en la relación LST-NDVI: UTFVI = (LST - LST_mean) / std_dev

Donde LST_mean se aproxima usando la relación inversa con NDVI.

Valores esperados: - > 0.5: Zona urbana fuerte (isla de calor) - 0 a 0.5: Zona urbana moderada - < 0: Zona vegetada/fresca

get_vci(image)#

Vegetation Condition Index (VCI) - Índice de Condición de Vegetación

Compara el NDVI actual con los valores históricos mín/máx para detectar estrés vegetal. VCI = (NDVI - NDVImin) / (NDVImax - NDVImin) * 100

Valores: - 0-20: Sequía severa - 20-40: Sequía moderada - 40-60: Condiciones normales - 60-80: Condiciones favorables - 80-100: Condiciones muy favorables

Referencias#

Kogan, F.N. (1995). Application of vegetation index and brightness temperature for drought detection. Advances in Space Research, 15(11), 91-100.

Note: Esta implementación usa valores aproximados. Para análisis precisos, usar estadísticas multi-anuales específicas del área.

get_vh(image, normalize=False)#

VH Polarization - Vertical transmit, horizontal receive. Sensitive to vegetation structure.

Parameters:
  • image (ee.Image) – Input SAR image with VH band

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Ulaby, F.T., Moore, R.K., Fung, A.K. (1986). Microwave Remote Sensing: Active and Passive. Volume 3: From Theory to Applications. Artech House, Norwood, MA.

get_vsdi(image, normalize=False)#

Vegetation Scattering Diversity Index - Measures scattering diversity in vegetated areas.

Parameters:
  • image (ee.Image) – Input SAR image with VV and VH bands

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Periasamy, S. (2018). Significance of dual polarimetric synthetic aperture radar in biomass retrieval: An attempt on Sentinel‐1. Remote Sensing of Environment, 217, 537-549.

get_vv(image, normalize=False)#

VV Polarization - Vertical transmit, vertical receive. Sensitive to rough surface scattering.

Parameters:
  • image (ee.Image) – Input SAR image with VV band

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Ulaby, F.T., Moore, R.K., Fung, A.K. (1986). Microwave Remote Sensing: Active and Passive. Volume 3: From Theory to Applications. Artech House, Norwood, MA.

get_vv_vh_ratio(image, normalize=False)#

VV/VH Ratio - Highly sensitive to structural changes, ideal for crop monitoring and mowing detection.

Parameters:
  • image (ee.Image) – Input SAR image with VV and VH bands

  • normalize (bool, optional) – If True, normalizes output to [0,1] range. Default is False.

References

Mascolo, L., Lopez‐Sanchez, J.M., Vicente‐Guijalba, F., Nunziata, F., Migliaccio, M., Mazzarella, G. (2016). A complete procedure for crop phenology estimation with PolSAR data based on the complex Wishart classifier. IEEE Transactions on Geoscience and Remote Sensing, 54(11), 6505-6515.

get_water_leaving_reflectance(image)#

Water Leaving Reflectance - Simplified approximation of water-leaving radiance contribution.

References

Gordon, H.R., Brown, O.B., Evans, R.H., Brown, J.W., Smith, R.C., Baker, K.S., Clark, D.K. (1988). A semianalytic radiance model of ocean color. Journal of Geophysical Research: Atmospheres, 93(D9), 10909-10924.

get_wdrvi(image)#

Wide Dynamic Range Vegetation Index - Enhanced vegetation monitoring for dense canopies.

References

Gitelson, A.A. (2004). Wide dynamic range vegetation index for remote quantification of biophysical characteristics of vegetation. Journal of Plant Physiology, 161(2), 165-173.

get_wi2015(image)#

Water Index 2015 (WI2015) - Índice de Agua 2015

Índice optimizado para detectar agua en diferentes condiciones, incluyendo aguas turbias y con sedimentos. Desarrollado específicamente para discriminar agua de otros tipos de cobertura usando Landsat.

NOTA IMPORTANTE: Los coeficientes originales del paper están diseñados para valores de reflectancia sin escalar (Digital Numbers). Como estamos trabajando con reflectancia escalada [0,1], debemos ajustar los coeficientes.

Fórmula original (para DN sin escalar): WI2015 = 1.7204 + 171*G + 3*R - 70*NIR - 45*SWIR1 - 71*SWIR2

Fórmula ajustada para reflectancia [0,1]: WI2015 = 1.7204 + 1.71*G + 0.03*R - 0.70*NIR - 0.45*SWIR1 - 0.71*SWIR2

Interpretación: - Valores > 0: Agua - Valores < 0: No agua - Valores más positivos indican mayor probabilidad de agua

Referencias#

Fisher, A., Flood, N., Danaher, T. (2016). Comparing Landsat water index methods for automated water classification in eastern Australia. Remote Sensing of Environment, 175, 167-182.

get_year_composite(return_counts: bool = False, count_valid_pixels: bool = False, scale_for_valid: int = 10, maxPixels_for_valid: float = 1000000000.0, count_mode: str = 'granules', return_df: bool = False, df_pivot: bool = False)#

Generate temporal composite images for all years in the time range.

Main processing method that creates multi-band images where each band represents a temporal period (season, month, etc.) using the configured statistical reducer and spectral/radar index.

Parameters:
  • return_counts (bool, optional) – If True, also return a list of dictionaries with image counts per year and period. Default is False (only the ImageCollection).

  • count_valid_pixels (bool, optional) – If True, counts only images that contain at least one valid (non-masked) pixel within the ROI for each period. If False, simply counts the number of images in the filtered ImageCollection, regardless of whether they contribute valid pixels to the ROI. Default is False.

  • scale_for_valid (int, optional) – Spatial resolution (meters) used when checking valid pixels with reduceRegion (only applies if count_valid_pixels=True). Default is 10.

  • maxPixels_for_valid (float, optional) – Maximum number of pixels allowed for the validity check (only applies if count_valid_pixels=True). Default is 1e9.

  • count_mode ({'granules', 'unique_dates'}, optional) – How to count inputs per period when return_counts=True: - ‘granules’: count all scenes (granules) intersecting the ROI after filters (dates, clouds, etc.). - ‘unique_dates’: count unique acquisition dates (YYYY-MM-dd), collapsing multiple tiles/orbits from the same day into one. Default is ‘granules’.

Returns:

  • ee.ImageCollection – Collection of multi-band composite images, one per year. Each image contains bands named after temporal periods. Band count equals successful periods with available data.

  • (ee.ImageCollection, list of dict), optional – If return_counts=True, returns a tuple containing the ImageCollection and a list of dictionaries. Each dictionary has the following keys:

    • year : int

    • period_idx : int

    • period_name : str

    • images_count : int

    • cloud_filter : bool

    • sat : str

    • index : str

    • key : str

    • percentile : int or None

    • count_mode : str

Notes

Processing workflow:

  1. Generate dynamic band names based on satellite and reducer

  2. Clear previous results (self.imagelist = [])

  3. For each year in range:

    1. Process all periods using get_period_composite()

    2. Validate data availability

    3. Optionally count images per period (granules or unique dates)

    4. Combine into multi-band image

    5. Rename bands to period names

  4. Return ImageCollection from processed images

  5. Optionally return image counts if return_counts=True

Band naming conventions:

Optical satellites (S2, Landsat, MODIS, S3):
  • Standard: ['nd', 'nd_1', 'nd_2', ...]

  • Percentile: ['nd_p90', 'nd_p90_1', ...]

SAR satellite (S1):
  • Named by index: ['VH', 'VH_1', ...], ['RVI', 'RVI_1', ...]

  • Percentile: ['VH_p90', 'VH_p90_1', ...]

Final band names use period names:
  • 4 periods: ['winter', 'spring', 'summer', 'autumn']

  • 12 periods: ['january', 'february', ..., 'december']

  • Custom: ['p1', 'p2', ..., 'pN']

Examples

Generate seasonal composites:

>>> collection = processor.get_year_composite()
>>> print(collection.size().getInfo())  # Number of years

Count input images per period (unique dates):

>>> collection, counts = processor.get_year_composite(
...     return_counts=True,
...     count_valid_pixels=False,
...     count_mode="unique_dates"
... )
>>> print(counts[0])
{'year': 2020, 'period_idx': 0, 'period_name': 'january', 'images_count': 6, ...}
Raises:
  • ee.EEException – If Earth Engine computation fails.

  • RuntimeError – If no valid data found for any year.

Warning

Years with insufficient data are skipped with console warnings. Large time ranges may approach computation limits.

See also

get_period_composite

Generates individual period composites

get_export

Export composites to files

get_gif

Create animated visualization

mask_landsat_clouds(image)#

Mask clouds and shadows in Landsat Collection 2 images using QA_PIXEL band.

Parameters:

image (ee.Image) – Landsat Collection 2 Level-2 image with QA_PIXEL band

Returns:

Cloud-masked image

Return type:

ee.Image

References

Landsat Collection 2 Level-2 Science Products https://www.usgs.gov/landsat-missions/landsat-collection-2-level-2-science-products

mask_s2_clouds(image)#

Mask clouds and shadows in Sentinel-2 images using QA60 band.

Parameters:

image (ee.Image) – Sentinel-2 SR image with QA60 band

Returns:

Cloud-masked image

Return type:

ee.Image

References

Sentinel-2 Cloud Masking with s2cloudless https://developers.google.com/earth-engine/tutorials/community/sentinel-2-s2cloudless

mask_s2_scl(image)#

Mask clouds, cloud shadows and cirrus in Sentinel-2 images using the Scene Classification Layer (SCL band).

SCL provides per-pixel classification at 20m resolution, offering more accurate cloud/shadow detection than the QA60 band (which is coarser and misses thin clouds and shadows).

Masked classes: - 1: Saturated / defective pixels - 3: Cloud shadows - 8: Medium probability cloud - 9: High probability cloud - 10: Thin cirrus

Parameters:

image (ee.Image) – Sentinel-2 SR image with SCL band (S2_SR_HARMONIZED collection).

Returns:

Cloud/shadow-masked image with SCL band removed.

Return type:

ee.Image

References

European Space Agency (2021). Sentinel-2 MSI Level-2A Algorithm Theoretical Basis Document. ESA-EOPG-GSCB-TN-0001.

S1ARDProcessor#

class ndvi2gif.S1ARDProcessor(speckle_filter='REFINED_LEE', speckle_filter_kernel_size=7, terrain_correction=True, terrain_flattening_model='VOLUME', dem='COPERNICUS_30', format='LINEAR')#

Bases: object

Analysis Ready Data (ARD) processor for Sentinel-1 SAR imagery.

Implements advanced preprocessing techniques for Sentinel-1 GRD data including radiometric terrain correction and various speckle filtering algorithms.

Parameters:
  • speckle_filter ({'REFINED_LEE', 'LEE', 'GAMMA_MAP', 'LEE_SIGMA', 'BOXCAR', None}) – Speckle filter algorithm. Default is ‘REFINED_LEE’.

  • speckle_filter_kernel_size (int) – Filter kernel size in pixels (must be odd). Default is 7.

  • terrain_correction (bool) – Enable radiometric terrain correction. Default is True.

  • terrain_flattening_model ({'VOLUME', 'SURFACE'}) – Scattering model for terrain correction. Default is ‘VOLUME’.

  • dem ({'COPERNICUS_30', 'COPERNICUS_90', 'SRTM_30', 'SRTM_90'}) – Digital Elevation Model. Default is ‘COPERNICUS_30’.

  • format ({'LINEAR', 'DB'}) – Output format. Default is ‘LINEAR’.

dem_ee#

Earth Engine DEM image object

Type:

ee.Image

Examples

>>> processor = S1ARDProcessor(
...     speckle_filter='REFINED_LEE',
...     terrain_correction=True
... )
>>> collection = ee.ImageCollection('COPERNICUS/S1_GRD')
>>> processed = collection.map(processor.process_image)
apply_speckle_filter(image)#

Apply the selected speckle filter to reduce SAR noise.

Routes to the appropriate filter implementation based on the configured speckle_filter parameter.

Parameters:

image (ee.Image) – Input SAR image with VV and VH bands.

Returns:

Filtered image with reduced speckle noise.

Return type:

ee.Image

Raises:

ee.EEException – If underlying Earth Engine focal/statistical operations fail during filtering.

apply_terrain_correction(image)#

Apply radiometric terrain correction to reduce topographic effects.

Implements the angular-based radiometric slope correction method from Vollrath et al. (2020). This correction compensates for variations in backscatter caused by local terrain slope and aspect relative to the sensor viewing geometry.

Parameters:

image (ee.Image) – Sentinel-1 image with VV, VH, and angle bands.

Returns:

Terrain-corrected image with adjusted VV and VH bands.

Return type:

ee.Image

Raises:

ee.EEException – If required bands or properties are missing (e.g., VV, VH, angle, or orbitProperties_pass) or if Earth Engine operations fail during terrain correction (projection/reprojection errors, invalid geometries).

Notes

The correction factor is clamped between 0.5 and 2.0 to prevent overcorrection in extreme terrain conditions.

References

Vollrath, A., Mullissa, A., & Reiche, J. (2020). Angular-based radiometric slope correction for Sentinel-1 on google earth engine. Remote Sensing, 12(11), 1867.

process_image(image)#

Apply complete preprocessing pipeline to a single image.

Executes the full ARD processing chain in order: 1. Terrain correction (if enabled) 2. Speckle filtering (if configured) 3. Format conversion (if DB requested)

Parameters:

image (ee.Image) – Raw Sentinel-1 GRD image.

Returns:

Preprocessed ARD image ready for analysis.

Return type:

ee.Image

Raises:

ee.EEException – If any step of the processing chain fails in Earth Engine (terrain correction, speckle filtering, or format conversion).

Examples

>>> processor = S1ARDProcessor()
>>> s1_collection = ee.ImageCollection('COPERNICUS/S1_GRD')
>>> processed = s1_collection.map(processor.process_image)
to_db(image)#

Convert backscatter values from linear to decibel scale.

Parameters:

image (ee.Image) – SAR image with VV and VH bands in linear scale.

Returns:

Image with bands converted to decibel scale (10*log10).

Return type:

ee.Image

Raises:

ee.EEException – If required bands (VV, VH) are missing or if Earth Engine evaluation fails during the logarithmic conversion.

Notes

Decibel scale is preferred for visualization and some analyses as it compresses the dynamic range and normalizes the distribution.

TimeSeriesAnalyzer#

class ndvi2gif.TimeSeriesAnalyzer(ndvi_seasonality_instance)#

Bases: object

Advanced time series analysis for Earth Engine remote sensing data.

Provides methods for extracting, analyzing, and visualizing temporal patterns in satellite data processed by NdviSeasonality.

Parameters:

ndvi_seasonality_instance (NdviSeasonality) – Configured NdviSeasonality instance with ROI, periods, years, etc.

processor#

Reference to the parent processor

Type:

NdviSeasonality

time_series_cache#

Cache for extracted time series data

Type:

dict

roi#

Region of interest

Type:

ee.Geometry

periods#

Number of temporal periods per year

Type:

int

start_year#

Starting year of analysis

Type:

int

end_year#

Ending year (inclusive)

Type:

int

sat#

Satellite sensor

Type:

str

index#

Vegetation/environmental index

Type:

str

Examples

>>> processor = NdviSeasonality(sat='S2', index='ndvi')
>>> analyzer = TimeSeriesAnalyzer(processor)
>>> df = analyzer.extract_time_series()
>>> fig = analyzer.plot_comprehensive_analysis()
analyze_trend(df: DataFrame | None = None, method: str = 'mann_kendall', alpha: float = 0.05) Dict[str, Any]#

Perform comprehensive trend analysis on time series.

Parameters:
  • df (pd.DataFrame or None, optional) – Time series dataframe. If None, extracts from ROI centroid.

  • method ({'mann_kendall', 'linear', 'sen_slope', 'all'}, optional) –

    Trend test method:

    • ’mann_kendall’: Non-parametric trend test

    • ’linear’: Linear regression

    • ’sen_slope’: Theil-Sen estimator

    • ’all’: Apply all methods

    Default is ‘mann_kendall’.

  • alpha (float, optional) – Significance level for statistical tests. Default is 0.05.

Returns:

Trend statistics including:

  • mann_kendall: tau, p_value, trend direction

  • linear: slope, r_squared, p_value, confidence interval

  • sen_slope: median slope, confidence interval

  • interpretation: text summary of results

Return type:

dict

Raises:
  • ValueError – If method is not one of {‘mann_kendall’, ‘linear’, ‘sen_slope’, ‘all’}.

  • KeyError – If required columns ('date', 'value') are missing from df.

  • RuntimeError – If trend estimation fails due to insufficient or invalid data.

Examples

>>> # Basic trend analysis
>>> trends = analyzer.analyze_trend(method='mann_kendall')
>>> print(trends['interpretation'])
>>> # All trend methods
>>> trends = analyzer.analyze_trend(method='all')
compare_phenology_years(point: tuple | Point | None = None, reference_year: int | None = None) Dict[str, Any]#

Compare phenological metrics across years to identify anomalies and trends.

Parameters:
  • point (location for extraction)

  • reference_year (year to use as reference (if None, uses mean of all years))

Returns:

Comparison results with anomalies and trends

Return type:

dict

compare_smoothing_impact(point=None, method='threshold', threshold_percentile=50) Dict[str, Any]#

Compare phenological metrics calculated with and without smoothing.

Useful for validating the impact of the v1.0 changes and for documenting differences in JOSS paper.

Parameters:
  • point (location or None) – Extraction point

  • method (str) – Phenology method to compare

  • threshold_percentile (float) – Threshold for threshold method

Returns:

Comparison results with metrics from both approaches

Return type:

dict

Examples

>>> # Compare impact of smoothing
>>> comparison = analyzer.compare_smoothing_impact()
>>> print("Raw data SOS:", comparison['raw']['2020']['sos'])
>>> print("Smoothed SOS:", comparison['smoothed']['2020']['sos'])
extract_phenology_metrics(df: DataFrame | None = None, method: str = 'threshold', threshold_percentile: float = 50, smoothing: bool = True, smoothing_window: int = 7, smoothing_order: int = 3, min_season_length: int = 60, quality_warnings: bool = True) Dict[str, Any]#

Extract phenological metrics with comprehensive quality control and warnings.

Parameters:
  • df (pd.DataFrame or None, optional) – Time series data. If None, extracts from ROI centroid.

  • method ({'threshold', 'derivative', 'logistic'}, optional) – Extraction method. Default is ‘threshold’.

  • threshold_percentile (float, optional) – Percentile for threshold method (0-100). Default is 50.

  • smoothing (bool, optional) – Apply Savitzky-Golay smoothing. Default is True.

  • smoothing_window (int, optional) – Window length for smoothing. Default is 7.

  • smoothing_order (int, optional) – Polynomial order for smoothing. Default is 3.

  • min_season_length (int, optional) – Minimum season length in days. Default is 60.

  • quality_warnings (bool, optional) – Print quality warnings for each method. Default is True.

Returns:

Phenological metrics per year with quality indicators.

Return type:

dict

extract_time_series(point: Point | Tuple[float, float] | None = None, reducer: str = 'mean', scale: int = 30, use_cache: bool = True) DataFrame#

Extract complete time series for a point or region.

Combines all temporal periods across all years into a continuous time series suitable for analysis.

Parameters:
  • point (ee.Geometry.Point, tuple, or None, optional) –

    Location for extraction:

    • None: uses ROI centroid

    • tuple: (longitude, latitude)

    • ee.Geometry.Point: direct point geometry

    • ee.Geometry.Polygon: for spatial averaging

  • reducer ({'mean', 'median', 'max', 'min', 'stdDev'}, optional) – Spatial reducer if using polygon. Default is ‘mean’.

  • scale (int, optional) – Scale in meters for spatial reduction. Default is 30.

  • use_cache (bool, optional) – Whether to use cached results. Default is True.

Returns:

DataFrame with columns:

  • date: datetime index

  • value: index values

  • year: year

  • period: period name

  • doy: day of year

  • season: meteorological season

  • month: month number

Return type:

pd.DataFrame

Raises:
  • ValueError – If point is not a valid coordinate tuple or buffer/scale are invalid.

  • ee.EEException – If Earth Engine extraction fails (geometry errors, reduceRegion failures).

  • RuntimeError – If no valid data can be extracted for the specified point/period.

Examples

>>> # Extract from ROI centroid
>>> df = analyzer.extract_time_series()
>>> # Extract from specific point
>>> df = analyzer.extract_time_series(point=(-5.5, 37.1))
>>> # Extract with different reducer
>>> df = analyzer.extract_time_series(reducer='median', scale=20)
plot_comprehensive_analysis(point=None, figsize=(22, 14), save_path=None)#

Create comprehensive time series analysis dashboard.

Generates a multi-panel figure with time series, trends, seasonal patterns, statistics, and quality metrics.

Parameters:
  • point (location or None, optional) – Extraction point. If None, uses ROI centroid.

  • figsize (tuple, optional) – Figure size (width, height). Default is (22, 14).

  • save_path (str or None, optional) – Path to save figure. If None, displays only.

Returns:

Generated figure object

Return type:

matplotlib.figure.Figure

Raises:
  • RuntimeError – If the input DataFrame is empty or contains insufficient data for analysis.

  • OSError – If saving the figure to save_path fails.

Notes

Dashboard includes:

  • Time series with trend line

  • Seasonal patterns boxplot

  • Annual comparison

  • Trend summary statistics

  • Autocorrelation function

  • Value distribution

  • Phenology summary

  • Data quality metrics

  • Seasonal statistics

Examples

>>> # Basic dashboard
>>> fig = analyzer.plot_comprehensive_analysis()
>>> # Save to file
>>> fig = analyzer.plot_comprehensive_analysis(
...     save_path='analysis_dashboard.png'
... )
plot_phenology_analysis(point=None, method='threshold', threshold_percentile=50, figsize=(24, 16), save_path=None)#

Create comprehensive phenological analysis dashboard.

Generates multi-panel visualization of phenological patterns, timing, amplitudes, and inter-annual variations.

Parameters:
  • point (location or None, optional) – Extraction point. If None, uses ROI centroid.

  • method ({'threshold', 'derivative', 'logistic'}, optional) – Phenology extraction method. Default is ‘threshold’.

  • threshold_percentile (float, optional) – Threshold percentile if using threshold method. Default is 50.

  • figsize (tuple, optional) – Figure size. Default is (24, 16).

  • save_path (str or None, optional) – Path to save figure.

Returns:

Generated figure

Return type:

matplotlib.figure.Figure

Raises:
  • ValueError – If method is not recognized or required columns are missing in df.

  • RuntimeError – If phenology metrics cannot be computed due to insufficient data.

  • OSError – If saving the figure to save_path fails.

Notes

Dashboard panels include:

  • Time series with phenological markers

  • Phenological timing trends

  • Amplitude and peak values

  • Growth/senescence rates

  • Season duration analysis

  • Annual curve comparison

  • Statistical summaries

  • Data quality assessment

SpatialTrendAnalyzer#

class ndvi2gif.SpatialTrendAnalyzer(ndvi_seasonality_instance)#

Bases: object

Spatial trend analysis for generating pixel-wise trend maps.

Complements TimeSeriesAnalyzer by providing spatial analysis capabilities using Earth Engine’s distributed computing.

Parameters:

ndvi_seasonality_instance (NdviSeasonality) – Configured NdviSeasonality instance

Examples

>>> processor = NdviSeasonality(sat='S2', index='ndvi')
>>> spatial = SpatialTrendAnalyzer(processor)
>>> trend_map = spatial.calculate_pixel_trends(method='linear')

Calculate per-pixel temporal trends across the ROI.

Parameters:
  • method ({'linear', 'sen', 'mann_kendall'}, optional) – Trend calculation method. Default is ‘linear’.

  • min_observations (int, optional) – Minimum valid observations per pixel. Default is 5.

  • export (bool, optional) – Export result to GeoTIFF. Default is False.

  • scale (int, optional) – Output resolution in meters. Default is 30.

Returns:

Multi-band trend image with:

  • slope: Trend slope

  • intercept: Y-intercept

  • magnitude: Total change over period

Return type:

ee.Image

Examples

>>> # Calculate linear trends
>>> trend_map = spatial.calculate_pixel_trends()
>>> # Export Sen's slope map
>>> trend_map = spatial.calculate_pixel_trends(
...     method='sen',
...     export=True,
...     scale=20
... )

SpatialPhenologyAnalyzer#

class ndvi2gif.SpatialPhenologyAnalyzer(ndvi_seasonality_instance)#

Bases: object

Server-side, per-pixel phenology raster generation with Earth Engine.

While TimeSeriesAnalyzer extracts phenological metrics for a single point (downloading the time series via getInfo), this class computes the same family of metrics for every pixel of the ROI entirely on Earth Engine, producing phenology rasters (Start/Peak/End of Season, etc.).

Three extraction methods are available, all running fully server-side:

  • 'threshold' : amplitude-based thresholding (SOS/EOS as the first/last day-of-year above an amplitude fraction of the seasonal curve).

  • 'derivative' : SOS/EOS from the steepest positive/negative rate of change between consecutive composites.

  • 'harmonic' : harmonic (Fourier) regression per pixel, used to reconstruct a smooth seasonal curve from which SOS/POS/EOS are extracted. This is the Earth Engine-friendly replacement for the client-side double-logistic fit (which relies on scipy.optimize.curve_fit and cannot run server-side).

Phenology is computed year by year (each year has its own seasonal cycle). Two entry points are provided:

  • extract_phenology_rasters() returns one image per year as an ee.ImageCollection (useful for analysing how phenology shifts over time, e.g. earlier SOS year after year).

  • phenology_summary() collapses all years into a single multi-band ee.Image using a reducer (median/mean), i.e. the typical phenology of the period.

Output bands (per year and in the summary): sos, pos, eos, los, amplitude, peak_value, baseline, growth_rate, senescence_rate. SOS/POS/EOS/LOS are expressed in day-of-year (days).

Parameters:

ndvi_seasonality_instance (NdviSeasonality) – Configured NdviSeasonality instance with ROI, periods and year range.

Notes

Phenology extraction needs enough intra-annual temporal resolution. Using periods=12 (monthly) or periods=24 (bi-monthly) is strongly recommended; with periods=4 (seasonal) results are coarse and a warning is issued.

Examples

>>> processor = NdviSeasonality(sat='S2', index='ndvi', periods=12,
...                             start_year=2018, end_year=2023)
>>> pheno = SpatialPhenologyAnalyzer(processor)
>>> # Option A: one phenology image per year
>>> yearly = pheno.extract_phenology_rasters(method='harmonic')
>>> # Option B: single multi-year median phenology map
>>> summary = pheno.phenology_summary(method='harmonic', reducer='median')
extract_phenology_rasters(method: str = 'threshold', threshold_percentile: float = 50, adaptive_threshold: bool = True, n_harmonics: int = 2, harmonic_step: int = 10, min_observations: int = 5, export: bool = False, export_target: str = 'local', drive_folder: str | None = None, crs: str = 'EPSG:4326', scale: int = 30) ImageCollection#

Compute one per-pixel phenology image per year (Option A).

Parameters:
  • method ({'threshold', 'derivative', 'harmonic'}, optional) – Phenology extraction method. Default is ‘threshold’.

  • threshold_percentile (float, optional) – Amplitude percentile (0-100) defining the season threshold for the 'threshold' and 'harmonic' methods. Default is 50.

  • adaptive_threshold (bool, optional) – If True, uses a lower threshold for SOS and a higher one for EOS (mirrors the client-side behaviour). Default is True.

  • n_harmonics (int, optional) – Number of harmonics for the 'harmonic' method. Default is 2.

  • harmonic_step (int, optional) – Day-of-year step used to reconstruct the smooth harmonic curve. Smaller values give finer SOS/EOS resolution at higher cost. Default is 10.

  • min_observations (int, optional) – Minimum valid composites per pixel and year. Pixels with fewer are masked. Default is 5.

  • export (bool, optional) – Export each yearly image to GeoTIFF. Default is False.

  • export_target ({'local', 'drive'}, optional) – Where to export when export=True. 'local' downloads a GeoTIFF to the working directory (band names are embedded with rasterio if available); 'drive' starts a batch task to Google Drive (Earth Engine preserves band names). Default is ‘local’.

  • drive_folder (str or None, optional) – Google Drive folder for export_target='drive'. Default is None (Drive root).

  • crs (str, optional) – Output CRS for export. Default is ‘EPSG:4326’.

  • scale (int, optional) – Output resolution in meters (used for export). Default is 30.

Returns:

One multi-band image per year, each carrying a 'year' property.

Return type:

ee.ImageCollection

Examples

>>> yearly = pheno.extract_phenology_rasters(method='derivative')
>>> first = ee.Image(yearly.first())
phenology_summary(method: str = 'threshold', reducer: str = 'median', threshold_percentile: float = 50, adaptive_threshold: bool = True, n_harmonics: int = 2, harmonic_step: int = 10, min_observations: int = 5, export: bool = False, export_target: str = 'local', drive_folder: str | None = None, crs: str = 'EPSG:4326', scale: int = 30) Image#

Collapse all years into a single multi-band phenology image (Option B).

Builds the per-year collection with extract_phenology_rasters() and reduces it across years with the requested reducer, yielding the typical phenology of the whole period.

Parameters:
Returns:

Multi-band image with the across-year reduced metrics, keeping the original band names (sos, pos, eos, …).

Return type:

ee.Image

Examples

>>> summary = pheno.phenology_summary(method='harmonic', reducer='median')

LandCoverClassifier#

class ndvi2gif.LandCoverClassifier(ndvi_seasonality_instance)#

Bases: object

Land cover classification workflow based on temporal NDVI composites.

This class integrates seasonal NDVI metrics (from an NdviSeasonality instance) with supervised and unsupervised classification methods in Google Earth Engine. It supports feature stack generation, training data ingestion, model fitting, and accuracy assessment.

processor#

Instance providing temporal NDVI composites and configuration.

Type:

NdviSeasonality

feature_stack#

Image containing stacked features (NDVI indices, temporal metrics).

Type:

ee.Image or None

training_data#

FeatureCollection with labeled training samples.

Type:

ee.FeatureCollection or None

validation_data#

FeatureCollection with labeled validation samples.

Type:

ee.FeatureCollection or None

classifier#

Trained Earth Engine classifier.

Type:

ee.Classifier or None

classified_image#

Output land cover classification map.

Type:

ee.Image or None

accuracy_results#

Accuracy metrics computed from validation data.

Type:

dict or None

roi#

Region of interest inherited from processor.

Type:

ee.Geometry

periods#

Number of temporal periods per year.

Type:

int

start_year#

First year of the analysis.

Type:

int

end_year#

Last year (exclusive) of the analysis.

Type:

int

sat#

Satellite name used (e.g., ‘S2’, ‘L8’).

Type:

str

add_training_data(training_points: str | FeatureCollection = None, training_polygons: str | FeatureCollection = None, class_property: str = 'class', points_per_class: int = 100) None#

Add training data for supervised classification.

Parameters:
  • training_points (str or ee.FeatureCollection) – Point features with class labels (shapefile path or ee.FeatureCollection)

  • training_polygons (str or ee.FeatureCollection) – Polygon features to sample points from

  • class_property (str) – Property containing class values

  • points_per_class (int) – If using polygons, number of points to sample per class

Raises:
  • ValueError – If no feature stack has been created or if neither points nor polygons are provided.

  • ee.EEException – If Earth Engine sampling fails when extracting training data.

classify_supervised(algorithm: str = 'random_forest', train_fraction: float = 0.7, params: Dict = None) Image#

Perform supervised classification.

Parameters:
  • algorithm (str) – Classification algorithm: - ‘random_forest’: Random Forest (default) - ‘svm’: Support Vector Machine - ‘cart’: Classification and Regression Trees - ‘naive_bayes’: Naive Bayes - ‘gradient_tree’: Gradient Tree Boost

  • train_fraction (float) – Fraction of data for training (rest for validation)

  • params (dict) – Algorithm-specific parameters

Returns:

Classified image

Return type:

ee.Image

Raises:
  • ValueError – If training data has not been added or if the classifier algorithm is not supported.

  • ee.EEException – If supervised classification fails in Earth Engine.

classify_unsupervised(algorithm: str = 'kmeans', n_clusters: int = 10, max_iterations: int = 20, params: Dict = None) Image#

Perform unsupervised classification (clustering).

Parameters:
  • algorithm (str) – Clustering algorithm: - ‘kmeans’: K-means clustering (default) - ‘cascade_kmeans’: Cascade K-means - ‘lda’: Latent Dirichlet Allocation

  • n_clusters (int) – Number of clusters

  • max_iterations (int) – Maximum iterations

  • params (dict) – Algorithm-specific parameters

Returns:

Clustered image

Return type:

ee.Image

Raises:
  • ValueError – If no feature stack has been created or if algorithm is not one of {‘kmeans’, ‘gmm’}.

  • ee.EEException – If unsupervised classification fails in Earth Engine.

create_feature_stack(indices: List[str] = None, include_statistics: bool = True, normalize: bool = True) Image#

Create multi-temporal feature stack for classification.

Parameters:
  • indices (list of str, optional) – Indices to stack. If None, uses current index.

  • include_statistics (bool) – Add temporal statistics (mean, std, max, min)

  • normalize (bool) – Normalize to [0,1] range

Returns:

Multi-band feature stack

Return type:

ee.Image

Raises:
  • ValueError – If indices contains unsupported names or is empty.

  • ee.EEException – If Earth Engine image processing fails when computing the stack.

export_results(description: str, scale: int = 30, region: Geometry | None = None)#

Export the classified image to Google Drive or Earth Engine Asset.

Parameters:
  • description (str) – Name of the export task.

  • scale (int, optional) – Spatial resolution in meters. Default is 30.

  • region (ee.Geometry, optional) – Geometry defining the export area. If None, uses the full image extent.

Returns:

The Earth Engine export task object.

Return type:

ee.batch.Task

Raises:
  • ValueError – If no classified image is available.

  • ee.EEException – If the export task could not be created.

get_accuracy_report() DataFrame#

Return accuracy metrics as a pandas DataFrame.

Returns:

Table with overall accuracy, kappa, producer’s and user’s accuracy for each class.

Return type:

pandas.DataFrame

Raises:

ValueError – If no accuracy metrics are available.

get_feature_importance() Dict[str, float]#

Get feature importance scores from a Random Forest classifier.

Returns:

Mapping of feature names to importance scores.

Return type:

dict

Raises:

ValueError – If classifier is not a Random Forest or not trained.

plot_confusion_matrix(labels: List[str])#

Plot the confusion matrix of the classification results.

Parameters:

labels (list of str) – List of class names in the same order as the matrix.

Returns:

Axis object containing the confusion matrix plot.

Return type:

matplotlib.axes.Axes

Raises:

ValueError – If no confusion matrix is available (classification or accuracy not run).

HydroperiodAnalyzer#

class ndvi2gif.HydroperiodAnalyzer(ndvi_seasonality, hydrological_year_start=(9, 1))#

Bases: object

GEE-native hydroperiod computation from satellite water indices.

Computes hydroperiod entirely in Google Earth Engine using the midpoint temporal weighting method. Each scene in the satellite collection receives a proportional number of days based on its position within the hydrological cycle, then weighted flood and valid days are accumulated per pixel.

Parameters:
  • ndvi_seasonality (NdviSeasonality) – Configured NdviSeasonality instance. The ROI, satellite, date range, cloud filtering, and band standardisation are reused directly — no duplicate configuration needed.

  • hydrological_year_start (tuple of (int, int), optional) – (month, day) marking the start of the hydrological cycle. Default (9, 1) = September 1st.

Examples

import ee
from ndvi2gif import NdviSeasonality, HydroperiodAnalyzer

ee.Initialize()

ns = NdviSeasonality(roi, sat='S2', start_year=2023, end_year=2024)
ha = HydroperiodAnalyzer(ns)

# Full GEE-native computation
result = ha.compute_hydroperiod(index='mndwi', threshold=0.1)

# result is an ee.Image with bands:
#   hydroperiod, valid_days, normalized,
#   first_flood_doy, last_flood_doy

# Export to Drive
ha.export_to_drive(folder='my_wetland')

# Per-pixel IRT (temporal representativity)
irt = ha.compute_irt_image()

Notes

Supported water indices (optical sensors): 'ndwi', 'mndwi', 'awei', 'aweinsh', 'wi2015'

The per-pixel IRT is computed as Simpson’s diversity index across monthly periods, which is fully computable per-pixel in GEE. The global IRT uses the Gini-based formula identical to the standalone phydroperiod library (computed client-side from scene dates).

HISTORICAL_START = {'Landsat': 1984, 'MODIS': 2000, 'S1': 2014, 'S2': 2017}#

First available hydrological year for each sensor’s full archive.

WATER_INDICES = frozenset({'awei', 'aweinsh', 'mndwi', 'ndwi', 'wi2015'})#

Water indices supported for hydroperiod computation.

compute_all_cycles(index='mndwi', threshold=0.0, normalize=True, compute_first_last=True)#

Compute hydroperiod for every hydrological cycle in the date range.

Iterates from ns.start_year to ns.end_year (inclusive), computing one hydroperiod image per cycle. Each cycle spans from hydrological_year_start in year Y to the same date in year Y+1.

Parameters:
  • index (str) – Water index for mask generation. Default 'mndwi'.

  • threshold (float) – Water classification threshold. Default 0.0.

  • normalize (bool) – Include 'normalized' band in each cycle image. Default True.

  • compute_first_last (bool) – Include 'first_flood_doy' / 'last_flood_doy' bands. Default True.

Returns:

Mapping {hyd_year: ee.Image} where hyd_year is the starting calendar year of each cycle (e.g. 2020 for 2020-2021). Each image has the same bands as compute_hydroperiod() plus a 'hyd_year' property for easy identification.

Return type:

dict

Examples

ns = NdviSeasonality(roi, sat='S2', start_year=2019, end_year=2023)
ha = HydroperiodAnalyzer(ns)

cycles = ha.compute_all_cycles(index='mndwi', threshold=0.1)
# cycles = {2019: ee.Image, 2020: ee.Image, ..., 2023: ee.Image}

# Export all cycles to Drive
for yr, img in cycles.items():
    ha.export_to_drive(image=img, description=f'hydroperiod_{yr}_{yr+1}')
compute_anomalies(cycles=None, index='mndwi', threshold=0.0, reference='period')#

Compute mean hydroperiod and per-cycle anomalies.

Calculates the mean normalised hydroperiod across a reference period and the anomaly of each cycle relative to that mean:

anomaly = cycle_normalized - mean_normalized

Positive values indicate a wetter-than-average year; negative values indicate a drier-than-average year.

Parameters:
  • cycles (dict, optional) – Output of compute_all_cycles(): {hyd_year: ee.Image}. If None, runs compute_all_cycles() automatically.

  • index (str) – Water index, used only when cycles is None.

  • threshold (float) – Classification threshold, used only when cycles is None.

  • reference (str) –

    Reference period for computing the mean:

    • 'period' (default): mean of the cycles in the current analysis range (ns.start_yearns.end_year).

    • 'historical': mean of the full satellite archive, from the sensor’s first available year to the last complete cycle. Gives a climatological baseline independent of the chosen analysis window. Note: GEE builds the full graph lazily so this call is fast, but rendering/export will be slower.

Returns:

{'mean': ee.Image, 'anomalies': {hyd_year: ee.Image}}

  • 'mean': mean normalised hydroperiod (band 'mean_hydroperiod', int16). Properties: 'reference', 'ref_start_year', 'ref_end_year', 'ref_n_cycles'.

  • 'anomalies': per-cycle anomaly images (band 'anomaly', int16). Same metadata properties set on each image.

Return type:

dict

Examples

# Mean of the analysis period
result = ha.compute_anomalies(cycles, reference='period')

# Climatological baseline (full satellite archive)
result = ha.compute_anomalies(cycles, reference='historical')

Map.addLayer(result['mean'], vis, 'Mean hydroperiod')
for yr, anom in result['anomalies'].items():
    Map.addLayer(anom, anom_vis, f'Anomaly {yr}/{yr+1}')
compute_hydroperiod(index='mndwi', threshold=0.0, hyd_year=None, normalize=True, compute_first_last=True, min_flood_days=3, permanent_threshold=0.95)#

Compute hydroperiod entirely in Google Earth Engine.

Implements the midpoint weighting algorithm:

  1. Generate binary water masks (via get_water_masks()).

  2. For each scene, compute weighted flood and valid-day contributions:

    • flood_contrib = water * weight (weight where flooded, 0 where dry)

    • valid_contrib = valid_mask * weight (weight where any valid obs)

  3. Sum contributions per pixel across all scenes → hydroperiod and valid_days.

  4. Optionally normalise: normalized = (hydroperiod / valid_days) * 365.

  5. Optionally compute first / last flood day (day of hydrological year).

Parameters:
  • index (str) – Water index for mask generation. Default 'mndwi'.

  • threshold (float) – Water classification threshold. Default 0.0.

  • hyd_year (int, optional) – Starting year of the hydrological cycle. Default ns.start_year.

  • normalize (bool) – Add a 'normalized' band corrected for uneven temporal coverage. Default True.

  • compute_first_last (bool) – Add 'first_flood_doy' and 'last_flood_doy' bands (days since hydrological year start, 0-indexed). Default True.

  • min_flood_days (int) – Minimum accumulated flood days required for a pixel to receive a valid first_flood_doy / last_flood_doy value. Pixels below this threshold are masked (likely noise or isolated cloud artefacts). Default 3.

  • permanent_threshold (float) – Fraction of valid days that must be flooded for a pixel to be considered permanently inundated (e.g. open sea, permanent lagoons). These pixels get first_flood_doy = 0 and last_flood_doy = 365 because a meaningful onset/recession date cannot be determined. Range [0, 1]. Default 0.95.

Returns:

Multi-band image clipped to the ROI with bands:

  • hydroperiod : accumulated weighted flood days (float32)

  • valid_days : accumulated weighted valid days (float32)

  • normalized : flood days normalised to 365-day year (int16, optional)

  • first_flood_doy: first flood day of cycle (int16, optional)

  • last_flood_doy : last flood day of cycle (int16, optional)

Image properties: 'hyd_year_start', 'hyd_year_end', 'index', 'threshold'.

Return type:

ee.Image

compute_irt_global(hyd_year=None)#

Compute the global Temporal Representativity Index (IRT).

Measures how uniformly the available scenes are distributed across the hydrological year. A value of 1 means perfect temporal coverage; 0 means all scenes cluster in a single period.

This uses the Gini-based formula identical to phydroperiod’s calculate_temporal_representativity(), computed client-side from the scene date metadata.

Parameters:

hyd_year (int, optional) – Starting year of the hydrological cycle.

Returns:

IRT value between 0 (worst) and 1 (best). Requires one .getInfo() call to retrieve scene dates.

Return type:

float

compute_irt_image(hyd_year=None, n_periods=12)#

Compute per-pixel Temporal Representativity Index as an ee.Image.

For each pixel, estimates how uniformly its valid (non-cloud) observations are distributed across the hydrological year. This is the GEE-native counterpart of phydroperiod’s calculate_pixel_irt().

Uses Simpson’s diversity index as a per-pixel-computable proxy:

\[\text{IRT}_{pixel} = \frac{N^2}{n_{periods} \cdot \sum n_i^2}\]

where \(N\) is the total number of valid observations for that pixel and \(n_i\) is the count in period i. This ranges from \(1/n_{periods}\) (all observations in one period) to 1 (perfectly uniform).

Parameters:
  • hyd_year (int, optional) – Starting year of the hydrological cycle.

  • n_periods (int) – Number of periods the year is divided into. Default 12 (monthly).

Returns:

Single-band IRT image (band 'irt'), values 0–1, clipped to ROI. Masked where no valid observations exist.

Return type:

ee.Image

Notes

Call get_water_masks() first (or let this method call it automatically via the hyd_year argument).

export_to_asset(asset_id, image=None, description=None, scale=10, crs='EPSG:4326', **kwargs)#

Export hydroperiod results to an Earth Engine Asset.

Parameters:
  • asset_id (str) – Full EE asset path (e.g. 'projects/my-project/assets/hydroperiod_2023_2024').

  • image (ee.Image, optional) – Image to export. If None, uses the last compute_hydroperiod() result.

  • description (str, optional) – Task name. Auto-generated if not provided.

  • scale (int) – Output pixel size in metres. Default 10.

  • crs (str) – Output CRS. Default 'EPSG:4326'.

  • **kwargs – Additional keyword arguments forwarded to ee.batch.Export.image.toAsset.

Returns:

Started export task.

Return type:

ee.batch.Task

export_to_drive(image=None, folder='hydroperiod', description=None, scale=10, crs='EPSG:4326', **kwargs)#

Export hydroperiod results to Google Drive.

Parameters:
  • image (ee.Image, optional) – Image to export. If None, uses the last compute_hydroperiod() result.

  • folder (str) – Google Drive destination folder. Default 'hydroperiod'.

  • description (str, optional) – Task name in the Earth Engine Tasks panel. Auto-generated from hydrological year if not provided.

  • scale (int) – Output pixel size in metres. Default 10 (Sentinel-2).

  • crs (str) – Output CRS. Default 'EPSG:4326'.

  • **kwargs – Additional keyword arguments forwarded to ee.batch.Export.image.toDrive.

Returns:

Started export task.

Return type:

ee.batch.Task

get_water_masks(index='mndwi', threshold=0.0, hyd_year=None)#

Generate weighted binary water masks from the satellite collection.

For each scene in the hydrological year:

  1. Compute the selected water index.

  2. Classify pixels: index > threshold → water (1), else → dry (0).

  3. Preserve the cloud/nodata mask already applied by NdviSeasonality (SCL-based for S2 when scl_mask=True, QA60 otherwise).

  4. Mosaic same-day scenes (max — water wins over dry).

  5. Attach temporal weight properties via the midpoint method.

Parameters:
  • index (str) – Water index to compute. One of: 'ndwi', 'mndwi', 'awei', 'aweinsh', 'wi2015'.

  • threshold (float) – Classification threshold. Default 0.0 works well for most water indices (positive = water). Increase for stricter mapping.

  • hyd_year (int, optional) – Starting calendar year of the hydrological cycle (e.g. 2023 for the Sep 2023 – Aug 2024 cycle). Defaults to ns.start_year.

Returns:

Binary water masks (band 'water': 1 = water, 0 = dry, masked = nodata/cloud) with properties: weight (days), start_doy, end_doy.

Return type:

ee.ImageCollection

Notes

Pixel-level cloud/shadow masking is controlled by the scl_mask parameter of NdviSeasonality (default True for S2).

Utility functions#

ndvi2gif.scale_OLI(image)#

Scale Landsat 8-9 OLI/TIRS sensor data to surface reflectance.

Applies Collection 2 Level-2 scaling factors to convert digital numbers (DN) to surface reflectance values in the range [0, 1]. The scaling formula (DN * 0.0000275 - 0.2) is specific to Landsat Collection 2 products.

Parameters:

image (ee.Image) – Raw Landsat 8 or 9 image from Collection 2 Level-2 with SR bands. Required bands: SR_B2, SR_B3, SR_B4, SR_B5, SR_B6, SR_B7

Returns:

Image with scaled and renamed optical bands:

  • Blue : SR_B2 scaled (0.45-0.51 μm)

  • Green : SR_B3 scaled (0.53-0.59 μm)

  • Red : SR_B4 scaled (0.64-0.67 μm)

  • Nir : SR_B5 scaled (0.85-0.88 μm)

  • Swir1 : SR_B6 scaled (1.57-1.65 μm)

  • Swir2 : SR_B7 scaled (2.11-2.29 μm)

Return type:

ee.Image

Examples

Apply to a single Landsat 8 image:

l8_image = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_044034_20140318')
scaled_image = scale_OLI(l8_image)
print(scaled_image.bandNames().getInfo())
# Output: ['Blue', 'Green', 'Red', 'Nir', 'Swir1', 'Swir2', ...]

Apply to an image collection:

l8_collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
scaled_collection = l8_collection.map(scale_OLI)
Raises:
  • KeyError – If expected OLI surface reflectance bands are missing in image (e.g., SR_B2SR_B7).

  • TypeError – If image is not an ee.Image.

Notes

The scaling coefficients are defined by USGS for Collection 2:

  • Scale factor: 0.0000275

  • Offset: -0.2

  • Valid range after scaling: typically -0.2 to 1.5

  • Negative values may occur in water or shadow areas

See also

scale_ETM

Scaling function for Landsat 4-5-7

References

USGS (2021). Landsat Collection 2 Level-2 Science Products. https://www.usgs.gov/landsat-missions/landsat-collection-2-level-2-science-products

ndvi2gif.scale_ETM(image)#

Scale Landsat 4-5-7 ETM+/TM sensor data to surface reflectance.

Applies Collection 2 Level-2 scaling factors for Enhanced Thematic Mapper Plus (ETM+) on Landsat 7 and Thematic Mapper (TM) on Landsat 4-5. Uses the same scaling formula as OLI but with different band numbering scheme.

Parameters:

image (ee.Image) – Raw Landsat 4, 5, or 7 image from Collection 2 Level-2. Required bands: SR_B1, SR_B2, SR_B3, SR_B4, SR_B5, SR_B7 Note: SR_B6 (thermal) is excluded as it requires different scaling

Returns:

Image with scaled and renamed optical bands:

  • Blue : SR_B1 scaled (0.45-0.52 μm)

  • Green : SR_B2 scaled (0.52-0.60 μm)

  • Red : SR_B3 scaled (0.63-0.69 μm)

  • Nir : SR_B4 scaled (0.77-0.90 μm)

  • Swir1 : SR_B5 scaled (1.55-1.75 μm)

  • Swir2 : SR_B7 scaled (2.09-2.35 μm)

Return type:

ee.Image

Examples

Apply to a Landsat 5 image:

l5_image = ee.Image('LANDSAT/LT05/C02/T1_L2/LT05_044034_20110716')
scaled_image = scale_ETM(l5_image)

Apply to mixed Landsat collection:

landsat_457 = ee.ImageCollection('LANDSAT/LE07/C02/T1_L2')
scaled_collection = landsat_457.map(scale_ETM)
Raises:
  • KeyError – If expected ETM+ surface reflectance bands are missing in image (e.g., SR_B1SR_B5 and SR_B7).

  • TypeError – If image is not an ee.Image.

Notes

Band numbering differs between ETM/TM and OLI sensors:

  • ETM/TM Band 1 (Blue) → OLI Band 2

  • ETM/TM Band 2 (Green) → OLI Band 3

  • ETM/TM Band 3 (Red) → OLI Band 4

  • No Band 6 processing (thermal requires different scaling)

Warning

Landsat 7 ETM+ has scan line corrector failure (SLC-off) after May 2003, resulting in data gaps. Consider using gap-filling techniques or focusing on Landsat 4-5 for historical analysis.

See also

scale_OLI

Scaling function for Landsat 8-9

References

USGS (2021). Landsat Collection 2 Level-2 Science Products. https://www.usgs.gov/landsat-missions/landsat-collection-2-level-2-science-products

See Also#