Metadata-Version: 2.4
Name: psmpredict
Version: 0.2.0
Summary: GPU-ready peptide MS/MS spectrum predictor trained from MaxQuant msms.txt
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=2.0
Requires-Dist: pyarrow>=14
Requires-Dist: pyyaml>=6
Requires-Dist: tqdm>=4.66
Dynamic: license-file

# PSMpredict v0.2

GPU-ready PyTorch pipeline that learns HCD MS/MS fragment intensities from MaxQuant `msms.txt` files and predicts spectra from peptide sequence and precursor charge.

## Changes in v0.2

- Chemistry-aware masks: H2O loss requires S/T/E/D; NH3 loss requires R/K/Q/N.
- Fragment charge cannot exceed precursor charge.
- Impossible channels are excluded from training loss and prediction output.
- Predicted intensities are max-normalized per peptide to 0-1.
- Validation is split by unique peptide sequence, preventing sequence leakage.
- `prepare --unmodified-only` creates an unmodified baseline directly.

These changes require retraining. Older checkpoints can still be loaded for inference, but they were not trained with the chemistry mask or sequence-level validation split.

## Pipeline

```mermaid
flowchart LR
    A[MaxQuant msms.txt] --> B[prepare_msms]
    B --> C[Optional unmodified-only filter]
    C --> D[Targets and chemistry mask]
    D --> E[psms.pt]
    E --> F[Unique-sequence split]
    F --> G[Transformer training]
    G --> H[best.pt]
    I[Peptide TSV] --> J[Prediction]
    H --> J
    J --> K[Mask impossible ions]
    K --> L[Max-normalize spectrum]
    L --> M[predicted_spectra.tsv]
```

## Neural network

```mermaid
flowchart TD
    S[Residue IDs] --> AE[Amino-acid embedding]
    M[Modification masses] --> ME[Linear projection]
    C[Precursor charge] --> CE[Charge embedding]
    P[Position] --> SUM[Element-wise sum]
    AE --> SUM
    ME --> SUM
    CE --> SUM
    P --> SUM
    SUM --> T[4-layer Transformer encoder]
    T --> A[Concatenate adjacent residue states]
    A --> H[Linear, GELU, dropout, linear]
    H --> O[12 non-negative channels per cleavage]
    O --> MASK[Chemistry and charge mask]
```

## Installation on the validated RTX 2070 SUPER setup

```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e . pytest
python -m pip install torch==2.5.1 --index-url https://download.pytorch.org/whl/cu121
pytest -q
```

Validated local environment:

- Python 3.13
- PyTorch 2.5.1 with CUDA 12.1
- NVIDIA GeForce RTX 2070 SUPER
- Test result: 4 passed, with one non-fatal PyTorch nested-tensor warning

On LUMI, use the current LUMI AI Factory ROCm PyTorch container and install PSMpredict without replacing the container-provided PyTorch build:

```bash
python -m pip install --no-deps -e .
```

## Train an unmodified model

