API Reference

Data Converters

Seismic Data

Note

By default, the SEG-Y ingestion tool uses Python’s multiprocessing to speed up parsing the data. This almost always requires a __main__ guard on any other Python code that is executed directly like python file.py. When running inside Jupyter, this is NOT needed.

1if __name__ == "__main__":
2    segy_to_mdio(...)

When the CLI is invoked, this is already handled.

See the official multiprocessing documentation here and here.

Conversion from SEG-Y to MDIO v1 format.

mdio.converters.segy.segy_to_mdio(segy_spec, mdio_template, input_path, output_path, overwrite=False, grid_overrides=None, segy_header_overrides=None)

A function that converts a SEG-Y file to an MDIO v1 file.

Ingest a SEG-Y file according to the segy_spec. This could be a spec from registry or custom.

Parameters:
  • segy_spec (SegySpec) – The SEG-Y specification to use for the conversion.

  • mdio_template (AbstractDatasetTemplate) – The MDIO template to use for the conversion.

  • input_path (UPath | Path | str) – The universal path of the input SEG-Y file.

  • output_path (UPath | Path | str) – The universal path for the output MDIO v1 file.

  • overwrite (bool) – Whether to overwrite the output file if it already exists. Defaults to False.

  • grid_overrides (GridOverrides | dict[str, Any] | None) – Option to add grid overrides. Prefer a mdio.GridOverrides instance; dict is still accepted (deprecated as of 1.2, planned for removal in a future release) but logs a deprecation warning.

  • segy_header_overrides (SegyHeaderOverrides | None) – Option to override specific SEG-Y headers during ingestion.

Return type:

None

Conversion from to MDIO various other formats.

mdio.converters.mdio.mdio_to_segy(segy_spec, input_path, output_path, selection_mask=None, client=None)

Convert MDIO file to SEG-Y format.

We export N-D seismic data to the flattened SEG-Y format used in data transmission.

The input headers are preserved as is, and will be transferred to the output file.

Input MDIO can be local or cloud based. However, the output SEG-Y will be generated locally.

A selection_mask can be provided (same shape as spatial grid) to export a subset.

Parameters:
  • segy_spec (SegySpec) – The SEG-Y specification to use for the conversion.

  • input_path (UPath | Path | str) – Store or URL (and cloud options) for MDIO file.

  • output_path (UPath | Path | str) – Path to the output SEG-Y file.

  • selection_mask (np.ndarray) – Array that lists the subset of traces

  • client (distributed.Client) – Dask client. If None we will use local threaded scheduler. If auto is used we will create multiple processes (with 8 threads each).

Raises:
  • ImportError – if distributed package isn’t installed but requested.

  • ValueError – if cut mask is empty, i.e. no traces will be written.

Return type:

None

Examples

To export an existing local MDIO file to SEG-Y we use the code snippet below. This will export the full MDIO (without padding) to SEG-Y format.

>>> from upath import UPath
>>> from mdio import mdio_to_segy
>>>
>>> input_path = UPath("prefix2/file.mdio")
>>> output_path = UPath("prefix/file.segy")
>>> mdio_to_segy(input_path, output_path)

Grid Overrides

pydantic model mdio.GridOverrides

Type-safe configuration for grid override operations during SEG-Y ingestion.

