CamPetro

Normalization to a Fixed Range or Value

On this page

Summary

Normalizing to a fixed range or value maps a curve onto targets chosen by the analyst, not onto a Key well. Percentile picks of the curve in a reference interval are tied to fixed values (a range), the median is moved to one fixed value, or the curve is expressed as a fraction between its low and high picks. Use it when there is no trusted key well, or when a downstream step expects a particular scale.

Inputs and outputs

Item Units
Input Curve value before normalization
Input Source low pick
Input Source middle pick
Input Source high pick
Input Reference low value
Input Reference middle value
Input Reference high value
Output Normalized curve value
Output Shifted value
Output Percent-range fraction

Equations

Let \(\nrmSrcLow\), \(\nrmSrcMid\) and \(\nrmSrcHigh\) be percentile picks of the curve in the reference interval, and let \(\nrmRefLow\), \(\nrmRefMid\) and \(\nrmRefHigh\) be fixed target values chosen by the analyst.

Scale to a fixed range. The two-point map of the previous page with fixed targets; the low pick goes to \(\nrmRefLow\) and the high pick to \(\nrmRefHigh\):

\[ \nrmOut = \nrmRefLow + \left(\nrmIn - \nrmSrcLow\right)\frac{\nrmRefHigh - \nrmRefLow}{\nrmSrcHigh - \nrmSrcLow} \]

Shift to a fixed value. The median is moved onto the target and nothing else changes:

\[ \nrmShifted = \nrmIn - \left(\nrmSrcMid - \nrmRefMid\right) \]

Percent-range scaling. The curve is expressed as the fraction of the distance from the low pick to the high pick. It is 0 at the low pick and 1 at the high pick, and it is not limited to the range 0 to 1:

\[ \nrmFrac = \frac{\nrmIn - \nrmSrcLow}{\nrmSrcHigh - \nrmSrcLow} \]

A constant curve (\(\nrmSrcHigh = \nrmSrcLow\)) has no usable range; the range map falls back to a pure shift and the fraction is set to 0. The percent-range fraction can be turned into the fixed-range result with \(\nrmOut = \nrmRefLow + \nrmFrac\left(\nrmRefHigh - \nrmRefLow\right)\).

Symbol Variable Units Typical range
\(x_{\mathrm{in}}\) Curve value before normalization
\(p_{\mathrm{lo}}\) Source low pick
\(p_{\mathrm{mid}}\) Source middle pick
\(p_{\mathrm{hi}}\) Source high pick
\(r_{\mathrm{lo}}\) Reference low value
\(r_{\mathrm{mid}}\) Reference middle value
\(r_{\mathrm{hi}}\) Reference high value
\(x_{\mathrm{norm}}\) Normalized curve value
\(x_{\mathrm{shift}}\) Shifted value
\(f_{\mathrm{n}}\) Percent-range fraction

Single-value calculator

Behavior

The three outputs treat the ends of the curve differently. With the default picks and targets, a reading of 0.30 maps to 0.302 with range scaling (about unchanged), 0.219 with the shift to a fixed median, and a fraction of 0.78. At the low end, a reading of 0.10 gives 0.078, 0.019 and 0.137, and a reading of 0.00 gives -0.034, -0.081 and -0.182: all three extrapolate linearly below the low pick and produce negative porosity unless they are clipped. At the high end a reading of 0.50 gives 0.525 with range scaling, so a curve that is not clipped will exceed the target maximum. The shift never changes the spread of the curve, while the range scaling changes it (by a factor of 1.12 in the worked example below).

Parameter guidance

Targets. Choose targets from something defensible: published or regional values for the zone, a matrix and shale response from the tool's own chart book, or a regional composite built from the best wells. For a gamma ray, common choices are a low target near the response of clean sand or carbonate and a high target near the response of the local shale. Do not tie the low pick to a theoretical zero unless the rock in the reference interval genuinely has none of the quantity.

Which pick goes where. Use the 5th and 95th percentile for the range and the 50th for the shift; the reasons and the effect of thickness are on Histogram and Percentile-Based Picks. A fixed value is the right choice when only an offset is in doubt; a fixed range when both the offset and the spread are. When a key well exists, the key-well form on Shift, Scale, and Shift-and-Scale is usually better because the target values come from real data from the same rock.

