mcpField
D
dlisio

dlisio

github.com/steadfastasartData & databases7359 installsUpdated 6w ago
Repository

About dlisio

dlisio is a Python library for reading binary RP66 DLIS and LIS79 well-log data into structured arrays and metadata objects. It does not write DLIS; its bundled helper supports controlled export of selected scalar curves to LAS while accounting for depth handling and lossy conversion.

Key features

  1. 01Read DLIS and LIS79 files
  2. 02Inspect logical files and frames
  3. 03Extract scalar and array channels
  4. 04Preserve channel metadata and dimensions
  5. 05Controlled LAS export of scalar curves

Use cases

  1. 01Inspect well logs with multiple logical files
  2. 02Read channels with duplicate names
  3. 03Export depth and measurement curves to LAS

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/steadfastasart/geoscience-skills --skill dlisio

After installing, type/dlisioin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
dlis_structure.md
frame_channels.md
scripts/
dlis_to_las.py

Details

From the project README

DLIS/LIS reading and controlled LAS export

Use dlisio for binary RP66 DLIS and LIS79 input. It returns structured NumPy arrays and metadata objects; it does not write DLIS. Use lasio for LAS.

Select a logical file and frame

Inspect the physical file before selecting data. Logical files and frames may have different depths, sampling rates and channel identities. dlis.load() returns a PhysicalFile context manager, not a generator. Read array data inside the context, then retain copied arrays or DataFrames after closing it.

from dlisio import dlis

def inventory(path):
    items = []
    with dlis.load(str(path)) as files:
        for logical_index, logical in enumerate(files):
            for frame_index, frame in enumerate(logical.frames):
                items.append({
                    'logical_file': logical_index, 'frame': frame_index,
                    'fingerprint': frame.fingerprint,
                    'index_type': frame.index_type, 'index': frame.index,
                    'channels': [(ch.fingerprint, ch.units, ch.dimension)
                                 for ch in frame.channels],
                })
    return items

A channel's identity includes type, mnemonic, origin and copy number. Names alone need not be unique. Use channel.fingerprint to access its array field; frame.curves() uses fingerprints as dtype titles even when names are disambiguated. The FRAMENO field records frame sequence numbers, not measured depth.

Read scalar and array channels

from dlisio import dlis
import pandas as pd

def read_frame(path, logical_file_index=0, frame_index=0):
    with dlis.load(str(path)) as files:
        if not 0 <= logical_file_index < len(files):
            raise ValueError('Logical file index out of range')
        logical = files[logical_file_index]
        if not 0 <= frame_index < len(logical.frames):
            raise ValueError('Frame index out of range')
        frame = logical.frames[frame_index]
        records = frame.curves()
        scalar = {name: records[name].copy() for name in records.dtype.names
                  if records[name].ndim == 1}
        arrays = {ch.fingerprint: records[ch.fingerprint].copy()
                  for ch in frame.channels if records[ch.fingerprint].ndim > 1}
        metadata = {'frame': frame.fingerprint, 'index_type': frame.index_type,
                    'index': frame.index,
                    'channels': {ch.fingerprint: {'name': ch.name, 'units': ch.units,
                                 'dimension': ch.dimension} for ch in frame.channels}}
        return pd.DataFrame(scalar), arrays, metadata

Keep array/image channels as arrays, preserving all trailing dimensions. A structured array has dtype.names, not .items(). Direct DataFrame conversion fails when it contains multidimensional fields. Do not average image channels into scalars without a requested, documented reduction.

Depth, missing values and conversion

  • Check frame.index_type and the first channel's units before declaring an index to be depth. A time channel or FRAMENO is not a depth surrogate.
  • Preserve increasing or decreasing depth order. Duplicate/nonmonotonic depths need explicit handling; do not silently sort or resample different passes.
  • DLIS has no universal LAS-style null sentinel. Retain NaNs and apply a vendor null marker only when its meaning is documented. Preserve masks through export.
  • Read frame and channel handling for identity, searching and separate lossless array export. Read file structure and LIS for metadata, encodings and the separate LIS API.

The bundled DLIS-to-LAS helper always includes a validated depth curve first, even when --curves requests only measurements. It accepts a unique mnemonic or full fingerprint, preserves m/ft and depth order, and writes STEP=0 for irregular sampling. Arrays are excluded with a diagnostic by default; explicitly requesting one fails instead of discarding it. LAS is a lossy representation of DLIS metadata and multidimensional samples.

python scripts/dlis_to_las.py well.dlis --list
python scripts/dlis_to_las.py well.dlis scalar.las --logical-file 0 --frame 0 --curves GR

Resolve the script path relative to this installed skill directory. For a non-depth-indexed frame, require an explicit --depth-channel. Supported export depth units are m and ft; other units need a documented conversion. --null-value records the operator's choice of a known vendor sentinel.

Verification scope

Checked with dlisio 1.0.4 using project-generated binary DLIS, including multiple logical files/frames, duplicate mnemonics, scalar/array channels, NaNs and LAS roundtrips. These synthetic files are project-owned, not redistributed field logs. LIS, damaged-file recovery and vendor-specific records need their own fixtures; do not claim those branches were exercised by the DLIS tests.

Official DLIS API, checked 2026-09-14. Use strict parsing unless an explicit, recorded recovery decision justifies relaxing it; errors must not be reported as successful empty exports.

Comments

Markdown supported