Skip to main content

diagfdr (Python)

Scope, calibration and stability diagnostics for target–decoy FDR claims in proteomics. A Python port of the R package diagFDR 0.2.1, for pipelines that live in Python (mokapot, MS²Rescore, DIA-NN post-processing). Every function mirrors its R counterpart and returns the same numbers on the same input: the test suite compares each diagnostic with oracle values written by the R package (tests/fixtures/make_fixtures.R) and reproduces every number of the article from the deposited exports (tests/test_paper_numbers.py).

Reference: Chion M, Godmer A, Douché T, Matondo M, Giai Gianetto Q (2026). diagFDR: Assessing False Discovery Rate Claims in Proteomics with Scope, Calibration and Stability Diagnostics. bioRxiv 10.64898/2026.04.16.718468.

Install

pip install diagfdr            # once released; until then:
pip install .                  # from this folder (add [parquet] for DIA-NN parquet reports)

Dependencies: numpy, pandas, scipy, jinja2; pyarrow for .parquet.

Command line

diagfdr report report.parquet --tool diann --qvalue-ceiling 0.5 --two-pass \
    --entrapment-fasta arabidopsis.fasta --size-ratio 0.432 --size-ratio-protein 0.155 \
    --out diagfdr_report.html
diagfdr report psms.txt --decoy-file decoy.psms.txt --tool mokapot --out report.html
diagfdr report msms.txt --tool maxquant --out report.html
diagfdr report Report.tsv --tool spectronaut --out report.html

report builds the natural lists of the export (for DIA-NN: experiment-wide Global.Q.Value, the min-over-runs Q.Value list that the paper flags as a scope mismatch, run × precursor, and protein groups under a label rule), runs every diagnostic, and writes an HTML report plus one CSV per table in <out>_tables/. The headline row of each list ends with a status (NO_ALERT / CAUTION / ALERT) and a reporting sentence following the five-item standard. Alerts motivate inspection; they are not verdicts.

Python API

import diagfdr as dg

rep  = dg.read_diann_parquet("report.parquet")
glob = dg.diann_global_precursor(rep, "Global.Q.Value", q_max_export=0.5, two_pass=True)
minr = dg.diann_global_minrunq(rep, q_col="Q.Value", q_max_export=0.5, two_pass=True)
pg   = dg.diann_global_proteingroup(rep, "Global.PG.Q.Value", rule="split", q_max_export=0.5, two_pass=True)

dg.headline(glob, 0.01)                    # T_alpha, D_alpha, decoy ratio, D^-1/2, FDP-CV benchmark
dg.local_tail(glob, [0.01])                # D_alpha,win
dg.ipe(glob)["IPE"]                        # decoy-reference PEP concordance error
dg.equal_chance_qbands(glob)["pooled"]     # decoy fraction at low confidence (single-pass only)
dg.scope_disagreement(glob, minr, [0.01])  # Jaccard between scope choices
dg.label_rule_audit(rep, "Protein.Group", "Global.PG.Q.Value", alpha=0.01, pep_col=None)
dg.picked_protein(pg, 0.01)

acc = set(dg.read_fasta_accessions("entrapment.fasta"))
ent = dg.diann_entrapment_ids(rep, acc)                       # precursors mapping only to the entrapment proteome
dg.entrapment(glob, ent, alpha=0.01, r=0.432)                 # raw (lower bound) and corrected (Wen et al.) estimates
dg.entrapment_discordant(glob.accepted(0.01), minr.accepted(0.01), ent)   # error on the scope-discordant set
dg.entrapment_size_ratio(["target.fasta", "contaminants.fasta"], "entrapment.fasta")   # r

diag = dg.run_all({"global": glob, "min_r": minr, "protein groups (split)": pg}, alpha_main=0.01)
dg.write_report(diag, "diagfdr_report.html")

Other readers: read_mokapot_psms + mokapot_competed_universe(q_mode="as_exported"|"recount"), read_maxquant_msms, maxquant_competed_msms, read_spectronaut + spectronaut_runxprecursor. Any table with columns id, is_decoy, q, pep, run, score can be wrapped in DfdrTable(...). Simulation with known truth: simulate_tdc, realised_fdp, check_cv_benchmark.

Not ported (use the R package): the mzIdentML reader, the pseudo-p-value / Storey π0 / BH diagnostics, and the plotting functions.

Tests

pip install .[test]
pytest                                   # 16 comparisons with the R oracle
DIAGFDR_DATA=/path/to/zenodo_18621806 pytest   # + the article's numbers (DIA-NN, entrapment, MS²Rescore)

Licence

GPL-3.0-or-later, as the R package.

Metadata

Release files for diagfdr 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for diagfdr 0.1.0
File Size Uploaded Provenance Actions
diagfdr-0.1.0.tar.gz 49.1 kB Without provenance Details for diagfdr-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for diagfdr 0.1.0
File Interpreter ABI Platform Actions
diagfdr-0.1.0-py3-none-any.whl Python 3 none any Details for diagfdr-0.1.0-py3-none-any.whl

Total release size: 98.7 kB

Release files / diagfdr-0.1.0.tar.gz

Download URL diagfdr-0.1.0.tar.gz
Size 49.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3793554e61c2b54118976201b79a7b31c9605bb81b39f37a615a7ee9cef4d197
BLAKE2b-256 checksum
How to use checksums
7ce5fafe146fdd9500a2034a32cd9b82ce1a91f0a0c4cfc031d09cacd756f327
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / diagfdr-0.1.0-py3-none-any.whl

Download URL diagfdr-0.1.0-py3-none-any.whl
Size 49.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9fc63e0a1f34a22ded95d74eba2e896e33b947f110a4f6902a3ae1562e0f8a5b
BLAKE2b-256 checksum
How to use checksums
b6afbf66b63e36a2473659ec3020371b4f1021eb80496c9923d72c4b831b3797
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for diagfdr 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page