Complete well log evaluation workflow from LAS/DLIS loading through QC,
petrophysical analysis, lithology classification, and visualization.
Use when performing formation evaluation from well log data.
Complete well log evaluation workflow from LAS/DLIS loading through QC,
petrophysical analysis, lithology classification, and visualization.
Use when performing formation evaluation from well log data.
End-to-end pipeline for formation evaluation, from loading well log files
through quality control, petrophysical analysis, lithology classification,
and multi-dimensional visualization.
import lasio
import numpy as np
import pandas as pd
# Load LAS file
las = lasio.read('well_A.las')
df = las.df().reset_index() # DataFrame with depth as column
null_val = float(las.well['NULL'].value)
df = df.replace(null_val, np.nan)
# Inspect available curvesprint(las.curves.keys()) # ['DEPT', 'GR', 'RHOB', 'NPHI', 'RT', 'DT']
well_name = las.well[].value
'WELL'
import dlisio
# Load DLIS file (for modern well data)with dlisio.dlis.load('well_B.dlis') as files:
f = files[0]
for frame in f.frames:
print(frame.name, [ch.name for ch in frame.channels])
# Extract channels to numpy arrays
frame = f.frames[0]
depth = frame.channels[0].curves()
gr = frame.channels[1].curves()
Stage 2: QC and Preparation (welly)
from welly import Well, Curve
# Load well with welly (uses lasio internally)
w = Well.from_las('well_A.las')
# Access curves
gr = w.data['GR']
print(gr.start, gr.stop, gr.step)
# Despike gamma ray log
gr_clean = gr.despike(z=2.0) # Remove spikes > 2 std dev# Normalize to 0-1 range
gr_norm = (gr_clean - gr_clean.min()) / (gr_clean.max() - gr_clean.min())
# Resample curves to common depth basis
df_resampled = w.df(keys=['GR', 'RHOB', 'NPHI', 'RT'], step=0.5)
df_resampled = df_resampled.dropna()
import pyvista as pv
# 3D well path with property
trajectory = np.column_stack([
df['X'].values, df['Y'].values, df['DEPT'].values * -1
])
well_path = pv.Spline(trajectory, n_points=len(trajectory))
well_path['GR'] = df['GR'].values
well_path['Porosity'] = phi_density.values
plotter = pv.Plotter()
plotter.add_mesh(well_path, scalars='Porosity', cmap='viridis',
line_width=5, render_lines_as_tubes=True)
plotter.show()
Common Pipelines
Standard Formation Evaluation
- [ ] Load LAS file with `lasio.read()`, replace null values with NaN
- [ ] Inspect available curves (GR, RHOB, NPHI, RT, DT minimum)
- [ ] QC curves with welly: despike, check ranges, identify washouts (caliper)
- [ ] Calculate Vshale from GR (linear, Larionov, or Clavier method)
- [ ] Calculate porosity from density or neutron-density crossplot
- [ ] Calculate water saturation using Archie or dual-water model
- [ ] Estimate permeability from Timur-Coates or Wyllie-Rose
- [ ] Flag pay zones: phi > cutoff, Sw < cutoff, Vsh < cutoff
- [ ] Generate composite log plot (GR, resistivity, porosity, Sw, pay flag)
- [ ] Export results to LAS or CSV
Multi-Well Correlation
- [ ] Load multiple LAS files with lasio or welly batch loading
- [ ] Standardize curve mnemonics across wells (GR, GRGC, SGR -> GR)
- [ ] Normalize GR logs to common scale across wells
- [ ] Pick formation tops manually or from Vshale transitions
- [ ] Create striplog for each well with formation intervals
- [ ] Build correlation panel with matplotlib or pyvista
- [ ] Export formation tops to CSV
Quick Log QC
- [ ] Load LAS file with `lasio.read()`
- [ ] Check depth range, step, and null values
- [ ] Print curve statistics: min, max, mean, NaN count
- [ ] Flag out-of-range values (GR: 0-300, RHOB: 1.5-3.0, NPHI: -0.05-0.6)
- [ ] Check for constant or stuck readings
- [ ] Identify depth intervals with poor data (washout from caliper)
- [ ] Plot all curves for visual inspection
When to Use
Use the well log evaluation workflow when:
Performing formation evaluation from LAS or DLIS well log data