Using example [msms.txt](https://zenodo.org/records/23295772/files/msms.hela.timstof.txt) available at [Zenodo](https://zenodo.org/records/23295772)

```bash
mkdir -p work results/model_v02
wget https://zenodo.org/records/23295772/files/msms.hela.timstof.txt
psmpredict prepare msms.hela.timstof.txt --output work/psms_v02.pt --unmodified-only
psmpredict train --data work/psms_v02.pt --output-dir results/model_v02 --epochs 100
```

The validated preparation produced 41,202 unmodified PSMs with no unknown modifications.

## Predict

Use an unmodified peptide input file such as `examples/peptides.unmodified.tsv`:

```text
Sequence	Modified sequence	Charge
PEPTIDE	_PEPTIDE_	2
```

Run prediction with the best v0.2 checkpoint:

```bash
psmpredict predict --checkpoint results/model_v02/best.pt --input examples/peptides.unmodified.tsv --output results/predicted_spectra_v02.tsv
```

Each output row contains:

- peptide row ID
- peptide sequence
- precursor charge
- fragment annotation
- theoretical fragment m/z
- max-normalized predicted intensity

Chemically impossible neutral losses and fragment charge states are omitted rather than exported with small scores.

## Latest validated v0.2 results

The unmodified v0.2 model was trained for 100 epochs on an NVIDIA GeForce RTX 2070 SUPER:

- total PSMs: 41,202
- training PSMs: 37,089
- validation PSMs: 4,113
- validation split: unique peptide sequence
- best validation spectral angle: 0.612018 at epoch 100
- final training MSE: 0.0027627
- prediction device: CUDA
- prediction test: 1 peptide and 46 chemically valid fragment rows
- output normalization: strongest predicted peak equals 1.0
- tests: 4 passed

For `PEPTIDE/2`, the strongest predicted fragments were:

```text
b4       1.0000
b6       0.9830
b5       0.8994
b4-H2O   0.8280
b5-H2O   0.6479
```

All NH3-loss fragments were removed because `PEPTIDE` contains none of the currently permitted NH3-loss residues R, K, Q, or N.

## Previous baseline

The v0.1 unmodified run used 41,202 PSMs and reached a validation spectral angle of 0.61601 at epoch 97. That run used a PSM-level split and unconstrained loss channels, so it is not directly comparable with v0.2.

The v0.2 score of 0.612018 is the more credible benchmark because validation peptides are sequence-disjoint from training peptides and chemically impossible channels are excluded.

## Code map

- `src/psmpredict/cli.py`: defines command-line arguments and dispatches `prepare`, `train`, and `predict`.
- `src/psmpredict/core.py`: parses MaxQuant data, constructs targets, creates chemistry and charge masks, batches peptides, defines the Transformer, calculates spectral angle, and handles checkpoints.
- `src/psmpredict/workflows.py`: performs the unique-sequence split, training loop, fragment m/z calculation, chemistry-masked prediction, and per-spectrum normalization.
- `tests/test_core.py`: tests target construction, precursor-charge masking, neutral-loss masking, and model output shape.
- `examples/peptides.unmodified.tsv`: example unmodified prediction input.
- `scripts/`: LUMI SLURM templates.
- `tools/plotPSM.py`: independent observed-spectrum plotting utility; it is not called by the model pipeline.

## Ideas borrowed from established tools

Implemented in v0.2:

- constrained fragment-ion output space
- normalized predicted spectra
- sequence-disjoint validation
- explicit unmodified-only training mode

Potential future additions:

- collision-energy and instrument embeddings
- fragmentation-method conditioning
- ProForma/Unimod modification handling
- transfer learning from pretrained spectrum models
- spectral-library export formats
- observed-versus-predicted mirror plots
- early stopping and learning-rate scheduling

MS2PIP supports multiple instruments, fragmentation methods, and library-oriented workflows. AlphaPeptDeep provides pretrained MS2, retention-time, and collision-cross-section models with transfer learning. These are useful future directions, but they should not be added until the required metadata or validated pretrained weights are available.

## Limitations

- Only b/y ions, fragment charges 1+/2+, H2O loss, and NH3 loss are modeled.
- Collision energy, instrument, fragmentation method, and ion mobility are not model inputs.
- MaxQuant-unannotated channels are treated as zero targets.
- The chemistry masks are conservative heuristics, not a complete fragmentation-chemistry model.
- Predicted intensities are relative and max-normalized, not detector counts or probabilities.
- Fragment m/z values are calculated theoretically and are not learned by the network.
- LUMI scripts remain templates until exact-container validation on a LUMI compute node.

## Literature

- Prosit: Gessulat et al., *Nature Methods* 2019, DOI 10.1038/s41592-019-0426-7.
- pDeep: Zhou et al., *Analytical Chemistry* 2017, DOI 10.1021/acs.analchem.7b02566.
- MS2PIP: Degroeve and Martens, *Bioinformatics* 2013, DOI 10.1093/bioinformatics/btt544.
- AlphaPeptDeep: Zeng et al., *Nature Communications* 2022, DOI 10.1038/s41467-022-34904-3.
