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
10 changes: 1 addition & 9 deletions src2020_10/article3_cavein_clustering_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,7 @@

def rolling_cv(rhob, wr):
"""Rolling coefficient of variation of bulk density over +/- wr (Eq. 5)."""
rhob = np.asarray(rhob, float)
n = len(rhob)
cv = np.zeros(n)
for i in range(n):
lo, hi = max(0, i - wr), min(n, i + wr + 1)
w = rhob[lo:hi]
m = w.mean()
cv[i] = w.std() / m if m != 0 else 0.0
return cv
return petrolib.data_qc_io.filt.moving_stat(rhob, 2 * wr + 1, "cv")


def caliper_excess(caliper, bit_size):
Expand Down
2 changes: 1 addition & 1 deletion src2021_04/article5_nmr_fluid_contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def classify_fluid(D, gas_D=1e-8, oil_D=5e-10):

def stacking_snr(base_snr, n_stacks):
"""Station stacking improves SNR as sqrt(number of stacked acquisitions)."""
return base_snr * np.sqrt(n_stacks)
return float(base_snr * petrolib.data_qc_io.signal.stack_gain(n_stacks))


# ---------------------------------------------- tests --------------
Expand Down
20 changes: 6 additions & 14 deletions src2021_12/article01_data_quality_ml.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def zscore(x):

def zscore_outliers(x, threshold=3.0):
"""Boolean outlier mask using |z| > threshold (default 3 -> 99.7%)."""
return np.abs(zscore(x)) > threshold
return petrolib.data_qc_io.clean.outlier_mask(x, "zscore", threshold=threshold)


# ---------------------------------------------- Eq. 2: IQR --------------
Expand All @@ -64,9 +64,7 @@ def iqr_bounds(x, k=1.5):


def iqr_outliers(x, k=1.5):
lo, hi = iqr_bounds(x, k)
x = np.asarray(x, float)
return (x < lo) | (x > hi)
return petrolib.data_qc_io.clean.outlier_mask(x, "iqr", k=k)


# ---------------------------------------------- Eqs. 3-4: normalize -----
Expand All @@ -82,8 +80,8 @@ def normalize_reference(v, R_min, R_max, W_min, W_max):
V_norm = R_min + (R_max - R_min) * (V - W_min)/(W_max - W_min).
R_* are reference-well 5th/95th percentiles, W_* the target well's.
"""
v = np.asarray(v, float)
return R_min + (R_max - R_min) * (v - W_min) / (W_max - W_min)
return petrolib.data_qc_io.scale.normalize_to_reference(
v, R_min, R_max, in_lo=W_min, in_hi=W_max)


# ---------------------------------------------- Eqs. 5-6: P / R ---------
Expand Down Expand Up @@ -114,10 +112,7 @@ def rmse(y_true, y_pred):

def add_gaussian_noise(x, sigma_fraction, rng=None):
"""Add N(0, sigma^2) noise with sigma = fraction * mean(|x|) (Eqs. 9-10)."""
x = np.asarray(x, float)
rng = rng or np.random.default_rng(0)
sigma = sigma_fraction * np.abs(x).mean()
return x + rng.normal(0.0, sigma, size=x.shape)
return petrolib.data_qc_io.signal.add_gaussian_noise(x, sigma_fraction, rng)


# ---------------------------------------------- Eq. 11: Pearson ---------
Expand All @@ -132,10 +127,7 @@ def pearson(x, y):

def sentinels_to_nan(x, sentinels=SENTINELS):
"""Replace LAS/DLIS no-data sentinels with NaN."""
x = np.asarray(x, float).copy()
for s in sentinels:
x[np.isclose(x, s)] = np.nan
return x
return petrolib.data_qc_io.clean.sentinels_to_nan(x, sentinels)


# ---------------------------------------------- tests --------------
Expand Down
31 changes: 11 additions & 20 deletions src2022_08/article5_cpa_fcm_logfacies.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@

import numpy as np

try:
import petrolib
except ImportError: # bare clone, not installed
import sys, pathlib
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
import petrolib


# -------------------------------------------- CPA (Eqs. 1-5) --------------

Expand Down Expand Up @@ -135,26 +142,10 @@ def fcm(X, c=5, m=2.0, n_iter=200, tol=1e-5, seed=0):

def synth_log_suite(n=600, n_facies=4, seed=0):
"""Five-log suite (GR, RD, DEN, AT, NP) with `n_facies` blocks."""
rng = np.random.default_rng(seed)
bp_true = sorted(rng.choice(np.arange(40, n - 40), n_facies - 1,
replace=False))
bp_full = [0] + list(bp_true) + [n]
facies_props = np.array([
[ 22.0, 80.0, 2.45, 75.0, 0.08], # facies 0: granitic, low GR
[ 75.0, 10.0, 2.20, 95.0, 0.30], # facies 1: shale
[ 35.0, 200.0, 2.60, 65.0, 0.05], # facies 2: fractured granite
[ 50.0, 30.0, 2.40, 80.0, 0.15], # facies 3: weathered
])
facies_labels = np.zeros(n, dtype=int)
out = np.zeros((n, 5))
for k, (a, b) in enumerate(zip(bp_full[:-1], bp_full[1:])):
fac = k % n_facies
facies_labels[a:b] = fac
for j in range(5):
mu = facies_props[fac, j]
sigma = 0.05 * abs(mu) + 1e-3
out[a:b, j] = rng.normal(mu, sigma, b - a)
return out, np.array(bp_true), facies_labels
logs, bp_true, facies_labels = petrolib.data_qc_io.synth.log_suite(
n, n_facies, rng=np.random.default_rng(seed))
out = np.column_stack([logs[c] for c in petrolib.data_qc_io.synth.LOG_SUITE_CURVES])
return out, bp_true, facies_labels


# -------------------------------------------- tests ----------------------
Expand Down
Loading