Metadata-Version: 2.5
Name: mzmlpy
Version: 0.10.0
Summary: A lightweight Python library for parsing mzML mass spectrometry files.
Project-URL: Homepage, https://github.com/tacular-omics/mzmlpy
Project-URL: Repository, https://github.com/tacular-omics/mzmlpy
Project-URL: Documentation, https://tacular-omics.github.io/mzmlpy/
Project-URL: Changelog, https://github.com/tacular-omics/mzmlpy/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/tacular-omics/mzmlpy/issues
Project-URL: DOI, https://doi.org/10.5281/zenodo.21960079
Author-email: "Patrick T. Garrett" <pgarrett@scripps.edu>, "John R. Yates III" <jyates@scripps.edu>
Maintainer-email: "Patrick T. Garrett" <pgarrett@scripps.edu>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: numpy>=1.26.0
Provides-Extra: mcp
Requires-Dist: mcp<3,>=2.1.1; extra == 'mcp'
Provides-Extra: numpress
Requires-Dist: pynumpress>=0.1.5; extra == 'numpress'
Provides-Extra: rapidgzip
Requires-Dist: rapidgzip>=0.14.0; extra == 'rapidgzip'
Provides-Extra: zstd
Requires-Dist: zstd>=1.5.5; extra == 'zstd'
Description-Content-Type: text/markdown

