Read, analyze, and manipulate well log data in LAS format using lasio library.
Read, analyze, and manipulate well log data in LAS format using lasio library.
Handle well log operations across all oil & gas pipeline skills. Provides code patterns for reading LAS files, extracting metadata, performing petrophysical calculations, and exporting data.
Primary source: lasio documentation
Library: lasio
Related packages:
pip install lasio pandas matplotlib numpy
import lasio
# Read LAS file
log = lasio.read('well_log.las')
# Access well metadata
print(f"Well: {log.well['WELL'].value}")
print(f"Field: {log.well['FLD'].value if 'FLD' in log.well else 'N/A'}")
print(f"Company: {log.well['COMP'].value if 'COMP' in log.well else 'N/A'}")
# Access curve data
print(f"Curves: {[curve.mnemonic for curve in log.curves]}")
print(f"Depth range: {log.index_min} to {log.index_max} {log.index_unit}")
import lasio
import pandas as pd
log = lasio.read('well_log.las')
# Convert to pandas DataFrame
df = log.df()
# Access specific curves
depth = df.index
gamma_ray = df['GR']
density = df['RHOB']
neutron = df['NPHI']
print(df.head())
import lasio
log = lasio.read('well_log.las')
# Version section
print(f"Version: {log.version['VERS'].value}")
print(f"Wrap: {log.version['WRAP'].value}")
# Well section
print(log.well)
# Parameters section
print(log.params)
# Other section
for item in log.other:
print(item)
# Curves section
for curve in log.curves:
print(f"{curve.mnemonic}: {curve.unit} - {curve.descr}")
import lasio
import numpy as np
log = lasio.read('well_log.las')
df = log.df()
# Calculate porosity from density
# Phi = (matrix - bulk) / (matrix - fluid)
matrix_density = 2.65 # g/cc (sandstone)
fluid_density = 1.0 # g/cc (water)
bulk_density = df['RHOB'].values
porosity = (matrix_density - bulk_density) / (matrix_density - fluid_density)
porosity = np.clip(porosity, 0, 0.5) # Clamp to reasonable range
print(f"Average porosity: {porosity.mean():.2%}")
# Calculate water saturation (Archie equation)
# Sw = ((a * Rw) / (Phi^m * Rt))^(1/n)
a = 1.0
m = 2.0
n = 2.0
Rw = 0.1 # ohm-m (formation water resistivity)
phi = porosity
Rt = df['RT'].values # true resistivity
Sw = ((a * Rw) / (phi**m * Rt))**(1/n)
Sw = np.clip(Sw, 0, 1)
print(f"Average water saturation: {Sw.mean():.2%}")
# Calculate shale volume from gamma ray
GR = df['GR'].values
GR_min = GR.min()
GR_max = GR.max()
Vsh = (GR - GR_min) / (GR_max - GR_min)
Vsh = np.clip(Vsh, 0, 1)
print(f"Average shale volume: {Vsh.mean():.2%}")
import lasio
import matplotlib.pyplot as plt
log = lasio.read('well_log.las')
df = log.df()
fig, axes = plt.subplots(1, 4, figsize=(15, 10), sharey=True)
# Gamma Ray
axes[0].plot(df['GR'], df.index)
axes[0].set_xlabel('GR (API)')
axes[0].set_ylabel('Depth (m)')
axes[0].invert_yaxis()
axes[0].grid(True, alpha=0.3)
# Resistivity
axes[1].semilogx(df['RT'], df.index)
axes[1].set_xlabel('RT (ohm-m)')
axes[1].grid(True, alpha=0.3)
# Density-Neutron
axes[2].plot(df['RHOB'], df.index, label='RHOB')
axes[2].set_xlabel('RHOB (g/cc)')
axes[2].grid(True, alpha=0.3)
# Caliper
axes[3].plot(df['CALI'], df.index)
axes[3].set_xlabel('CALI (in)')
axes[3].grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('well_logs.png', dpi=150)
import lasio
log = lasio.read('well_log.las')
# Export to CSV
log.to_csv('output.csv')
# Export to Excel
log.to_excel('output.xlsx')
# Write new LAS file
log.write('modified.las')
import lasio
# Read malformed LAS files
log = lasio.read('problematic.las', ignore_header_errors=True)
# Handle encoding issues
log = lasio.read('file.las', encoding='latin-1')
# Read only headers (fast for large files)
log = lasio.read('large.las', read_policy=[])
# Custom null policy
log = lasio.read('file.las', null_policy='common')
import lasio
import numpy as np
from lasio import LASFile, CurveItem, HeaderItem
# Create new LAS file
las = LASFile()
# Add well metadata
las.well.append(HeaderItem('WELL', value='Well-001'))
las.well.append(HeaderItem('FLD', value='Test Field'))
las.well.append(HeaderItem('LOC', value='North Sea'))
las.well.append(HeaderItem('SRVC', value='Acme Logging'))
# Add curves
depths = np.arange(1000, 2000, 0.5)
gr = np.random.uniform(20, 150, len(depths))
rhob = np.random.uniform(2.2, 2.7, len(depths))
las.add_curve('DEPT', depths, unit='m')
las.add_curve('GR', gr, unit='API', descr='Gamma Ray')
las.add_curve('RHOB', rhob, unit='g/cc', descr='Bulk Density')
# Write file
las.write('new_well.las')
Used by:
oil-gas-pipelines/exploration - Formation evaluation, log correlationoil-gas-pipelines/drilling - Real-time LWD interpretationoil-gas-pipelines/reservoir-production - Reservoir characterization# Check if curve exists
if 'GR' in log.keys():
gr = log['GR']