Clipping. Decide whether the result is clipped to the target range. Clipping a gamma ray to its range is usually harmless; clipping a porosity curve removes real information at the extremes.

Worked example

A synthetic neutron porosity curve over a clean-to-shaly interval, with no key well. The 5th, 50th and 95th percentiles are mapped to fixed values: 0.03 and 0.38 for the range, and 0.20 for the median. The same curve is also expressed as a percent-range fraction.

rng = np.random.default_rng(5)

# Synthetic neutron porosity (v/v) over a clean-to-shaly interval in a well with no key well.
clean = rng.random(500) < 0.4
nphi = np.where(clean, rng.normal(0.08, 0.02, 500), rng.normal(0.32, 0.04, 500))

p_lo, p_mid, p_hi = np.percentile(nphi, [5, 50, 95])
print(f"picks  P5 = {p_lo:.3f}   P50 = {p_mid:.3f}   P95 = {p_hi:.3f}")

# 1. Percent-range (0 to 1) scaling
frac = (nphi - p_lo) / (p_hi - p_lo)
print(f"percent-range: min {frac.min():.2f}, max {frac.max():.2f}, share outside 0-1 = {np.mean((frac < 0) | (frac > 1)):.1%}")

# 2. Scale to a fixed range: P5 -> 0.03 and P95 -> 0.38
t_lo, t_hi = 0.03, 0.38
out = t_lo + (nphi - p_lo) * (t_hi - t_lo) / (p_hi - p_lo)
print(f"fixed range : P5 {np.percentile(out, 5):.3f}, P95 {np.percentile(out, 95):.3f}  (targets {t_lo}, {t_hi})")

# 3. Shift to a fixed value: median -> 0.20
t_mid = 0.20
shifted = nphi - (p_mid - t_mid)
print(f"fixed value : median {np.median(shifted):.3f}  (target {t_mid}); spread unchanged: {np.std(shifted) / np.std(nphi):.2f}")
print(f"range scaling changed the spread by a factor {np.std(out) / np.std(nphi):.2f}")

Output

picks  P5 = 0.057   P50 = 0.281   P95 = 0.370
percent-range: min -0.09, max 1.16, share outside 0-1 = 10.0%
fixed range : P5 0.030, P95 0.380  (targets 0.03, 0.38)
fixed value : median 0.200  (target 0.2); spread unchanged: 1.00
range scaling changed the spread by a factor 1.12

Assumptions and limitations

  • The fixed targets are right for the reference interval. A wrong target is transferred to every sample of the well.
  • The reference interval has a distribution that justifies the choice of percentiles: it contains both low and high-end material for a range map.
  • Range scaling assumes the curve stretches or compresses uniformly between and beyond the picks. The extremes are extrapolated, and so are not trustworthy.
  • For the shift to a fixed value, the spread of the curve is already correct and only the offset needs fixing.
  • Forcing every well to the same range erases real differences between wells (for example, a shalier well will have the same P95 as a clean one).

QC checks

  • The percentiles of the output in the reference interval equal the targets (the 5th and 95th for range scaling, the 50th for the shift). This is a check on the arithmetic, not on the targets.
  • The output is in a plausible physical range everywhere: no negative porosity, no gamma ray below zero. Clip or revisit the targets if it is not.
  • Compare with an unnormalized well whose curve is believed good. The normalized well should land near it in similar rock.
  • Spread: if range scaling changed the standard deviation by more than about 20 percent, the picks may be unstable or the targets may disagree with the data.
  • Keep the targets and the picks in the project record so the normalization can be reproduced.

Going Deeper

Percent-range scaling is the same operation as the min-max scaling used in statistics and machine learning, with percentiles in place of the minimum and maximum so that outliers do not set the scale. The distinction between normalizing to a key well and to fixed values is a distinction in where the targets come from: a key well supplies targets that carry real information about the local rock, and a fixed target supplies only the analyst's assumption. In a basin with many wells and one trusted data set, building a regional composite from the best wells and normalizing every well to it is often the compromise.

References

  1. Shier, D.E., 2004. Well log normalization: methods and guidelines. Petrophysics, 45(3), 268–280.

Python reference implementation

Python reference implementation

The Python reference implementation is available to registered users with a verified email address. Register or sign in to view it.