<div align="center">
  <img src="https://raw.githubusercontent.com/tacular-omics/mzmlpy/main/logo.png" alt="MZMLpy Logo" width="400" style="margin: 20px;"/>

  [![Python package](https://github.com/tacular-omics/mzmlpy/actions/workflows/ci.yml/badge.svg)](https://github.com/tacular-omics/mzmlpy/actions/workflows/ci.yml)
  [![codecov](https://codecov.io/github/tacular-omics/mzmlpy/graph/badge.svg?token=1CTVZVFXF7)](https://codecov.io/github/tacular-omics/mzmlpy)
  [![PyPI version](https://badge.fury.io/py/mzmlpy.svg)](https://badge.fury.io/py/mzmlpy)
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21960079.svg)](https://doi.org/10.5281/zenodo.21960079)
  [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
  [![License: MIT](https://img.shields.io/badge/License-MIT-g.svg)](https://opensource.org/licenses/MIT)

</div>

**mzmlpy** is a Python library for reading mzML mass spectrometry files. It's built for
people writing proteomics or metabolomics pipelines who need a reader that's fast on
large files, tells them exactly what's wrong with a malformed file, and doesn't force a
full decode just to look at a spectrum's metadata.

## Why mzmlpy?

- **Lazy by design** — metadata is parsed up front; binary m/z and intensity arrays are
  only decoded when you actually touch them.
- **Fast random access** — opens and indexes a 48 MB Orbitrap file in about 0.05 s
  (pyteomics: about 1 s); full decoding is on par with pyteomics and pymzml (see below).
- **Type-safe** — dataclass-based models with full type annotations, not loosely-typed
  XML trees.
- **Handles gzip well** — reads `.mzML.gz` directly, with a self-indexed gzip format for
  random access without decompressing the whole file.
- **Common compressions** — zlib out of the box; zstd and MS-Numpress through optional
  extras.
- **Validates, not just parses** — a `validate()` function reports structural and
  decoding problems instead of silently producing bad data.

## Install

```bash
pip install mzmlpy
```

Optional extras:

```bash
pip install mzmlpy[numpress]   # MS-Numpress decoding
pip install mzmlpy[zstd]       # Zstandard compression
pip install mzmlpy[rapidgzip]  # Parallel gzip decompression (recommended for .gz files)
pip install mzmlpy[mcp]        # MCP server for AI coding assistants
```

## Quick example

```python
from mzmlpy import Mzml

with Mzml("path/to/file.mzML") as reader:
    print(f"File: {reader.file_name}  |  Spectra: {len(reader.spectra)}")

    for spectrum in reader.spectra:
        mz = spectrum.mz
        intensity = spectrum.intensity
        print(f"  {spectrum.id} MS{spectrum.ms_level} — {len(mz)} peaks")
```

Both `.mzML` and `.mzML.gz` files are supported. Metadata is parsed eagerly; binary data
is decoded on demand.

## What else it can do

```python
from mzmlpy import Mzml, validate

# Structural/decoding validation, no repair attempted
report = validate("data.mzML", decode_binary=True)
print(report.valid, report.issues)

# Filter by metadata without decoding any arrays
with Mzml("data.mzML") as reader:
    for spectrum in reader.spectra.filter(ms_level=2, rt_range=(60, 180)):
        print(spectrum.id)
```

Gzipped files get the same lazy, indexable access as plain mzML — `gzip_mode="auto"` uses an
embedded index, then rapidgzip if installed, then decompression into memory, and never writes
files next to yours. For fast re-opens, convert once with `write_indexed_gzip` (random access with
no extra files) or open once with `gzip_mode="indexed"` to save reusable sidecar indexes. Ion
mobility data (e.g. Bruker timsTOF PASEF) is exposed on the spectrum whether it's stored
as a binary array or a scan-level parameter.

| Feature | Notes |
|---|---|
| `.mzML` / `.mzML.gz` | Transparent gzip handling, including self-indexed files |
| Validation | `validate()` reports issues without altering the file |
| Filtering | By MS level, retention time, and precursor, without decoding arrays |
| Ion mobility | Detects both array-based and scan-level IM data |
| MCP server | `pip install mzmlpy[mcp]` — file discovery, metadata, and bounded array access for AI clients |
| CLI | `python -m mzmlpy` for validation and inspection from the shell |

See the **[Getting Started guide](https://tacular-omics.github.io/mzmlpy/getting-started/)**
and **[API Reference](https://tacular-omics.github.io/mzmlpy/api/mzml/)** for the full
picture, including gzip mode details, the CLI, and the MCP server.

Using an AI coding assistant? Point it at
**[`llms.txt`](https://github.com/tacular-omics/mzmlpy/blob/main/llms.txt)**, a short index of the
package and its docs, or at
**[`llms-full.txt`](https://github.com/tacular-omics/mzmlpy/blob/main/llms-full.txt)** for the full API
guide with signatures and examples.

## In the tacular-omics family

mzmlpy reads mzML; [tdfpy](https://github.com/tacular-omics/tdfpy) reads the Bruker
timsTOF `.d` format the same way. Both feed spectra into
[spxtacular](https://github.com/tacular-omics/spxtacular), the shared spectrum-processing
layer for deisotoping, deconvolution, and downstream analysis.

## Links

- **Docs**: https://tacular-omics.github.io/mzmlpy/
- **Changelog**: [`CHANGELOG.md`](https://github.com/tacular-omics/mzmlpy/blob/main/CHANGELOG.md)

## Citation

Citation metadata are provided in [`CITATION.cff`](CITATION.cff). All archived releases are
available from Zenodo at [doi:10.5281/zenodo.21960079](https://doi.org/10.5281/zenodo.21960079).

## Benchmarks

`benchmarks/` contains a reproducible harness comparing mzmlpy against
[pyteomics](https://github.com/levitsky/pyteomics) and [pymzml](https://github.com/pymzml/pymzML)
on compression-format support, throughput, and gzip handling.

Measured 2026-09-24 on a 47.9 MB, 3,392-spectrum Q Exactive HF file (PRIDE PXD015669,
`QEHF1_09771_JB`), pyteomics 5.0.1 and pymzml 2.7.0, range over two runs on a shared
workstation (indicative only):

| Benchmark | mzmlpy | pyteomics | pymzml |
|---|---|---|---|
| Open + build index | 0.047–0.056 s | 0.94–1.08 s | — |
| Decode every spectrum | 2.2–2.7 s | 3.4–4.8 s | 2.8–3.3 s |
| Open + 8 scattered reads | 0.053–0.058 s | 1.1–2.1 s | error on this file |

Full decoding is of the same order in all three; the large differences are index
construction, random access and encoding coverage (pymzml returns no peaks for Numpress-then-zlib and
zstd arrays; pyteomics cannot read zstd). See
[`benchmarks/README.md`](https://github.com/tacular-omics/mzmlpy/blob/main/benchmarks/README.md)
for how to run it yourself, and the full results on the
**[Benchmarks page](https://tacular-omics.github.io/mzmlpy/benchmarks/)**.

## License

MIT — see [`LICENSE`](https://github.com/tacular-omics/mzmlpy/blob/main/LICENSE).
