Skip to content

Search and filters in the PSM and protein tables' own filter menu - #81

Open
t0mdavid-m wants to merge 10 commits into
mainfrom
claude/filter-bar
Open

t0mdavid-m wants to merge 10 commits into
mainfrom
claude/filter-bar

Conversation

@t0mdavid-m

@t0mdavid-m t0mdavid-m commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Needs openms-insight with t0mdavid-m/OpenMS-Insight#32 released. That PR adds the table options this one uses (search, search_placeholder, numeric_filters). requirements.txt still pins openms-insight==0.4.0. After the release, this PR needs one more commit that bumps the pin. Until then, tests/test_sequence_display.py::test_filtered_table_adds_q_values_and_a_filter_menu fails against 0.4.0. Everything else passes either way.

Before: the PSM and Identified proteins pages only had the Insight Table's per-column filter dialog:

  • You couldn't search the whole table.
  • You couldn't tighten the FDR, drop one-hit proteins, require a protein in several replicates of a condition, or hide contaminants on the protein table.
  • The PSM table showed only the score, which is Percolator's PEP, while the page's info box called it the q-value.

After: each table filters itself, from its own toolbar and filter menu. There is no separate filter bar above it.

  • PSM table:
    • The search box in the toolbar searches the sequence in any modification form (M(ox), M[Oxidation] and M(Oxidation) all match) and the protein accessions.
    • The filter button opens the dialog on q-value thresholds. "1 % (run)", the run's own FDR, comes first, then 0.5 / 0.1 / 0.01 %, so a threshold can only tighten the run's.
    • A new q-value column sits next to Score. m/z and RT are rounded for display, and the info box says what Score and q-value are.
  • Protein table:
    • The search box searches accession, gene and description.
    • The dialog offers peptides ≥ 2 / 3 / 5 (distinct peptides) and replicates ≥ 1 … n. "Replicates" is the most files of one condition with a PSM of the protein, using the conditions from Describe experiment, and is shown in a new replicates column. A fractionated run counts samples, not fractions.
    • The key figures above the table count what its filters leave, without contaminants.
  • Contaminants keep openms-insight's toggle_filters checkbox in each table's title row. It is on by default for proteins and off for PSMs.
  • Every filter in force shows as a chip under the toolbar. Each chip can be removed, and "Clear all" removes them all. The filters stay when you leave the page and come back.

Dropped: the protein page's PSM q-value threshold. It filtered the PSMs underneath the protein table, so it changed each protein's peptide and PSM counts, its coverage and the linked peptide and PSM tables. A filter on a column of the protein table can't express that. Faking it with a per-protein "best q-value" column would keep proteins whose counts still include PSMs above the threshold, which is misleading. The PSM table keeps its q-value threshold.

How: the search and the thresholds are openms-insight Table options, applied in Python over every row through the table's pagination state. Neither a search nor a threshold builds a new cache.

  • PSM page: sequence_display.filtered_table_id() builds one table variant per run and sequence form from the workflow's cached PSM table, as the modification-display variants already do. It adds q_value (read from the idXML in id_idx order) and not_contaminant, and declares search=[sequence, sequence_display, proforma, protein_accession], numeric_filters={"q_value": ...} and toggle_filters. The thresholds offered come from result_filters.q_suggestions().
  • Protein page: it passes the whole protein table to show_insight_table with search, numeric_filters (protein_numeric_filters()) and toggle_filters. show_insight_table now returns the Table, so the key figures come from Table.export_data(state), the rows the viewer's filters leave.
  • src/common/filter_bar.py is removed. The no-Streamlit logic stays in src/common/result_filters.py.

walkthrough

Proteins: dialog with thresholds Proteins: ≥ 2 peptides, ≥ 2 replicates Proteins: plus search
PSMs: q-value thresholds PSMs: search + q ≤ 0.001 PSMs: q ≤ 0.0001 leaves none

Video (mp4): https://raw.githubusercontent.com/OpenMS/quantms-web/claude/media-nav/r6-table-menu.mp4

