用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/kucherenko/petropowers --skill well-log-analysis命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
Generate realistic synthetic oil & gas data (LAS well logs, SEG-Y seismic, core photos, time-series) with proper physical constraints for testing, demos, and training.
Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
基于 SOC 职业分类
正在显示 SKILL.md
| name | well-log-analysis |
| description | 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']
else:
print("GR curve not found")
print(f"Available: {list(log.keys())}")
# Check depth unit
print(f"Index unit: {log.index_unit}") # 'm' or 'ft'
# Convert if needed
if log.index_unit == 'ft':
df = log.df()
df.index = df.index * 0.3048 # Convert to meters
# Check for null values
df = log.df()
null_value = log.null
print(f"Null value: {null_value}")
# Replace nulls
import numpy as np
df = df.replace(null_value, np.nan)
If user requests:
petropowers:oil-gas-delegationpetropowers:oil-gas-delegationpetropowers:oil-gas-delegation| Operation | Code |
|---|---|
| Read LAS | lasio.read('file.las') |
| Get DataFrame | log.df() |
| Access curve | log['GR'] or log.df()['GR'] |
| Get curve mnemonics | [c.mnemonic for c in log.curves] |
| Export CSV | log.to_csv('output.csv') |
| Write LAS | log.write('output.las') |
User: "Calculate porosity from this LAS file"
Agent:
import lasio
import numpy as np
log = lasio.read('well.las')
df = log.df()
# Density porosity
matrix = 2.65
fluid = 1.0
phi = (matrix - df['RHOB']) / (matrix - fluid)
print(f"Average porosity: {phi.mean():.2%}")
print(f"Porosity range: {phi.min():.2%} to {phi.max():.2%}")
Output:
Average porosity: 23.45%
Porosity range: 5.2% to 41.3%
OSDU uses standard schemas for well log data in the cloud:
| LAS Field | OSDU WellLog Field |
|---|---|
| WELL | FacilityName (via Well) |
| FLD | FieldName |
| DEPT | LogCurveDepth |
| GR, RHOB, NPHI | LogCurveData.Curves |
| Company | Operator |
import requests
headers = {
"Authorization": "Bearer <token>",
"data-partition-id": "mypartition"
}
# Get storage instructions
storage_resp = requests.post(
"https://api.osdu.com/api/dataset/v1/storageInstructions",
headers=headers,
json={
"kind": "osdu:wks:dataset--File.LAS:1.0.0",
"dataContentType": "text/plain"
}
)
# Upload file to provided URL
upload_url = storage_resp.json()["storageLocation"]["signedUrl"]
with open("well_log.las", "rb") as f:
requests.put(upload_url, data=f.read())
# Register dataset
register_resp = requests.post(
"https://api.osdu.com/api/dataset/v1/register",
headers=headers,
json={
"id": "dataset--File.LAS:1654321",
"kind": "osdu:wks:dataset--File.LAS:1.0.0"
}
)
import json
from datetime import datetime
def create_welllog_manifest(well_id, wellbore_id, curves, legal_tags):
"""Create OSDU manifest for well logs"""
# Map LAS curves to OSDU curves
curve_data = []
for curve in curves:
curve_data.append({
"CurveID": f"log-curve-{curve['mnemonic']}",
"CurveUnit": curve['unit'],
"LogCurveValues": curve['values']
})
manifest = {
"kind": "osdu:wks:Manifest:1.0.0",
"Data": {
"WorkProduct": {
"kind": "osdu:wks:work-product--WellLog:1.0.0",
"id": f"work-product--WellLog:{well_id}-{datetime.now().strftime('%Y%m%d')}",
"legal": legal_tags,
"data": {
"Name": f"Well Log {well_id}",
"WellboreID": f"master-data--Wellbore:{wellbore_id}",
"LogCurveDepth": {
"Start": curves[0]['start_depth'],
"End": curves[0]['end_depth'],
"Unit":
},
: {
: curve_data
}
}
}
}
}
json.dumps(manifest, indent=)
import lasio
import json
def las_to_osdu_welllog(las_file, wellbore_id, legal_tags):
"""Convert LAS file to OSDU WellLog schema"""
# Read LAS file
log = lasio.read(las_file)
# Extract curves
curves = []
for curve in log.curves:
curves.append({
"mnemonic": curve.mnemonic,
"unit": curve.unit,
"values": curve.data.tolist(),
"start_depth": log.index_min,
"end_depth": log.index_max
})
# Create manifest
manifest = create_welllog_manifest(
well_id=log.well['WELL'].value,
wellbore_id=wellbore_id,
curves=curves,
legal_tags=legal_tags
)
return manifest
# Example usage
manifest = las_to_osdu_welllog(
"well_001.las",
wellbore_id="master-data--Wellbore:wellbore-001",
legal_tags={"legaltags": ["my-legal-tag"], "otherRelevantDataCountries": ["US"]}
)
If user requests:
petropowers:oil-gas-delegationpetropowers:oil-gas-delegation