FAIMS compensation-voltage prediction¶
xiRT predicts crosslinked-peptide compensation voltage (CV) in volts, not collision cross section (CCS). These data do not establish a calibrated CV-to-CCS conversion or an intensity-calibrated optimal voltage.
The integration follows the data conventions of
xiFAIMS, pinned at
b85482ffc246b2dc669c4592f752568fd9b1baed (Apache-2.0). It trains xiRT's
native shared GRU, not the upstream XGBoost model.
Train from observations¶
xirt faims train --input 4PM_DSS_LS_nonunique1pCSM.csv \
8PM_DSS_Liu_nonunique1pCSM.csv --output results/faims --features charge
| Canonical column | xiFAIMS alias | Meaning |
|---|---|---|
peptide1, peptide2 |
PepSeq1, PepSeq2 |
Bare modified peptide sequences |
link_pos1, link_pos2 |
LinkPos1, LinkPos2 |
One-based crosslink sites |
precursor_charge |
exp charge |
Positive integer charge |
precursor_mz |
exp m/z |
Positive finite m/z, needed for charge-mz |
precursor_mass |
exp mass |
Optional legacy precursor context |
isTT |
same | Explicit boolean target-target identification |
fdr |
same | Identification FDR in [0, 1] |
run |
same | Explicit CV label, unless --cv-column is supplied |
--features selects sequence (no numeric context), charge (default), or
charge-mz. Legacy precursor uses charge, m/z and mass for compatibility
with the archived first experiment. --no-precursor-features is an alias for
the sequence-only ablation. Charge is required during observation aggregation
even for sequence-only training, because it defines a precursor.
Unsigned CV045 run labels mean negative voltages. Only explicit CV labels
and the pinned 8PM_DSS_A_50_rep1-style Liu convention are parsed; arbitrary
filename numbers are not voltages. Supply a finite numeric voltage column
with --cv-column your_column for another convention.
Training retains explicit TT observations with fdr <= 0.01, canonicalizes
peptide/site pairs and averages observed CV per modified pair, sites, charge
and source. Source IDs are distinct input filename stems. Do not combine an
aggregate CSV with its constituent original observations.
The 75/12.5/12.5% split groups unordered unmodified peptide pairs, keeping
charges, PTMs and sites together. --split-seed controls partitions and
--seed initialization. Vocabulary, numeric normalization and target scaling
use training rows only. Validation controls early stopping and restores the
best weights. --epochs changes the 150-epoch ceiling; --params accepts a
full mapping from default_faims_params(). Outputs include faims.pt,
predictions.csv, history.csv, metrics.json, audit.json and shared
prediction/learning-curve QC PNGs.
Predict and explain¶
xirt predict --input unlabelled_precursors.csv \
--checkpoint results/faims/faims.pt --output predictions.csv
xirt explain --input unlabelled_precursors.csv \
--checkpoint results/faims/faims.pt --output explanations --limit 1
Inference requires only sequences, sites and the checkpoint's selected numeric
fields. CV labels, FDR, TT and run columns are unnecessary.
xirt faims predict remains a compatibility alias. Outputs preserve row order
and add faims_cv-prediction, the legacy faims_cv_prediction_v alias and
unknown_token_count. Add --qc qc --observed faims_cv when labels are
available to generate the same annotated QC used for RT.
Unseen PTMs are counted and warned about rather than silently stripped; their reserved unknown embedding may be untrained. N-terminal modifications, noncanonical residues, invalid sites and peptides longer than the saved limit are rejected explicitly. The default maximum is 60 residues, without truncation.
Python API¶
from xirt.faims import FAIMSPredictor, prepare_faims_observations, split_precursors
from xirt.predictor import Predictor
precursors, audit = prepare_faims_observations(raw, source="experiment")
partitions = split_precursors(precursors)
fitted = FAIMSPredictor().fit(
partitions.loc[partitions["split"] == "train"],
partitions.loc[partitions["split"] == "validation"],
)
fitted.save("faims.pt")
predictor = Predictor.load("faims.pt")
predictions = predictor.predict(unlabelled_precursors)
explanation = predictor.explain(unlabelled_precursors.iloc[:1], steps=64)
fit checks disjoint unmodified-pair groups and accepts no test set. Checkpoints
contain all preprocessing and unit semantics. Both prediction APIs return
volts. Residue explanations separate residue, terminus and
precursor contributions and report a completeness diagnostic.
Examples and measured comparison¶
make notebook-faims opens a focused train/save/load/predict example using
915 bundled precursors. make notebook-analysis opens shared RT/FAIMS QC
and residue-level explanations after running both training tutorials.
See notebooks for execution and output paths.
The source checkout's benchmark-faims/README.md, protocol.json and reports
document the controlled comparison of sequence only, sequence + charge and
sequence + charge + m/z across pooled original 4PM/8PM, 26S and 293T cohorts.
Three initializations share one fixed pair-group partition and training budget.
make benchmark-faims runs or resumes the experiment using verified local input
CSVs. Raw observations and trained weights stay local.
Held-out RMSE in volts (mean ± sample SD across the three initializations):
| Cohort | Sequence only | + Charge | + Charge and m/z |
|---|---|---|---|
| Pooled original 4PM+8PM | 9.98 ± 0.30 | 8.77 ± 0.19 | 8.28 ± 0.13 |
| 26S | 7.50 ± 0.44 | 7.03 ± 0.10 | 6.99 ± 0.17 |
| 293T | 11.23 ± 0.11 | 11.14 ± 0.13 | 9.25 ± 0.19 |
Charge helps pooled 4PM/8PM and 26S but adds little on the 56-precursor 293T holdout. Charge+m/z has the lowest mean RMSE, although its 0.04 V advantage over charge-only on 26S is small relative to seed variability. Full predictions, transfer scores and annotated correlations are in the reports.
The earlier precursor/baseline results and exact source snapshot are preserved
unchanged under benchmark-faims/archive/2026-10-20-precursor-baselines/.
Its test results were already inspected before designing the new ablation:
the repeated holdout is not a fresh blinded test.
Seed variability describes optimization, not biological replication or a confidence interval. Individual peptides, proteins, runs and instruments are not held out. External transfer excludes shared source/target peptide pairs and reports unknown-token coverage separately. The small 293T holdout warrants particular caution; this comparison does not establish universal generalization.