Testing

  • Real LFQ run on 4 demo files (2 per condition, UPS2_ratio01 / UPS2_ratio10, yeast + UPS2 database, 1 % PSM FDR), in headless Chromium with the openms-insight branch on PYTHONPATH.
  • Identified proteins (key figures: proteins / peptides / PSMs):
    • no filters: 627 / 850 / 3,979;
    • ≥ 2 peptides and ≥ 2 replicates: 166 / 404 / 2,577, the same as the previous filter bar gave;
    • plus search "dehydrogenase": 11 / 25 / 239;
    • "Clear all": 627 / 850 / 3,979.
  • PSM table, file B000248: 1,013 PSMs; "CAH2" leaves 23. Every PSM that passed in this run has q = 0.00095, so q ≤ 0.001 keeps all 23 and q ≤ 0.0001 leaves none ("Showing 0 rows"). Removing that chip brings back the 23.
  • tests/test_result_filters.py covers:
    • q thresholds start at the run and never loosen it, including a run without a PSM filter;
    • the protein thresholds offered;
    • replicates per condition, and per sample for fractions;
    • the protein flags and the column placement.
  • test_filtered_table_adds_q_values_and_a_filter_menu checks:
    • q-values join by id_idx;
    • the variant's search / threshold / toggle config;
    • the variant is built once;
    • the table's own ProForma search and q threshold.
  • python -m pytest tests/ test_gui.py with the openms-insight branch: 363 passed, 2 skipped. With the pinned 0.4.0: the one test named above fails, all others pass. python -m py_compile content/*.py src/common/*.py: clean. pylint --errors-only: only the existing E0611 errors on pyopenms imports.

Note: with 4 or more files the protein table folds its per-file columns into the rows (Tabulator's responsive collapse). That happens on main too, and this PR doesn't change it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk

The PSM FDR on Configure was a bare number field in percent, easy to
misread as a q-value. It now offers 0.1 / 1 / 5 % as quick choices next
to the number field and reads the level back as "1 % = keep PSMs with
q ≤ 0.01"; at 100 % it says the filter is not applied. The stored
parameter (psm-fdr-percent) is unchanged. src/common/fdr_display.py
holds the wording so the results pages can reuse it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
Both pages get a filter bar above their table. The PSM table: a search
over sequence (any modification form) and proteins, and a q-value
threshold that can only tighten the run's PSM FDR; a new q-value column
shows Percolator's q-value next to the score. The protein table: search
over accession, gene and description, the same q-value threshold
(applied to the PSMs, so peptide and PSM counts follow), a minimum of
distinct peptides, and "found in at least n replicates of a condition"
from the conditions set on Describe experiment.

Contaminants are shown or hidden with openms-insight's own toggle in
the table's title row (hidden by default on the protein table, shown
on the PSM table as before), and the q-value threshold of the PSM table
is an insight range filter, so changing it needs no new cache. The
filter logic lives in src/common/result_filters.py, without Streamlit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
@t0mdavid-m t0mdavid-m self-assigned this Nov 2, 2026
Base automatically changed from claude/fdr-input to main November 2, 2026 08:52
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 290001db-aa85-4ae1-a1f4-a33eaf027e61
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Combine the protein filters with per-sample counts for fractionated runs:
"found in n replicates" counts samples, not fractions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
The peptide table of the protein page got extra_key twice (the q-value
threshold and the per-sample key), a SyntaxError on that page; key the
cache on both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
The separate filter bars above the PSM and protein tables are gone. Each
table now filters itself through openms-insight's toolbar search box and
filter dialog, on the server, over every row:

- PSM table: search over the sequence (OpenMS, label and ProForma forms) and
  proteins; q-value thresholds in the dialog, the run's own FDR first, then
  0.5 / 0.1 / 0.01 %.
- Protein table: search over accession, gene and description; "at least"
  thresholds for peptides (2, 3, 5) and, with conditions, replicates.

The filters in force show as removable chips under the table's toolbar. The
protein page's key figures count the rows the table's filters leave
(Table.export_data with the page's state), so show_insight_table now returns
the Table.

Dropped: the protein page's q-value threshold applied to the underlying PSMs.
It changed peptide and PSM counts, coverage and the linked tables, which a
filter on one column of the protein table cannot express.

Needs the table options search / search_placeholder / numeric_filters from
openms-insight (t0mdavid-m/OpenMS-Insight#32); requirements.txt still pins
0.4.0 until that is released.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
@t0mdavid-m t0mdavid-m changed the title Filter bars on the PSM and protein pages Search and filters in the PSM and protein tables' own filter menu Nov 2, 2026

t0mdavid-m commented Nov 2, 2026 •

Copy link
Copy Markdown
Member Author

Three checks are red on 1aaefc8, and none of them needs a code change in this PR:


Generated by Claude Code

@t0mdavid-m
t0mdavid-m enabled auto-merge November 3, 2026 15:21
@t0mdavid-m

Copy link
Copy Markdown
Member Author

fix ci

…ilter menu

openms-insight 0.4.0 predates the Table search box, one-sided numeric
filters and filter chips this PR uses (Insight #32, merged at 01df461).
Until a release has them, requirements.txt installs a wheel built from
Insight main at that commit, with its Vue bundle, from the
claude/insight-dev-wheels branch (sha256-pinned). Replace it with the
next PyPI release before an app release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D5Wo2FHPpi5a8X6GppNxEk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants