Metadata-Version: 2.4
Name: nsevt
Version: 0.3.2
Summary: Peaks-over-threshold GPD tail inference with continuous and interval-censored (grouped) fits, profile-likelihood intervals for shape and endpoint, permutation trend tests, power/MDE, and multi-source robustness.
Author-email: Elí Gaiska Salomón-Guzmán <salomon.eli@colpos.mx>
Maintainer-email: Elí Gaiska Salomón-Guzmán <salomon.eli@colpos.mx>
License-Expression: MIT
Project-URL: Homepage, https://github.com/GaiskaSalomon/nsevt
Project-URL: Repository, https://github.com/GaiskaSalomon/nsevt
Project-URL: Issues, https://github.com/GaiskaSalomon/nsevt/issues
Keywords: extreme value theory,generalized Pareto,non-stationarity,permutation test,power analysis,climate extremes
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.22
Requires-Dist: scipy>=1.7
Provides-Extra: demo
Requires-Dist: streamlit>=1.30; extra == "demo"
Requires-Dist: pandas>=1.3; extra == "demo"
Requires-Dist: matplotlib>=3.5; extra == "demo"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-cov>=4.0; extra == "test"
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.12; extra == "dev"
Dynamic: license-file

# nsevt — non-stationary extreme-value tail inference

[![CI](https://github.com/GaiskaSalomon/nsevt/actions/workflows/ci.yml/badge.svg)](https://github.com/GaiskaSalomon/nsevt/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/nsevt.svg)](https://pypi.org/project/nsevt/)
[![Python versions](https://img.shields.io/pypi/pyversions/nsevt.svg)](https://pypi.org/project/nsevt/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![DOI](https://zenodo.org/badge/1328485209.svg)](https://zenodo.org/badge/latestdoi/1328485209)

`nsevt` is a dependency-light Python package for four connected tasks:

1. peaks-over-threshold generalized Pareto (GPD) estimation with an adaptive
   profile-likelihood interval for shape;
2. a likelihood-ratio trend test calibrated by complete-block label
   permutation;
3. Monte Carlo power and signed minimum-detectable-effect (MDE) analysis; and
4. a pre-specified multi-source robustness analysis that distinguishes
   non-reproduction with adequate power from an unresolved comparison.

The package uses deliberately measured terminology. A negative GPD shape point
estimate gives a finite **model-conditional statistical endpoint**. `nsevt`
reports support for a negative shape only when the entire 95% profile interval
lies below zero; neither result is called a physical ceiling.

## Install

From PyPI:

```bash
pip install nsevt
```

For development or the optional Streamlit demonstration:

```bash
git clone https://github.com/GaiskaSalomon/nsevt.git
cd nsevt
pip install -e ".[dev,demo]"
```

## Quick start

```python
import numpy as np
import nsevt

rng = np.random.default_rng(7)
threshold, xi, sigma = 40.0, -0.25, 10.0
years = np.repeat(np.arange(1980, 2030), 12)
uniform = rng.uniform(size=years.size)
excess = sigma / xi * ((1 - uniform) ** (-xi) - 1)
values = threshold + excess

fit = nsevt.gpd_pot(values, threshold=threshold, n_boot=300)
print(fit.summary())
print("negative-shape estimate:", fit.bounded_estimate)
print("negative shape supported by 95% CI:", fit.bounded_supported)

trend = nsevt.trend_permutation(excess, years, n_perm=999)
print("LR permutation p:", trend["p_permutation"],
      "+/-", trend["p_permutation_mcse"])

mde = nsevt.min_detectable_effect(
    excess, years, direction="both", n_rep=200, n_perm_calibration=499
)
print("positive MDE:", mde["mde_positive"])
print("negative MDE:", mde["mde_negative"])
```

## Multi-source robustness

Sources must be genuinely distinct products with comparable temporal support;
early and late halves of one record are not substitutes.

```python
result = nsevt.multisource_robustness(
    [("product A", values_a, years_a),
     ("product B", values_b, years_b)],
    threshold=40,
    reference="product A",
)
print(result.trend_status)
print(result.table())
```

Possible trend statuses include `reproduced`, `inconsistent_direction`,
`not_reproduced_with_power`, `not_resolved`, and `no_reference_signal`. Agreement
or disagreement across sources is a robustness result; it does not by itself
attribute a discrepancy to instruments, homogenization, or physical change.

## Stable and experimental functionality

| status | module | purpose |
|---|---|---|
| stable | `nsevt.gpd` | GPD fit, profile interval, conditional endpoint bootstrap, return levels |
| stable | `nsevt.trend` | LR block-label permutation, power/MDE, descriptive block-bootstrap interval |
| stable | `nsevt.transportability` | multi-source robustness and power-aware status |
| stable with assumptions | `split_conformal` | upper tail bound for exchangeable calibration scores |
| experimental | `block_conformal` | block-aggregate dependence sensitivity diagnostic |
| experimental | `twoscale_trend` | residual-bootstrap distribution-valued trend diagnostic |
| experimental | `wasserstein_decomposition` | numerical quantile-grid energy decomposition |

The exact assumptions and claim boundaries are documented in
[`docs/assumptions.md`](docs/assumptions.md). Experimental APIs are retained for
evaluation but are not part of the package's central inferential claim.

## Reproducibility and tests

The implementation was adapted from research pipelines and then regression-
checked; it is not represented as a verbatim copy. Randomized routines accept a
seed and report the number of successful replicates. Run the validation suite
with:

```bash
pip install -e ".[dev]"
ruff check src tests demo
pytest --cov=nsevt --cov-report=term-missing --cov-fail-under=80
python -m build
python -m twine check dist/*
```

See [`docs/validation.md`](docs/validation.md) for what each test establishes
and, equally importantly, what it does not establish.

## Citation and license

Use [`CITATION.cff`](CITATION.cff) or the Zenodo DOI shown above. `nsevt` is
released under the MIT License; see [`LICENSE`](LICENSE).
