# pstcricq/cabrera-mhw-twin architecture

> Architecture diagram of the GitHub repository pstcricq/cabrera-mhw-twin, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pstcricq/cabrera-mhw-twin
- Repository: https://github.com/pstcricq/cabrera-mhw-twin

## Overview

cabrera-mhw-twin is a marine-heatwave data product for Cabrera MPA. Its main workflow harmonizes satellite SST and park-boundary data, computes heatwave indicators and warming scenarios, exports tables and metadata, then serves them through an HTTP API consumed by a five-page dashboard. A separate in-situ branch supplies station data for satellite validation. The graph follows the documented workflow and sampled calls; source excerpts are partial, so uncertain connections—especially refresh orchestration and dashboard page-specific requests—are omitted.

Main entry points: [`dashboard/common.py`](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/common.py) (API client), [`src/cabrera_twin/pipeline.py`](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/pipeline.py) (Build pipeline), [`src/cabrera_twin/analysis/indicators.py`](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/indicators.py) (Indicator computation), [`data/processed`](https://github.com/pstcricq/cabrera-mhw-twin/tree/main/data/processed) (Processed series)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_sources["Data ingestion"]
  node_sst_ingest["Satellite SST ingest<br/>[sst.py]"]
  node_insitu_ingest["Station ingest<br/>[insitu.py]"]
  node_mpa_ingest["Park boundary<br/>[mpa.py]"]
  node_processed[("Processed series")]
end

subgraph group_analysis["Heatwave analysis"]
  node_pipeline["Build pipeline<br/>[pipeline.py]"]
  node_detection["Heatwave detection<br/>[mhw.py]"]
  node_scenarios["Warming scenarios<br/>[whatif.py]"]
  node_indicators["Indicator computation<br/>[indicators.py]"]
end

subgraph group_exports["Data products"]
  node_table_export["Parquet and metadata<br/>[tables.py]"]
  node_stac_export["STAC catalog<br/>[stac.py]"]
  node_exports_store[("Exported datasets")]
end

subgraph group_service["API service"]
  node_api["HTTP API<br/>[api.py]"]
end

subgraph group_dashboard["Dashboard"]
  node_client["API client<br/>[common.py]"]
  node_overview["Overview<br/>[overview.py]"]
  node_year["Year explorer<br/>[year_explorer.py]"]
  node_trends["Trends and what-if<br/>[trends.py]"]
  node_validation["Validation page<br/>[validation.py]"]
  node_method["Method and data<br/>[method.py]"]
end

node_copernicus(("Copernicus Marine"))
node_socib(("SOCIB station"))
node_boundary_source(("MPA boundary source"))
node_user(("Analyst"))

node_copernicus -->|"provides SST"| node_sst_ingest
node_socib -->|"provides observations"| node_insitu_ingest
node_boundary_source -->|"provides boundary"| node_mpa_ingest
node_sst_ingest -->|"writes SST"| node_processed
node_insitu_ingest -->|"writes station data"| node_processed
node_mpa_ingest -->|"writes boundary"| node_processed
node_pipeline -->|"opens SST"| node_sst_ingest
node_pipeline -->|"requests mask"| node_mpa_ingest
node_pipeline -->|"computes indicators"| node_indicators
node_indicators -->|"detects events"| node_detection
node_indicators -->|"computes scenarios"| node_scenarios
node_indicators -->|"reads station data"| node_insitu_ingest
node_pipeline -->|"writes results"| node_table_export
node_pipeline -->|"writes catalog"| node_stac_export
node_table_export -->|"writes tables"| node_exports_store
node_stac_export -->|"writes catalog"| node_exports_store
node_api -->|"queries exports"| node_exports_store
node_api -->|"reads boundary and metadata"| node_processed
node_client -->|"requests data"| node_api
node_overview -->|"fetches data"| node_client
node_year -->|"fetches data"| node_client
node_trends -->|"requests scenarios"| node_client
node_validation -->|"fetches data"| node_client
node_method -->|"fetches data"| node_client
node_user -->|"views"| node_overview
node_user -->|"explores year"| node_year
node_user -->|"tests warming"| node_trends
node_user -->|"checks validation"| node_validation
node_user -->|"reads method"| node_method

click node_sst_ingest "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/ingest/sst.py"
click node_insitu_ingest "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/ingest/insitu.py"
click node_mpa_ingest "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/ingest/mpa.py"
click node_processed "https://github.com/pstcricq/cabrera-mhw-twin/tree/main/data/processed"
click node_pipeline "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/pipeline.py"
click node_detection "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/mhw.py"
click node_scenarios "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/whatif.py"
click node_indicators "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/indicators.py"
click node_table_export "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/export/tables.py"
click node_stac_export "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/export/stac.py"
click node_exports_store "https://github.com/pstcricq/cabrera-mhw-twin/tree/main/data/exports"
click node_api "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/api.py"
click node_client "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/common.py"
click node_overview "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/overview.py"
click node_year "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/year_explorer.py"
click node_trends "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/trends.py"
click node_validation "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/validation.py"
click node_method "https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/method.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_sst_ingest,node_insitu_ingest,node_mpa_ingest,node_processed toneBlue
class node_pipeline,node_detection,node_scenarios,node_indicators toneAmber
class node_table_export,node_stac_export,node_exports_store toneMint
class node_api toneRose
class node_client,node_overview,node_year,node_trends,node_validation,node_method,node_copernicus,node_socib,node_boundary_source,node_user toneIndigo
```

## Components

### Data ingestion

- [Satellite SST ingest](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/ingest/sst.py): `src/cabrera_twin/ingest/sst.py`
- [Station ingest](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/ingest/insitu.py): `src/cabrera_twin/ingest/insitu.py`
- [Park boundary](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/ingest/mpa.py): `src/cabrera_twin/ingest/mpa.py`
- [Processed series](https://github.com/pstcricq/cabrera-mhw-twin/tree/main/data/processed): `data/processed`

### Heatwave analysis

- [Build pipeline](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/pipeline.py): `src/cabrera_twin/pipeline.py`
- [Heatwave detection](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/mhw.py): `src/cabrera_twin/analysis/mhw.py`
- [Warming scenarios](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/whatif.py): `src/cabrera_twin/analysis/whatif.py`
- [Indicator computation](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/analysis/indicators.py): `src/cabrera_twin/analysis/indicators.py`

### Data products

- [Parquet and metadata](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/export/tables.py): `src/cabrera_twin/export/tables.py`
- [STAC catalog](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/export/stac.py): `src/cabrera_twin/export/stac.py`
- [Exported datasets](https://github.com/pstcricq/cabrera-mhw-twin/tree/main/data/exports): `data/exports`

### API service

- [HTTP API](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/src/cabrera_twin/api.py): `src/cabrera_twin/api.py`

### Dashboard

- [API client](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/common.py): `dashboard/common.py`
- [Overview](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/overview.py): `dashboard/overview.py`
- [Year explorer](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/year_explorer.py): `dashboard/year_explorer.py`
- [Trends and what-if](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/trends.py): `dashboard/trends.py`
- [Validation page](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/validation.py): `dashboard/validation.py`
- [Method and data](https://github.com/pstcricq/cabrera-mhw-twin/blob/main/dashboard/method.py): `dashboard/method.py`

### Other components

- **Copernicus Marine**
- **SOCIB station**
- **MPA boundary source**
- **Analyst**

## Connections

- Copernicus Marine → Satellite SST ingest: provides SST
- SOCIB station → Station ingest: provides observations
- MPA boundary source → Park boundary: provides boundary
- Satellite SST ingest → Processed series: writes SST
- Station ingest → Processed series: writes station data
- Park boundary → Processed series: writes boundary
- Build pipeline → Satellite SST ingest: opens SST
- Build pipeline → Park boundary: requests mask
- Build pipeline → Indicator computation: computes indicators
- Indicator computation → Heatwave detection: detects events
- Indicator computation → Warming scenarios: computes scenarios
- Indicator computation → Station ingest: reads station data
- Build pipeline → Parquet and metadata: writes results
- Build pipeline → STAC catalog: writes catalog
- Parquet and metadata → Exported datasets: writes tables
- STAC catalog → Exported datasets: writes catalog
- HTTP API → Exported datasets: queries exports
- HTTP API → Processed series: reads boundary and metadata
- API client → HTTP API: requests data
- Overview → API client: fetches data
- Year explorer → API client: fetches data
- Trends and what-if → API client: requests scenarios
- Validation page → API client: fetches data
- Method and data → API client: fetches data
- Analyst → Overview: views
- Analyst → Year explorer: explores year
- Analyst → Trends and what-if: tests warming
- Analyst → Validation page: checks validation
- Analyst → Method and data: reads method
