> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wherobots.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Building Sentinel-2 mosaics with RasterFlow

<Badge color="purple">Private Preview</Badge>

<Tip>
  The following content is a read-only preview of an executable Jupyter notebook.

  To run this notebook interactively:

  1. Go to [**Wherobots Cloud**](https://cloud.wherobots.com).
  2. Start a runtime.
  3. Open the notebook.
  4. In the Jupyter Launcher:
     1. Click **File > Open Path**.
     2. Paste the following path to access this notebook: `examples/Analyzing_Data/RasterFlow_S2_Mosaic.ipynb`
     3. Click **Enter**.
</Tip>

This notebook demonstrates how to generate a harvest season Sentinel-2 median mosaic using Wherobots RasterFlow. You will learn how to define an Area of Interest, build a seasonal composite mosaic, and visualize the results as RGB imagery.

### Sentinel-2 Mosaics for Harvest and Growing Seasons or Custom Time Ranges

RasterFlow provides pre-built seasonal mosaic datasets that use latitude-based heuristics to determine the optimal imaging window for agricultural analysis.

S2\_MED\_PLANTING: Sentinel-2 median composite dataset for planting season.

S2\_MED\_HARVEST: Sentinel-2 median composite dataset for harvest season.

S2\_MED\_WINDOWED\_PIXEL\_ALL\_BANDS: Sentinel-2 median composite over a user-specified date window, returning all 12 L2A spectral bands at 10m. No season heuristic is applied.

In this example, we will generate a mosaic for the harvest season.  The mosaic contains 5 bands:

* `s2med_harvest:B02` - Blue (10m)
* `s2med_harvest:B03` - Green (10m)
* `s2med_harvest:B04` - Red (10m)
* `s2med_harvest:B08` - NIR (10m)
* `s2med_harvest:N_VALID_PIXELS` - Count of valid pixels used in the median calculation

After the harvest mosaic, we'll build a second mosaic over the same AOI using `S2_MED_WINDOWED_PIXEL_ALL_BANDS` to show how to get all 12 spectral bands over a custom date window.

## Setup and Imports

```python theme={"system"}
import os
from datetime import datetime

import geopandas as gpd
import wkls
import xarray as xr
from rasterflow_remote import RasterflowClient
from rasterflow_remote.data_models import DatasetEnum
```

## Initializing the RasterFlow client

```python theme={"system"}
rf_client = RasterflowClient()
```

## Selecting an Area of Interest (AOI)

We will use Haskell County, Kansas as our AOI. This is an agricultural region in the US Great Plains, ideal for demonstrating harvest-season imagery.

```python theme={"system"}
# Generate a geometry for Haskell County, Kansas using Well-Known Locations (https://github.com/wherobots/wkls)
gdf = gpd.read_file(wkls["us"]["ks"]["Haskell County"].geojson())

# Save the geometry to a parquet file in the user's S3 path
aoi_path = os.getenv("USER_S3_PATH") + "harvest_mosaic_aoi.parquet"
gdf.to_parquet(aoi_path)

# Store bounds for visualization later
min_lon, min_lat, max_lon, max_lat = gdf.total_bounds

print(f"AOI saved to: {aoi_path}")
print(f"Bounds: [{min_lon:.4f}, {min_lat:.4f}, {max_lon:.4f}, {max_lat:.4f}]")
```

## Building the harvest season mosaic

This step builds a Sentinel-2 median composite mosaic for the harvest season only.

The workflow will:

1. Query Sentinel-2 imagery for the AOI and date range
2. Filter to harvest season dates based on latitude
3. Apply [cloud and quality filtering](https://docs.wherobots.com/develop/rasterflow/rasterflow-datasets#cloud-and-quality-filtering) — excluding scenes with >= 75% cloud cover and masking pixels flagged as cloud, cloud shadow, cirrus, saturated/defective, or unclassified in the SCL band
4. Compute a pixel-wise median composite across remaining valid observations
5. Output the result as a Zarr store

> **Note:** This step will take approximately 10-15 minutes to complete.  If you want to skip this build\_mosaic step, you can uncomment the next cell and start with a pre-generated mosaic.

```python theme={"system"}
# Use the pre-generated mosaic instead
# mosaic_store = "s3://wherobots-examples/rasterflow/mosaics/haskell_harvest.zarr"
```

```python theme={"system"}
mosaic_index = rf_client.build_mosaic(
    # Dataset type for harvest season median mosaic
    datasets=[DatasetEnum.S2_MED_HARVEST],
    
    # Path to our AOI in GeoParquet format
    aoi=aoi_path,
    
    # Date range for imagery to be used
    start=datetime(2024, 1, 1),
    end=datetime(2025, 1, 1),
    
    # Output CRS (Web Mercator)
    crs_epsg=3857,
)

mosaic_index.mosaics
```

```python theme={"system"}
# This example AOI has one geometry, so we select the first (only) mosaic location.
mosaic_store = mosaic_index.first_row_mosaic

mosaic_store
```

## Visualizing outputs

If RasterFlow is enabled for your organization, you can visualize the Zarr outputs using [cloud.wherobots.com/map](https://cloud.wherobots.com/map).

## Building an ALL\_BANDS mosaic over a custom window

Pick the `S2_MED_WINDOWED_PIXEL_ALL_BANDS` dataset when:

* You need a **specific date window** (e.g., a single month, or pre/post a known event) — `start` and `end` are used directly, with no latitude-based seasonal filtering.
* You need bands beyond RGB+NIR — for example **red-edge** (B05, B06, B07, B8A), **water vapor** (B09), or **SWIR** (B11, B12) bands for indices like NDMI, NBR, or NDWI.

The mosaic contains 12 bands at 10m: B01, B02, B03, B04, B05, B06, B07, B08, B8A, B09, B11, B12 (B10 is excluded because it isn't part of L2A).

Cloud and quality filtering and the median composition step are the same as for the harvest mosaic above. We'll reuse the AOI we wrote to S3 and build a peak-vegetation summer composite for July–August 2024.

```python theme={"system"}
all_bands_index = rf_client.build_mosaic(
    # All 12 L2A spectral bands, median composite over the date window below
    datasets=[DatasetEnum.S2_MED_WINDOWED_PIXEL_ALL_BANDS],
    
    # Reuse the same AOI as the harvest example
    aoi=aoi_path,
    
    # Custom date window — used directly, no seasonal heuristic
    start=datetime(2024, 7, 1),
    end=datetime(2024, 9, 1),
    
    # Output CRS (Web Mercator)
    crs_epsg=3857,
)

all_bands_store = all_bands_index.first_row_mosaic
print(f"All-bands mosaic store: {all_bands_store}")
```

## Summary

This notebook demonstrated how to:

1. Use RasterFlow to build a harvest-season Sentinel-2 median mosaic
2. Build a custom-window all-bands Sentinel-2 mosaic with `S2_MED_WINDOWED_PIXEL_ALL_BANDS`

### Next steps

* Compare with a **planting season** mosaic using `DatasetEnum.S2_MED_PLANTING`
* Run the **FTW model** for field boundary detection (see `RasterFlow_FTW.ipynb`)
* Use the mosaic as input for **model inference** using [predict\_mosaic](https://docs.wherobots.com/reference/rasterflow/client#predict_mosaic)
