Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions LIBRARY_MERGE_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ implementations of shared concepts), and an evaluation of three competing migrat
architectures scored independently for migration safety, end-state quality, and
single-maintainer execution realism.

> **Status — July 2026: executed to completion.** All eleven domain trains are merged:
> `flow_transport`, `nmr`, `porosity_lithology`, `acoustic_geomech`, `geochem_fluids`,
> `em_dielectric`, `nuclear`, `inversion_numerics`, the depth/imaging group
> (`depth_matching`, `depth_correction`, `borehole_image`, `wellbore_geometry`),
> `integrity_drilling`, and `data_qc_io` — plus the earlier foundation modules
> (`constants`, `units`, `ml_stats`, `saturation_resistivity`, `capillary_pressure`,
> `relperm_wettability`, `testing`). Every adoption PR was verified byte-identical on
> stdout against the pre-change article, alongside the four regression gates below.
> Scope deltas vs. the section-7 sketches are documented in the PR bodies; the largest:
> the planned `data_qc_io` `units.py`/`metrics.py`/`align.py`/`pay.py` files were
> dropped because `petrolib.units`, `petrolib.ml_stats`, `petrolib.depth_matching`,
> and `petrolib.porosity_lithology` already covered them (`detect_bed_boundaries`
> lives in `data_qc_io.filt`). Corpus forms that are not bit-reproducible from the
> canonical API (e.g. `+1e-10`/`+1e-12` guard variants, scipy-kernel smoothers,
> legacy `RandomState` generators) deliberately remain local to their articles.

---

## 1. Summary of the recommendation
Expand Down
11 changes: 7 additions & 4 deletions petrolib/data_qc_io/scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import numpy as np
from numpy.typing import ArrayLike, NDArray

from .. import ml_stats

_Float = NDArray[np.float64]


Expand All @@ -34,16 +36,17 @@ def normalize_to_reference(
``in_lo``/``in_hi`` are the input-well endpoints; when omitted they are
taken as the ``pct`` percentiles of ``x`` (the Shier 5th/95th convention),
or the min/max when ``pct=None`` (the image-histogram convention). No
clipping is applied. Sources: src2021_12/article01 (normalize_reference),
src2016_12/article6 (histogram_normalize), src2015_04/article4
(histogram_scale).
clipping is applied. The affine map itself is
:func:`petrolib.ml_stats.affine_rescale` (bit-identical arrangement).
Sources: src2021_12/article01 (normalize_reference), src2016_12/article6
(histogram_normalize), src2015_04/article4 (histogram_scale).
"""
v = _arr(x)
if in_lo is None:
in_lo = float(np.percentile(v, pct[0])) if pct is not None else float(np.min(v))
if in_hi is None:
in_hi = float(np.percentile(v, pct[1])) if pct is not None else float(np.max(v))
return np.asarray(ref_lo + (ref_hi - ref_lo) * (v - in_lo) / (in_hi - in_lo))
return ml_stats.affine_rescale(v, src_lo=in_lo, src_hi=in_hi, dst_lo=ref_lo, dst_hi=ref_hi)


def match_moments(x: ArrayLike, target_mean: float, target_std: float) -> _Float:
Expand Down
Loading