Show JSON schema
{
   "title": "GridOverrides",
   "description": "Type-safe configuration for grid override operations during SEG-Y ingestion.",
   "type": "object",
   "properties": {
      "AutoChannelWrap": {
         "default": false,
         "description": "Streamer: auto-detect channel-wrap geometry (Type A vs B).",
         "title": "Autochannelwrap",
         "type": "boolean"
      },
      "AutoShotWrap": {
         "default": false,
         "description": "Streamer: derive dense shot_index from interleaved shot_point values.",
         "title": "Autoshotwrap",
         "type": "boolean"
      },
      "CalculateShotIndex": {
         "default": false,
         "description": "OBN: derive dense shot_index from sparse shot_point values per shot_line.",
         "title": "Calculateshotindex",
         "type": "boolean"
      },
      "NonBinned": {
         "default": false,
         "description": "Collapse selected dims into a single trace dimension without spatial binning.",
         "title": "Nonbinned",
         "type": "boolean"
      },
      "HasDuplicates": {
         "default": false,
         "description": "Add a trace dimension (chunksize 1) to disambiguate duplicate trace indices.",
         "title": "Hasduplicates",
         "type": "boolean"
      },
      "chunksize": {
         "anyOf": [
            {
               "exclusiveMinimum": 0,
               "type": "integer"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "Chunk size for the trace dimension when `non_binned` is True.",
         "title": "Chunksize"
      },
      "non_binned_dims": {
         "anyOf": [
            {
               "items": {
                  "type": "string"
               },
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "Dimension names to collapse into the trace dimension when `non_binned` is True.",
         "title": "Non Binned Dims"
      }
   },
   "additionalProperties": false
}

field AutoChannelWrap: bool = False

Streamer: auto-detect channel-wrap geometry (Type A vs B).

field AutoShotWrap: bool = False

Streamer: derive dense shot_index from interleaved shot_point values.

field CalculateShotIndex: bool = False

OBN: derive dense shot_index from sparse shot_point values per shot_line.

field chunksize: int | None = None

Chunk size for the trace dimension when non_binned is True.

Constraints:
  • gt = 0

field HasDuplicates: bool = False

Add a trace dimension (chunksize 1) to disambiguate duplicate trace indices.

field NonBinned: bool = False

Collapse selected dims into a single trace dimension without spatial binning.

field non_binned_dims: list[str] | None = None

Dimension names to collapse into the trace dimension when non_binned is True.

SEG-Y File Headers

In-place updates for SEG-Y text and binary file headers on an MDIO dataset.

Headers live as attributes on the scalar segy_file_header variable. Reads use mdio.open_mdio(). Writes go through Zarr because xarray does not persist attribute updates on an existing array.

class mdio.segy.headers.SegyFileHeaders(text_header, binary_header)

Resolved SEG-Y text and binary file headers stored on an MDIO dataset.

Parameters:
text_header

Sanitized 40x80 textual file header.

Type:

str

binary_header

Binary header fields as a JSON-friendly integer mapping.

Type:

dict[str, int]

mdio.segy.headers.update_segy_file_headers(mdio_path, *, text_header=None, binary_header=None, template=None)

Update SEG-Y text and/or binary headers on an existing MDIO file.

Reads the dataset with mdio.open_mdio() (lazy chunks) and writes only segy_file_header attributes. Trace data is not read or rewritten.

None arguments leave that header unchanged when it already exists. If the variable or an attribute is missing, a default is written. Defaults come from template when given, otherwise SEG-Y Revision 1.0.

Missing samples_per_trace and sample_interval values are inferred from the fastest (last) dimension of the default data variable. MDIO sample coordinates are milliseconds; the binary header stores the interval in microseconds. Inference raises if the spacing does not represent one positive, integer number of microseconds.

User binary_header values are merged onto the existing header, or onto the default header when the file has none. Prefer updating values of keys that already exist. Adding or removing binary fields can break SEG-Y export.

The resolved textHeader and binaryHeader values replace those two attributes on segy_file_header. Other attributes on that variable, including rawBinaryHeader, and all attributes on other nodes are preserved. For Zarr v2 stores, unconsolidated node metadata is the source of truth and consolidated metadata is rebuilt from the opened group’s format after the update.

Parameters:
  • mdio_path (UPath | Path | str) – Local or remote path to the MDIO store.

  • text_header (str | None) – Replacement textual header. Sanitized to the 40x80 ASCII card layout.

  • binary_header (Mapping[str, int] | None) – Binary header fields to set or overlay. Integer-valued mapping.

  • template (SegySpec | None) – SEG-Y spec used to build defaults when the file lacks header fields.

Returns:

The text and binary headers stored after the update.

Raises:
  • MDIONotFoundError – If mdio_path does not exist.

  • ValueError – If a provided text header cannot be sanitized, a binary field is not an integer, or sample_interval / samples_per_trace cannot be inferred from the fastest dimension.

Return type:

SegyFileHeaders

SEG-Y textual file header validation and sanitization helpers.

mdio.segy.text_header.sanitize_text_header(text_header)

Coerce a SEG-Y textual file header into the 40x80 ASCII-printable card layout.

Runs of two or more \n collapse to one (some writers terminate cards with \n\n). Each row gets unsafe characters replaced with spaces and is padded/truncated to 80 chars. The result always has exactly 40 rows.

Parameters:

text_header (str) – Decoded textual file header string.

Returns:

Sanitized header that satisfies validate_text_header().

Return type:

str

mdio.segy.text_header.validate_text_header(text_header)

Validate a SEG-Y textual file header is 40 rows of 80 ASCII-printable characters.

Parameters:

text_header (str) – Decoded text header in wrapped form (40 rows of 80 chars joined by \n).

Raises:

ValueError – If row count, row width, or any character fails the SEG-Y ASCII contract.

Return type:

None

Core Functionality

Dimensions

Dimension (grid) abstraction and serializers.

class mdio.core.dimension.Dimension(coords, name)

Dimension class.

Dimension has a name and coordinates associated with it. The Dimension coordinates can only be a vector.

Parameters:
  • coords (list | tuple | NDArray | range) – Vector of coordinates.

  • name (str) – Name of the dimension.

coords

Vector of coordinates.

Type:

list | tuple | NDArray | range

name

Name of the dimension.

Type:

str

max()

Get maximum value of dimension.

Return type:

NDArray[float]

min()

Get minimum value of dimension.

Return type:

NDArray[float]

property size: int

Size of the dimension.

Optimization

Optimize MDIO seismic datasets for fast access patterns using ZFP compression and Dask.

This module provides tools to create compressed, rechunked transpose views of seismic data for efficient access along dataset dimensions. It uses configurable ZFP compression based on data statistics and supports parallel processing with Dask Distributed.

class mdio.optimize.access_pattern.OptimizedAccessPatternConfig(*, optimize_dimensions, processing_chunks, compressor=None)

Configuration for fast access pattern optimization.

Parameters:
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

mdio.optimize.access_pattern.optimize_access_patterns(dataset, config, n_workers=1, threads_per_worker=1)

Optimize MDIO dataset for fast access along dimensions.

Optimize an MDIO dataset by creating compressed, rechunked views for fast access along configurable dimensions, then append them to the existing MDIO file.

This uses ZFP compression with tolerance based on data standard deviation and the provided quality level. Requires Dask Distributed for parallel execution. It will try to grab the existing distributed.Client or create its own. Existing Client will be kept running after optimization.

Parameters:
  • dataset (Dataset) – MDIO Dataset containing the seismic data.

  • config (OptimizedAccessPatternConfig) – Configuration object with quality, access patterns, and processing chunks.

  • n_workers (int) – Number of Dask workers. Default is 1.

  • threads_per_worker (int) – Threads per Dask worker. Default is 1.

Raises:

ValueError – If required attrs/stats are missing or the dataset is invalid.

Return type:

None

Examples

For Post-Stack 3D seismic data, we can optimize the inline, crossline, and depth dimensions.

>>> from mdio import optimize_access_patterns, OptimizedAccessPatternConfig
>>> from mdio import open_mdio
>>>
>>> conf = OptimizedAccessPatternConfig(
>>>     optimize_dimensions={
>>>         "inline": (4, 512, 512),
>>>         "crossline": (512, 4, 512),
>>>         "time": (512, 512, 4),
>>>     },
>>>     processing_chunks= {"inline": 512, "crossline": 512, "time": 512}
>>> )
>>>
>>> ds = open_mdio("/path/to/seismic.mdio")
>>> optimize_access_patterns(ds, conf, n_workers=4)