Skip to content

PRM Data Elements

Parallel Reaction Monitoring (PRM) experiments select a predefined list of precursor ions and collect high-resolution MS2 spectra for each across the chromatographic run. The two classes on this page represent those two levels of structure.

PrmTarget

A PrmTarget represents one entry in the instrument's target list — a single analyte defined by its m/z, charge state, expected retention time, and expected ion mobility. The instrument uses these values to schedule isolation windows and select the correct mobility range during data collection.

Each target accumulates back-references to all PrmTransition objects collected for it via the transitions field.

from tdfpy import PRM

with PRM("experiment.d") as prm:
    for target in prm.targets:
        print(
            f"Target {target.target_id}: "
            f"{target.monoisotopic_mz:.4f} m/z, "
            f"charge {target.charge}, "
            f"RT {target.time:.1f} s, "
            f"1/K0 {target.one_over_k0:.3f}"
        )
        # All transitions collected for this target
        for tr in target.transitions:
            print(f"  Frame {tr.frame_id}, RT {tr.rt:.1f} s")

tdfpy.PrmTarget dataclass

PrmTarget(
    target_id: int,
    external_id: str | None,
    time: float,
    one_over_k0: float,
    monoisotopic_mz: float,
    charge: int,
    description: str,
    transitions: tuple[PrmTransition, ...] = (),
)

A predefined PRM target ion from the PrmTargets table.

Defines the expected m/z, charge, retention time, and ion mobility for a target analyte in a PRM acquisition.

Field Type Description
target_id int Unique target ID
external_id str \| None External identifier
time float Expected retention time in seconds
one_over_k0 float Expected ion mobility (1/K0)
monoisotopic_mz float Target m/z
charge int Charge state
description str Target description
transitions tuple[PrmTransition, ...] Associated PRM transitions

PrmTransition

A PrmTransition represents a single MS2 acquisition event for a PRM target — one isolation window applied to a specific frame and mobility scan range. Multiple transitions are collected for each target as the analyte elutes across time.

PrmTransition provides .peaks for raw scan data and .centroid() for processed spectra, consistent with the DiaWindow and PasefFrameMsmsInfo APIs.

from tdfpy import PRM

with PRM("experiment.d") as prm:
    for transition in prm.transitions:
        print(
            f"Frame {transition.frame_id}, "
            f"target {transition.target.target_id}, "
            f"isolation {transition.isolation_mz:.3f} m/z, "
            f"CE {transition.collision_energy:.1f} eV"
        )
        # Centroided MS2 spectrum — shape (N, 3): [m/z, intensity, 1/K0]
        peaks = transition.centroid()
        break

tdfpy.PrmTransition dataclass

PrmTransition(
    _timsdata: TimsData,
    frame_id: int,
    scan_num_begin: int,
    scan_num_end: int,
    isolation_mz: float,
    isolation_width: float,
    collision_energy: float,
    target: PrmTarget,
    rt: float,
    polarity: Polarity,
)

Bases: _TdfData

A PRM isolation window bound to a specific frame.

Each instance corresponds to one row in the PrmFrameMsMsInfo table: a contiguous range of mobility scans acquired with a specific isolation window and collision energy, linked to a PRM target.

Field Type Description
frame_id int Frame ID
scan_num_begin int First mobility scan (inclusive)
scan_num_end int Last mobility scan (inclusive)
isolation_mz float Isolation window center m/z
isolation_width float Isolation window width in Th
collision_energy float Collision energy in eV
target PrmTarget Associated PRM target
rt float Retention time in seconds
polarity Polarity Ion polarity

peaks property

peaks: list[npt.NDArray[np.float64]]

Read raw peaks for this PRM transition and return as list of (mz, intensity) arrays.

centroid

centroid(
    mz_tolerance: float = 8,
    mz_tolerance_type: Literal["ppm", "da"] = "ppm",
    im_tolerance: float = 0.1,
    im_tolerance_type: Literal[
        "relative", "absolute"
    ] = "relative",
    min_peaks: int = 3,
    max_peaks: int | None = None,
    noise_filter: (
        Literal[
            "mad",
            "percentile",
            "histogram",
            "baseline",
            "iterative_median",
        ]
        | float
        | None
    ) = None,
    ion_mobility_type: Literal[
        "ccs", "ook0", "voltage"
    ] = "ook0",
) -> np.ndarray

Centroid the spectrum for this PRM transition using the specified parameters.

Source code in src/tdfpy/elems.py
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
def centroid(
    self,
    mz_tolerance: float = 8,
    mz_tolerance_type: Literal["ppm", "da"] = "ppm",
    im_tolerance: float = 0.1,
    im_tolerance_type: Literal["relative", "absolute"] = "relative",
    min_peaks: int = 3,
    max_peaks: int | None = None,
    noise_filter: Literal["mad", "percentile", "histogram", "baseline", "iterative_median"] | float | None = None,
    ion_mobility_type: Literal["ccs", "ook0", "voltage"] = "ook0",
) -> np.ndarray:
    """Centroid the spectrum for this PRM transition using the specified parameters."""
    get_spectrum = partial(
        get_centroided_spectrum,
        self.timsdata,
        frame_id=self.frame_id,
        spectrum_index=None,
        ion_mobility_type=ion_mobility_type,
        mz_tolerance=mz_tolerance,
        mz_tolerance_type=mz_tolerance_type,
        im_tolerance=im_tolerance,
        im_tolerance_type=im_tolerance_type,
        min_peaks=min_peaks,
        max_peaks=max_peaks,
        noise_filter=noise_filter,
    )

    try:
        return get_spectrum(use_numba=True)
    except (ImportError, RuntimeError, TypeError, ValueError):
        warnings.warn(
            f"Numba centroiding failed for frame {self.frame_id}. Falling back to Python implementation.",
            UserWarning,
            stacklevel=2,
        )
        return get_spectrum(use_numba=False)