Shape catalogues of physical response signals: derivative preprocessing, banded DTW, PAM k-medoids, conformal assignment, RF/SHAP attribution. Pure-numpy core (Pyodide-safe).
Project description
pygeotypes — shape catalogues of physical response signals
pygeotypes builds a catalogue of behaviour types from response signals whose shape reflects
the underlying physical system — pressure transients of fractured reservoirs, hydrogeology pumping
tests, thermal response tests — and assigns new signals to that catalogue with statistical
guarantees. It packages the methodology of Kamel Targhi et al. (2026, Computational Geosciences,
DOI 10.1007/s10596-026-10459-w) as a reusable,
permissively-licensed library, and adds a conformal-prediction assignment layer on top.
Naming.
pip install pygeotypes·import pygeotypes— distribution and import match. The bare namegeotypesis taken on PyPI by an unrelated geospatial-utilities package; this library is unrelated to it and shares no module names with it. "GeoTypes" itself is the term of the methodology paper (the catalogue of flow-behaviour types).
Why this package exists (mid-2026 gap): scikit-learn-extra (k-medoids) is unmaintained, the
fast Rust kmedoids is GPL-3, tslearn/aeon drag numba/native dependencies that do not run in
Pyodide. The pygeotypes core is pure numpy/scipy — it runs unchanged offline and in the
browser (Pyodide) — with optional accelerated/attribution extras.
The pipeline
raw (t, p) signals
│ preprocess: log-resample → Bourdet derivative → p'' → normalize
▼
curves on a common log grid
│ distance: Sakoe-Chiba banded DTW (numpy DP; dtaidistance backend offline)
▼
pairwise distance matrix
│ cluster: PAM k-medoids (BUILD+SWAP, multi-init, seeded) + silhouette K-selection
▼
Catalogue (medoid curves + labels + provenance; exact JSON round-trip)
│ assign: nearest-medoid + split-conformal p-values / prediction sets / OOD flag
│ attribute (extra): RF + TreeSHAP + permutation cross-check + correlation pruning
▼
which behaviours exist · which one is this signal · what controls each behaviour
Install
pip install pygeotypes # pure core (numpy + scipy)
pip install pygeotypes[fast] # + dtaidistance (C-fast offline DTW matrices)
pip install pygeotypes[attr] # + scikit-learn + shap (attribution layer)
Quickstart
import numpy as np
from pygeotypes import (
generate_warren_root_ensemble, prepare_curves, dtw_matrix,
pam_kmedoids, select_k, build_catalogue, ConformalAssigner, nearest_medoid,
)
from pygeotypes.preprocess import prepare_curves
# 1. an ensemble of dual-porosity pressure responses (or bring your own curves)
ens = generate_warren_root_ensemble(200, seed=0)
t_list = [ens["tD"]] * 200
p_list = list(ens["curves"])
# 2. preprocess: common log grid + Bourdet derivative + z-score
t_grid, X = prepare_curves(t_list, p_list, n_points=96, derivative_order=1)
# 3. cluster into GeoTypes
D = dtw_matrix(X, window=10) # dtaidistance if installed, else numpy
diag = select_k(D, range(2, 9)) # silhouette + elbow diagnostics
res = pam_kmedoids(D, k=diag["best_k"], seed=0)
# 4. the persistent catalogue artifact
cat = build_catalogue(X, t_grid, D, k=res.k, dtw_window=10, result=res)
cat.to_json("catalogue.json")
# 5. assign a NEW curve — with conformal guarantees
assigner = ConformalAssigner(cat).fit(X_calibration, labels_calibration)
out = assigner.predict(new_curve, alpha=0.1)
out.point_prediction # nearest medoid
out.prediction_set # GeoTypes consistent with the curve at 90% coverage
out.out_of_catalogue # honest "this shape is not in the catalogue" flag
Modules
| Module | What | Deps |
|---|---|---|
pygeotypes.preprocess |
log resampling, Bourdet derivative (log-window L), second derivative p'', normalization, prepare_curves |
numpy |
pygeotypes.distance |
banded DTW (numpy DP), pairwise matrices (optional dtaidistance backend, parity-tested), live distances_to_references |
numpy (+fast) |
pygeotypes.cluster |
PAM k-medoids on precomputed distances, silhouette-from-distances, select_k |
numpy |
pygeotypes.catalogue |
the Catalogue artifact: medoids + labels + preprocessing + provenance, exact JSON round-trip |
numpy |
pygeotypes.assign |
nearest-medoid + ConformalAssigner (class-conditional split-conformal: p-values, prediction sets, OOD) |
numpy |
pygeotypes.attribute |
Spearman correlation pruning, RF with accuracy gate, TreeSHAP + permutation importance cross-check | [attr] |
pygeotypes.synthetic |
Warren-Root dual-porosity + homogeneous radial generators (Gaver-Stehfest inversion), seeded ensembles | numpy+scipy |
Guarantees & honesty
- Determinism: every stochastic step is seeded (
numpy.random.default_rng); same inputs + seed → identical catalogue, bit-for-bit. - Conformal validity: under exchangeability, prediction sets cover the true class with probability ≥ 1−α per class (class-conditional calibration). The empty set is reported as an out-of-catalogue flag, never silently replaced by the nearest medoid. Mind the finite-sample floor: the minimum achievable p-value is 1/(n_c+1), so α below that cannot produce empty sets.
- Attribution gate: if the Random Forest cannot predict the labels from the descriptors (held-out accuracy below the gate), SHAP/permutation importances are withheld — noise is not reported as insight. SHAP and permutation rankings are cross-checked (Spearman agreement).
- Physics validation: the synthetic generators are tested against closed-form limits
(homogeneous late-time
0.5(ln tD + 0.80907), derivative plateau 0.5, Warren-Root → homogeneous as ω→1, valley-depth monotonicity in ω).
Docs
- docs/theory.md — the science: PTA derivatives, DTW, PAM, conformal prediction, attribution pitfalls (with references)
- docs/quickstart.md — worked end-to-end example
- docs/design.md — package design, licensing rationale, Pyodide lane, API stability
Development
py -3.12 -m venv .venv && .venv/Scripts/pip install -e .[dev,attr,fast]
.venv/Scripts/python -m pytest # 32 tests: physics limits, DTW properties/parity, PAM recovery,
# conformal coverage + OOD, JSON round-trips, SHAP sanity
Versioning: CAOS X.XX.XXX display convention (CHANGELOG + git tags); PEP 440 in pyproject.toml.
Consumed by CAOS_RES_FlowDNA (FlowDNA).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pygeotypes-0.1.2.tar.gz.
File metadata
- Download URL: pygeotypes-0.1.2.tar.gz
- Upload date:
- Size: 30.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55f8cead0e21eeca194dab31db89aa3f0ee1b879d2cc00b50ed45a8ef81c4c4a
|
|
| MD5 |
936192aeb777a53076ab663d4de33883
|
|
| BLAKE2b-256 |
05ac1463b26d45b02b6f6fd2b369f1816e061ac6b90490a9cd727fd4b59b1d2c
|
Provenance
The following attestation bundles were made for pygeotypes-0.1.2.tar.gz:
Publisher:
publish-pypi.yml on fsantibanezleal/CAOS_GeoTypes
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pygeotypes-0.1.2.tar.gz -
Subject digest:
55f8cead0e21eeca194dab31db89aa3f0ee1b879d2cc00b50ed45a8ef81c4c4a - Sigstore transparency entry: 2064712785
- Sigstore integration time:
-
Permalink:
fsantibanezleal/CAOS_GeoTypes@172e7815f383601eae80652011b9cc2e1a397f99 -
Branch / Tag:
refs/tags/v0.01.002 - Owner: https://github.com/fsantibanezleal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@172e7815f383601eae80652011b9cc2e1a397f99 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pygeotypes-0.1.2-py3-none-any.whl.
File metadata
- Download URL: pygeotypes-0.1.2-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
890f09c1f385345e1e63b7fc760d824ee4a1992f7bf97649be1d093e406e9d1f
|
|
| MD5 |
5f62de4cf6e983382000a0d8c15e1f73
|
|
| BLAKE2b-256 |
3528fabf7ce2938e7c76e6af9585d69bd79e3a858fdf3e04140d49d6533e671e
|
Provenance
The following attestation bundles were made for pygeotypes-0.1.2-py3-none-any.whl:
Publisher:
publish-pypi.yml on fsantibanezleal/CAOS_GeoTypes
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pygeotypes-0.1.2-py3-none-any.whl -
Subject digest:
890f09c1f385345e1e63b7fc760d824ee4a1992f7bf97649be1d093e406e9d1f - Sigstore transparency entry: 2064712827
- Sigstore integration time:
-
Permalink:
fsantibanezleal/CAOS_GeoTypes@172e7815f383601eae80652011b9cc2e1a397f99 -
Branch / Tag:
refs/tags/v0.01.002 - Owner: https://github.com/fsantibanezleal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@172e7815f383601eae80652011b9cc2e1a397f99 -
Trigger Event:
release
-
Statement type: