CamPetro

Coal and Salt Identification

On this page

Summary

Coal and salt are real rocks with logging responses that look like a bad hole: low density, odd neutron and unusual slowness. They must be recognised first, or the bad-hole flags will null them out. Each is identified from a vote among several curves with characteristic values, and the thresholds depend on the tools and are only starting points.

Inputs and outputs

Item Units
Input Bulk density, Neutron porosity, Compressional slowness g/cm³, v/v, µs/ft
Input Gamma ray, Photoelectric factor (supporting evidence) gAPI, b/e
Output A coal flag and a salt flag (0 or 1)

Equations

Each rock is flagged by a vote among independent tests. For coal, using low density, high neutron and high slowness:

\[ N_{\mathrm{coal}} = \left[\rhob < \rho_{c}\right] + \left[\phiN > \phi_{c}\right] + \left[\dtc > \Delta t_{c}\right], \qquad \text{coal if } N_{\mathrm{coal}} \ge 2 \]

For salt (halite), using low density, near-zero neutron and a slowness inside a narrow window:

\[ N_{\mathrm{salt}} = \left[\rhob < \rho_{s}\right] + \left[\phiN < \phi_{s}\right] + \left[\Delta t_{s,1} < \dtc < \Delta t_{s,2}\right], \qquad \text{salt if } N_{\mathrm{salt}} \ge 2 \]

where \([\cdot]\) is 1 if the condition holds and 0 otherwise. Supporting evidence tightens the vote: coal has a very low photoelectric factor and salt a very low gamma ray, so adding \(\peFactor < P_{c}\) for coal or \(\GR < \mathrm{GR}_s\) for salt removes washouts that mimic the density and neutron. Wherever coal or salt is flagged the bad-hole flag is forced to zero, \(\badFlag = 0\).

Symbol Variable Units Typical range
\(\rho_b\) Bulk density g/cm³ 1.8 to 3.0
\(\phi_N\) Neutron porosity v/v -0.02 to 0.60
\(\Delta t\) Compressional slowness µs/ft 40 to 140
\(\mathrm{GR}\) Gamma ray gAPI 10 to 250
\(P_e\) Photoelectric factor b/e 1.8 to 5.1
\(F_{bh}\) Bad-hole flag
Bad hole

Single-value calculator

No calculator: identification is a vote over several curves and depends on the tool and formation. The worked example scores the rules on a synthetic table of five rock types.

Behavior

Two of three is a compromise. In the worked example (30 coal, 40 halite, 400 shale, 300 sandstone and 60 washout samples) the vote flags 29 of 30 coal samples and all 40 halite samples, and no shale or sandstone. But it also flags 10 of the 60 washout samples as coal, because a washout lowers the density and raises the neutron and the slowness in the same way coal does. Requiring a photoelectric factor below 1.0 b/e removes all 10 washout samples and costs one coal sample (28 of the 29 remain). The salt test is cleaner because halite has an unusual slowness window and a near-zero neutron response that few other rocks share.

Parameter guidance

Signatures. Typical log responses, from chart books and general practice, are starting points and depend on the tool and its vintage:

Density (g/cm³) Neutron (v/v, limestone scale) Sonic (µs/ft) GR PE (b/e) Other
Coal about 1.2 to 1.8 high, often above 0.4 high, often above 100 usually low, can be high very low, below about 1 high resistivity; hole often enlarged
Salt (halite) about 2.03 to 2.05 about 0.00 to -0.03 about 67 very low about 4.7 Very high resistivity; smooth caliper unless leached

Setting thresholds. Start with a coal density of about 2.0 g/cm³, neutron of about 0.45 to 0.60 and sonic of about 110 µs/ft, and salt density of about 2.05 g/cm³, neutron below about 0.03 and slowness between about 65 and 74 µs/ft, and adjust using a known coal or salt in the well or an offset well. A narrow slowness window is the most discriminating test for salt. Use the thresholds per formation: coal and salt are only expected in some zones, so apply the test only there.

Supporting curves. Add PE (coal below about 1 b/e) and GR (halite below about 15 to 20 gAPI) as extra conditions to reduce false flags. Resistivity can help but is affected by the same hole. A caliper that is enlarged in a coal bed or leached in salt agrees but does not discriminate.

Padding. Beds can be thin and the transition from coal or salt to the surrounding rock is blurred by the vertical resolution of the tools. Pad the flag by a few samples on each side so the boundary samples are treated as the same rock.

Order of operations. Identify coal and salt first, and exempt them from the bad-hole flags of Caliper-Based Flags and Log-Quality Flags. Use the coal and salt flags as a lithology mask in later steps: coal must not receive a shale or sand porosity model.

Worked example

A synthetic table with five rock types whose log responses overlap, as they do in real data. The two-of-three vote is scored on each, and PE is then used as an additional test for coal.

rng = np.random.default_rng(4)

# Synthetic class means and spreads (rhob g/cm3, nphi v/v limestone scale, dt us/ft, gr gAPI, pe b/e)
classes = {
    "shale":     dict(n=400, rhob=(2.50, 0.08), nphi=(0.30, 0.05), dt=(95, 10), gr=(110, 20), pe=(3.0, 0.4)),
    "sandstone": dict(n=300, rhob=(2.40, 0.06), nphi=(0.15, 0.04), dt=(80, 8),  gr=(35, 12),  pe=(1.9, 0.3)),
    "coal":      dict(n=30,  rhob=(1.60, 0.20), nphi=(0.55, 0.12), dt=(125, 15), gr=(30, 20), pe=(0.4, 0.3)),
    "halite":    dict(n=40,  rhob=(2.03, 0.03), nphi=(0.01, 0.02), dt=(67, 1.5), gr=(12, 5),  pe=(4.7, 0.2)),
    "washout":   dict(n=60,  rhob=(2.15, 0.12), nphi=(0.40, 0.08), dt=(110, 15), gr=(100, 25), pe=(3.5, 0.8)),
}
rows, labels = [], []
for name, c in classes.items():
    cols = [rng.normal(*c[k], c["n"]) for k in ("rhob", "nphi", "dt", "gr", "pe")]
    rows.append(np.column_stack(cols))
    labels += [name] * c["n"]
X = np.vstack(rows)
labels = np.array(labels)
rhob, nphi, dt, gr, pe = X.T

# Coal: two of three of low density, high neutron, high slowness
coal_votes = (rhob < 2.0).astype(int) + (nphi > 0.45) + (dt > 110)
coal = coal_votes >= 2
# Salt: two of three of low density, near-zero neutron, slowness inside the halite window
salt_votes = (rhob < 2.07).astype(int) + (nphi < 0.03) + ((dt > 65) & (dt < 74))
salt = salt_votes >= 2

print(f"{'class':10s} {'n':>4} {'coal flag':>10} {'salt flag':>10}")
for name in classes:
    m = labels == name
    print(f"{name:10s} {m.sum():4d} {coal[m].mean():10.1%} {salt[m].mean():10.1%}")

# A third, independent line of evidence: PE and GR
coal_pe = coal & (pe < 1.0)
print(f"\ncoal flags also with PE < 1.0 b/e: {coal_pe.sum()} of {coal.sum()}")
print(f"washout samples flagged as coal by the 2-of-3 vote: {coal[labels == 'washout'].sum()} of 60")
print(f"washout samples left after also requiring PE < 1.0: {coal_pe[labels == 'washout'].sum()} of 60")

Output

class         n  coal flag  salt flag
shale       400       0.0%       0.0%
sandstone   300       0.0%       0.0%
coal         30      96.7%       0.0%
halite       40       0.0%     100.0%
washout      60      16.7%       0.0%

coal flags also with PE < 1.0 b/e: 28 of 39
washout samples flagged as coal by the 2-of-3 vote: 10 of 60
washout samples left after also requiring PE < 1.0: 0 of 60

Assumptions and limitations

  • The tools read in the usual way. Tool vintage, hole size and mud change the apparent density and neutron of salt and coal.
  • Coal and salt are expected in the interval. The rules are not meant to search the whole well for them.
  • The neutron is on a limestone scale. A different scale changes the thresholds.
  • A washout in a shale produces a response similar to coal in the density and neutron. The distinction relies on PE, GR and the sonic.
  • Salt is halite. Other evaporites (anhydrite, gypsum, potash, carnallite) have different responses and need separate tests.

QC checks

  • Flags are zones, not isolated samples. A flag that appears on a single sample is probably a spike.
  • The coal and salt flags agree with core, cuttings or a mud log where available.
  • No flags in the middle of clean sandstone or shale, and none where the other curves disagree (a very low gamma ray in salt but a high one in the flagged zone).
  • A flagged coal has a low PE and a high resistivity; a flagged salt has a low GR, a smooth caliper and a slowness near 67 µs/ft.
  • Flagged zones are excluded from the bad-hole flags and nulling, and carry their own lithology code.

Going Deeper

Coal and salt are among the few rocks for which logs give a nearly unambiguous answer, because their physical properties are unusual: coal is low density and rich in hydrogen, and halite has no hydrogen, a known density and a distinctive sonic velocity. The difficulty is not in the rocks but in their confusion with a bad hole, which produces readings of the same kind from different causes. A flag based on one curve is therefore avoided; a vote among several is the standard compromise. Where a project has a lithology interpretation from other sources, such as mud logs or cuttings, it can replace the log-based flag with something more reliable.

References

  1. Asquith, G. and Krygowski, D., 2004. Basic Well Log Analysis, 2nd edition. AAPG Methods in Exploration Series 16, American Association of Petroleum Geologists, Tulsa, OK.
  2. Rider, M. and Kennedy, M., 2011. The Geological Interpretation of Well Logs, 3rd edition. Rider-French Consulting Ltd, Sutherland, UK.

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.