Skip to content

Validation and filtering

mzmlpy.validate

validate(
    file: str | Path,
    *,
    decode_binary: bool = False,
    check_index: bool = False
) -> ValidationReport

Validate plain or gzip mzML without creating or repairing caches.

The default checks XML structure, list counts, IDs, references, index ID agreement, and supported array metadata. Set decode_binary to decode every array and compare lengths. Set check_index to seek to XML footer offsets and verify their targets. This does not perform full XSD, controlled-vocabulary, or embedded gzip index validation. Memory grows with IDs, references, and findings, plus the largest record.

File-open errors raise OSError. Malformed content is returned as report issues.

Source code in src/mzmlpy/validation.py
def validate(file: str | Path, *, decode_binary: bool = False, check_index: bool = False) -> ValidationReport:
    """Validate plain or gzip mzML without creating or repairing caches.

    The default checks XML structure, list counts, IDs, references, index ID agreement,
    and supported array metadata. Set decode_binary to decode every array and compare
    lengths. Set check_index to seek to XML footer offsets and verify their targets.
    This does not perform full XSD, controlled-vocabulary, or embedded gzip index validation.
    Memory grows with IDs, references, and findings, plus the largest record.

    File-open errors raise OSError. Malformed content is returned as report issues.
    """
    with open(file, "rb") as raw:
        compressed = raw.read(2) == b"\x1f\x8b"
        raw.seek(0)
        if compressed:
            with gzip.GzipFile(fileobj=raw) as handle:
                return _validate_stream(cast(BinaryIO, handle), decode_binary=decode_binary, check_index=check_index)
        return _validate_stream(raw, decode_binary=decode_binary, check_index=check_index)

mzmlpy.ValidationReport dataclass

ValidationReport(
    issues: tuple[ValidationIssue, ...],
    spectrum_count: int,
    chromatogram_count: int,
    arrays_decoded: int,
    index_entries_checked: int,
    complete: bool,
    decode_binary: bool,
    check_index: bool,
)

Results of the requested checks, without claiming full schema or ontology validation.

Structural validation scans XML and records IDs and references without decoding arrays. Binary decoding and byte-offset verification are explicit, potentially expensive options.

valid property

valid: bool

Whether parsing completed and the requested checks found no errors.

to_dict

to_dict() -> dict

Return JSON-serializable results, including the computed valid flag.

Source code in src/mzmlpy/validation.py
def to_dict(self) -> dict:
    """Return JSON-serializable results, including the computed valid flag."""
    return {"valid": self.valid, **asdict(self)}

mzmlpy.ValidationIssue dataclass

ValidationIssue(
    code: str,
    message: str,
    location: str,
    severity: Literal["error", "warning"] = "error",
)

One machine-readable finding with a stable code and an XML location.

mzmlpy.SpectrumFilter dataclass

SpectrumFilter(
    *,
    ms_level: int | None = None,
    rt_range: (
        tuple[float | None, float | None] | None
    ) = None,
    polarity: Polarity | None = None,
    precursor_mz_range: (
        tuple[float | None, float | None] | None
    ) = None,
    spectrum_type: (
        Literal["centroid", "profile"] | None
    ) = None,
    ook0_range: (
        tuple[float | None, float | None] | None
    ) = None,
    drift_time_range: (
        tuple[float | None, float | None] | None
    ) = None,
    faims_voltage_range: (
        tuple[float | None, float | None] | None
    ) = None
)

Combine metadata criteria with AND, without decoding binary arrays.

Every range is an inclusive (lower, upper) tuple; either end may be None for an open bound. rt_range is in seconds and matches any scan. precursor_mz_range overlaps any reported isolation window, or matches a selected ion when that precursor has no usable isolation window. ook0_range (1/K0, Vs/cm²), drift_time_range and faims_voltage_range (signed volts) match any scan. Missing metadata does not match a requested criterion.

matches

matches(spectrum: Spectrum) -> bool

Return whether a spectrum satisfies every supplied criterion.

Source code in src/mzmlpy/filtering.py
def matches(self, spectrum: Spectrum) -> bool:
    """Return whether a spectrum satisfies every supplied criterion."""
    if self.ms_level is not None and spectrum.ms_level != self.ms_level:
        return False
    if self.spectrum_type is not None and spectrum.spectrum_type != self.spectrum_type:
        return False
    if self.polarity is not None and spectrum.polarity != self.polarity:
        return False
    if self.rt_range is not None and not any(_within(scan.rt, self.rt_range) for scan in spectrum.scans):
        return False
    if self.ook0_range is not None and not any(_within(scan.ook0, self.ook0_range) for scan in spectrum.scans):
        return False
    if self.drift_time_range is not None and not any(
        _within(scan.drift_time, self.drift_time_range) for scan in spectrum.scans
    ):
        return False
    if self.faims_voltage_range is not None and not any(
        _within(scan.faims_compensation_voltage, self.faims_voltage_range) for scan in spectrum.scans
    ):
        return False
    if self.precursor_mz_range is not None and not self._matches_precursor(spectrum, self.precursor_mz_range):
        return False
    return True