
Understanding the pepVet Scoring Model
Source:vignettes/articles/scoring-model.Rmd
scoring-model.RmdModel overview
score_peptides() reduces a digest tibble to one row per
protein. That row contains component scores, a composite score, a
verdict, and the digest-level median_peptide_length used to
interpret peptide density.
The model uses explicit component scores and a weighted sum so that each contribution remains visible.
Positioning
pepVet is not a peptide detectability predictor. It does not estimate whether an experiment will identify a specific peptide from empirical MS training data. Instead, it ranks a protein digest for a chosen enzyme-workflow combination.
- ML detectability models learn nonlinear interactions from observed peptide detections.
- pepVet uses a rule-based multi-criteria decision analysis with explicit, linear weights.
- ML detectability models output per-peptide predictions or suitability scores, depending on the model.
- pepVet outputs per-protein digest-quality rankings.
Interpret pepVet as a digest-ranking model for pre-acquisition planning, not as a substitute for peptide-level detectability prediction.
Valid peptides
Most pepVet components operate on valid peptides. A peptide is valid
if its length falls inside the active length_range.
The default window is 7 to 25 residues. It is a strict, conservative prior for routine workflows, not a universal LC-MS/MS detection boundary.
Peptides outside that window still appear in
digest_protein() output. They are real cleavage products,
but the default score excludes them from its valid-peptide numerators.
Empirical work shows that peptide observability depends on
physicochemical properties and the analytical platform rather than on
one universal length interval (Mallick et al. 2007). Use a preset or
custom range when the workflow supports different boundaries.
short_seq <- "AKAKAKAKAKAKAKAKAKAKAKAKAKAKAKAKAK"
evaluate_digest(short_seq, enzyme = "trypsin")$scores
#> # A tibble: 1 × 12
#> protein_id S_length S_coverage S_count S_hydro S_charge composite_score
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 sequence_1 0 0 0 0 0 0
#> # ℹ 5 more variables: verdict <chr>, median_peptide_length <dbl>,
#> # preset_used <chr>, n_high_efficiency_sites <int>,
#> # n_low_efficiency_sites <int>Component scores
S_length
S_length is the fraction of peptides that are valid.
Low S_length can result from many products below the
active window or from long products above it.
S_coverage
S_coverage is the fraction of the protein sequence
covered by at least one valid peptide.
pepVet merges overlapping valid peptide intervals before summing widths. A residue covered twice still counts once.
S_count
S_count is a normalized peptide-density score.
In the current release, the expected peptide density is enzyme-aware. For digests with at least three peptide rows, pepVet uses the observed digest median length. For sparse digests, it falls back to enzyme-class expectations.
This is a bounded heuristic, not a mechanistic cleavage model. Enzyme-aware medians keep tryptic and GluC digests from sharing one fixed peptide-density prior.
ev_bsa <- evaluate_digest(bsa_path, enzyme = "trypsin", missed_cleavages = 1L)
ev_bsa$scores[, c("S_count", "median_peptide_length", "composite_score")]
#> # A tibble: 1 × 3
#> S_count median_peptide_length composite_score
#> <dbl> <dbl> <dbl>
#> 1 1 10 0.885When there are no cleavage sites for the selected enzyme, pepVet
warns and sets S_count to 0. A zero
S_count is a failed digest, so pepVet also sets the
composite score to 0 and the verdict to Poor.
This hard failure applies even when the uncut full-length peptide falls
inside the active length window and gives full sequence coverage. It is
the documented exception to the weighted-sum equation.
S_hydro
S_hydro is the fraction of valid peptides with GRAVY
values inside the active gravy_range.
The default range is -1.0 to 0.6. The
membrane preset assumes a wider hydrophobicity range and
extends the upper boundary to 2.0.
S_charge
S_charge is the fraction of valid peptides that retain
at least one non-terminal basic residue.
This score does not predict ionization or fragmentation. The implementation uses non-terminal basic residues as a charge-richness proxy. A value of zero means that no valid peptide contains such a residue.
Composite score and verdicts
The component scores enter a weighted sum, which the package then maps to one of three advisory labels.
Weights and presets
The composite score is a weighted sum.
Default weights depend on whether S_unique is in
play.
| Mode | Weight vector |
|---|---|
| Protein-only | c(S_length = 0.200, S_coverage = 0.348, S_count = 0.226, S_hydro = 0.138, S_charge = 0.088) |
| Proteome-aware | c(S_length = 0.160, S_coverage = 0.279, S_count = 0.181, S_hydro = 0.110, S_charge = 0.070, S_unique = 0.200) |
Default weights are documented expert priors that encode relative importance chosen for pepVet. They were not fitted to experimental outcomes, and the repository does not retain a derivation record that supports a more specific provenance claim. Coverage and peptide count receive the largest combined weight in the protein-only vector.
pepvet_preset() returns shipped starting configurations
for several workflows.
pepvet_preset("dia")
#> $gravy_range
#> [1] -1.0 0.8
#>
#> $length_range
#> [1] 7 30
#>
#> $weights
#> S_length S_coverage S_count S_hydro S_charge S_unique
#> 0.2 0.3 0.2 0.1 0.1 0.1
#>
#> $include_pI
#> [1] FALSE
pepvet_preset("membrane")
#> $gravy_range
#> [1] -1 2
#>
#> $length_range
#> [1] 7 30
#>
#> $weights
#> S_length S_coverage S_count S_hydro S_charge S_unique
#> 0.25 0.25 0.20 0.05 0.15 0.10
#>
#> $include_pI
#> [1] FALSEThese presets record four settings together.
length_rangegravy_rangeweightsinclude_pI
Changing a preset can alter both the weights and the peptide windows. Inspect the resolved values before comparing scores.
score_peptides() records the resolved configuration in
preset_used. When the active GRAVY range, peptide-length
range, weights, and pI flag exactly match a shipped preset, the function
reports the preset name. Otherwise it reports "custom". Use
this field to identify scores produced under different workflow
assumptions.
Verdict thresholds
pepVet maps the composite score to three labels.
| Verdict | Threshold |
|---|---|
Good |
>= 0.65 |
Moderate |
>= 0.40 |
Poor |
< 0.40 |
The package retains these strict, conservative thresholds as triage boundaries. No analysis has calibrated them to an identification probability, false discovery rate, or fixed instrument platform. The current PeptideAtlas analysis contained too few negative protein-level examples for reliable calibration. Use the labels for ranking and review, not as experimental outcome claims.
Worked outputs
digest_report(evaluate_digest(bsa_path, enzyme = "trypsin", missed_cleavages = 1L))
#> pepVet digest check
#> -------------------
#> Protein sp|P02769|ALBU_BOVIN Albumin OS=Bos taurus OX=9913 GN=ALB
#> PE=1 SV=4
#> Enzyme trypsin
#> Preset standard
#> Missed cleavages Up to 1
#> Peptides 157 total; 108 within 7-25 aa
#> Verdict Good
#> Composite 0.885
#> Component Score Profile
#> S_length 0.688 [#######---]
#> S_coverage 0.997 [##########]
#> S_count 1.000 [##########]
#> S_hydro 0.769 [########--]
#> S_charge 0.778 [########--]
digest_report(evaluate_digest(h3_path, enzyme = "trypsin"))
#> pepVet digest check
#> -------------------
#> Protein sp|P68431|H31_HUMAN Histone H3.1 OS=Homo sapiens OX=9606
#> GN=H3C1 PE=1 SV=2
#> Enzyme trypsin
#> Preset standard
#> Missed cleavages Up to 1
#> Peptides 59 total; 18 within 7-25 aa
#> Verdict Moderate
#> Composite 0.619
#> Component Score Profile
#> S_length 0.305 [###-------]
#> S_coverage 0.632 [######----]
#> S_count 0.662 [#######---]
#> S_hydro 0.833 [########--]
#> S_charge 0.833 [########--]The two reports show the component values for BSA and H3.1 under the specified trypsin settings. Interpret the displayed values rather than treating either protein as a universal positive or negative control.
Interpretation boundaries
The model is intended for within-configuration digest ranking. Its limits and the available empirical checks define how far that interpretation can go.
Limitations
The current model has several limits.
- It does not model post-translational modifications directly.
- It does not model chromatographic gradients, charge-state envelopes, or instrument-specific fragmentation methods.
- It uses heuristic windows and thresholds rather than empirically calibrated identification probabilities.
- It assumes the supplied proteome digest is the relevant comparison space for uniqueness.
- It assumes the active GRAVY and length windows describe a conventional C18 reversed-phase LC with ESI unless a different preset or custom configuration is supplied.
- It treats the weight vectors as expert priors, not validated coefficients.
These limits define the intended use: digest planning, enzyme ranking, and pre-acquisition triage under an explicit scoring configuration.
Scope
pepVet scores are rankings, not calibrated probabilities. The composite score has no unit. Comparisons should remain within one enzyme-workflow configuration.
Cross-preset comparisons are not valid just because the numeric scale
looks the same. A standard score of 0.75 and a
targeted score of 0.60 reflect different
weight vectors and can answer different questions.
Empirical evaluation
A January 2026 analysis evaluated the default parameters against a human PeptideAtlas build containing 5.3 million unique observed peptide sequences. Internal score diagnostics also described component relationships. These analyses provide evidence about the sampled data and model behavior, but they do not establish performance across organisms, enzymes, instruments, or workflows.
Score diagnostics (
score_diagnostics()): VIF, PCA, and ablation describe component relationships and the effect of removing each component in the evaluated sample. See the Score Diagnostics article.PeptideAtlas concordance: in the sampled human tryptic digests, the mean observation rate was 38.0 percentage points higher for peptides inside the default length and GRAVY windows than for peptides outside them (bootstrap 95% CI [36.1, 40.0] percentage points). Wider grid-search ranges produced greater enrichment, which is consistent with the defaults acting as strict, conservative filters rather than estimated detection boundaries. See the PeptideAtlas Concordance article for the analysis and its limitations.
References
Mallick P, Schirle M, Chen SS, et al. Computational prediction of proteotypic peptides for quantitative proteomics. Nature Biotechnology. 2007;25:125-131. doi: 10.1038/nbt1275.
Session info
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.4 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
#> [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
#> [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
#> [10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] pepVet_0.99.1
#>
#> loaded via a namespace (and not attached):
#> [1] vctrs_0.7.3 crayon_1.5.3 cli_3.6.6
#> [4] knitr_1.51 rlang_1.3.0 xfun_0.60
#> [7] otel_0.2.0 generics_0.1.4 textshaping_1.0.5
#> [10] jsonlite_2.0.0 glue_1.8.1 S4Vectors_0.51.5
#> [13] Biostrings_2.81.5 htmltools_0.5.9 stats4_4.6.1
#> [16] ragg_1.5.2 sass_0.4.10 cleaver_1.51.0
#> [19] rmarkdown_2.31 Seqinfo_1.3.0 tibble_3.3.1
#> [22] evaluate_1.0.5 jquerylib_0.1.4 fastmap_1.2.0
#> [25] IRanges_2.47.2 yaml_2.3.12 lifecycle_1.0.5
#> [28] compiler_4.6.1 fs_2.1.0 pkgconfig_2.0.3
#> [31] XVector_0.53.0 systemfonts_1.3.2 digest_0.6.39
#> [34] R6_2.6.1 utf8_1.2.6 pillar_1.11.1
#> [37] magrittr_2.0.5 bslib_0.11.0 tools_4.6.1
#> [40] pkgdown_2.2.1 BiocGenerics_0.59.10 cachem_1.1.0
#> [43] desc_1.4.3