diff --git a/.github/workflows/readme-screenshots.yml b/.github/workflows/readme-screenshots.yml new file mode 100644 index 0000000..b460978 --- /dev/null +++ b/.github/workflows/readme-screenshots.yml @@ -0,0 +1,80 @@ +name: Refresh README screenshots + +# Commit curated browser-test images only for documentation updates. +on: + push: + branches: + - docs/project-readme + paths: + - README.md + workflow_dispatch: + inputs: + run_id: + description: Successful Interface browser preview run ID (optional) + required: false + type: string + +permissions: + actions: read + contents: write + +jobs: + curate: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: true + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Install image tools + run: python -m pip install --quiet pillow + - name: Retrieve real browser captures + env: + GH_TOKEN: ${{ github.token }} + GIVEN_RUN: ${{ inputs.run_id }} + shell: bash + run: | + set -euo pipefail + run_id="$GIVEN_RUN" + if [[ -z "$run_id" ]]; then + run_id="$(gh run list --workflow ui-preview.yml --status success --limit 1 --json databaseId --jq '.[0].databaseId')" + fi + [[ "$run_id" =~ ^[0-9]+$ ]] || { echo "No successful browser run found"; exit 1; } + echo "Source run: $run_id" + mkdir -p benchmarks/output/ui-preview + gh run download "$run_id" --name ramplotr-interface-preview --dir benchmarks/output/ui-preview + echo "RUN_ID=$run_id" >> "$GITHUB_ENV" + - name: Create image crops + run: python scripts/curate-readme-screenshots.py + - name: Record screenshot provenance + shell: bash + run: | + cat > docs/screenshots/README.md < | Expandable sequence tracks for four chains of 1BBB | +| **Prediction confidence and PAE** | **Multi-model ensemble analysis** | +| Synthetic AlphaFold-style PAE heatmap linked to the structure viewer | Circular angle and classification consistency analysis of NMR models | + +## Get started + +### Run the interactive app + +Install [R](https://www.r-project.org/) (a current R 4.x release), clone the repository and start the Shiny application: + +```bash +git clone https://github.com/BiKC/RamplotR.git +cd RamplotR +``` ```r -install.packages(c("shiny", "shinyWidgets", "colourpicker", "bio3d", "NGLVieweR", "DT", "jsonlite")) +install.packages(c( + "shiny", "shinyWidgets", "colourpicker", "bio3d", + "NGLVieweR", "DT", "jsonlite", "htmltools", "xml2" +)) shiny::runApp("shinyRam") ``` -The input panel lets you select a four-character PDB identifier or upload a local PDB or mmCIF structure (.pdb, .ent, .cif, .mcif, .mmcif). Uploads retain insertion codes and atom alternate locations for backbone processing. Structures with consistent multiple models offer a model selector. Both PDB and mmCIF uploads are supported; see the [inspection guide](docs/inspection-user-guide.md) for the current model and comparison limitations. - -## Scientific interpretation - -Reference density grids are in `shinyRam/static/`. They include the original distributions derived from the protein selection discussed by [Lovell et al. (2003)](https://pubmed.ncbi.nlm.nih.gov/12557186/), plus additional datasets. The chosen background controls the visual plot; residue-aware classification uses corresponding General, GLY, PRO and preProline grids from the selected dataset. The explicitly labelled legacy mode reproduces classification against the displayed background. +Enter a four-character **PDB ID** (for example, `1CRN`), **upload** your own PDB/mmCIF structure or choose **AlphaFold DB** to retrieve an available model by UniProt accession. Local uploads support `.pdb`, `.ent`, `.cif`, `.mcif` and `.mmcif`. -Reference distributions and density-percentile thresholds in RamplotR must not be described as equivalent to MolProbity quality metrics without independent validation. Save the selected reference dataset, scientific mode, threshold settings and application version alongside published results. +The project has also been hosted at [bioit.shinyapps.io/RamplotR](https://bioit.shinyapps.io/RamplotR/), but that deployment may not reflect the latest GitHub version. Running locally is the most reliable way to use the current implementation. Public-accession retrieval requires an internet connection; uploaded coordinates and local map files can be inspected without an external folding service. -## Interface +### Analyse many structures -The primary plot and 3D viewer share a selected-residue inspector, which remains visible when you switch tabs. A compact sequence overview directly beneath these views shows **every selected chain at once**; expand it to browse individual residues without leaving the plot. The loaded interface also offers a condensed laptop layout and a reversible focus mode for hiding analysis settings. Click a point, row, sequence letter or residue in the molecular structure to show the corresponding residue across all views. The inspector includes **Show in plot**, **Clear**, and outlier-review navigation. Changing residue filters, density reference, classification mode or palette updates the result without refetching the structure. +From the repository root, process a structure or a directory containing supported structure files: -The residue table has readable angles, combined scientific/review filters and CSV export. The 3D viewer supports cartoon, ribbon, sticks, ball-and-stick and surface representations; ligand, DNA, RNA, spin and rock controls remain visible beneath the viewer as modern switches. RamplotR's own ordered publication palette is selected by default, with legacy colour schemes and custom colours still available. +```bash +Rscript scripts/ramplotr-batch.R --input structures/ --output results/ --report +``` -The optional comparison tab aligns a chain from each of two structures by sequence and displays angular and classification differences, including insertions and deletions. Multi-model structures can be inspected model by model. The Summary tab exports vector SVG and 300-dpi PNG plots plus a self-contained report with reproducibility settings. +The offline command produces per-residue CSV, machine-readable JSON and a batch summary; `--report` additionally requests SVG and standalone HTML reports. For a compatible multi-model structure, add `--ensemble-models 20`. Use `--help` for all options, including declared prediction provenance and an optional matching wwPDB validation XML. -### AlphaFold and ESMFold confidence (Phase B) +See the [batch-analysis instructions](docs/phase-c-guide.md#offline-batch-mode) for examples and resource limits. -AlphaFold DB accession lookup and explicit AlphaFold 2/3, ColabFold and ESMFold upload provenance can add pLDDT tracks beneath every chain. AlphaFold PAE and AF3 confidence JSON are optional, strictly matched to the selected coordinates, and shown as a linked, collapsible heatmap. ESMFold local PDBs expose pLDDT from their B-factor fields; standard ESMFold does not provide PAE. Experimental B-factors are never interpreted as prediction confidence. See the [prediction guide](docs/phase-b-guide.md). +## Scientific interpretation -For screenshots, limitations and the complete workflow see the [inspection and publication guide](docs/inspection-user-guide.md). The interface layout and browser verification history are documented in [interface-refresh.md](docs/interface-refresh.md). +RamplotR's **residue-aware mode** evaluates general residues, glycine, proline and pre-proline against their corresponding bundled reference distributions. The selected plotting background is independent of those residue-specific classification calculations. The original density references trace back to the distributions discussed by [Lovell et al. (2003)](https://pubmed.ncbi.nlm.nih.gov/12557186/); other bundled reference datasets can also be selected. -## Extended verification and research workflows (Phase C) +**RamplotR region labels are not interchangeable with MolProbity or wwPDB classifications.** They use different reference populations, residue treatments and region definitions. Our [independent validation results](docs/phase-a-results.md), [reproducible protocol](docs/wwpdb-validation.md) and [pinned experimental-structure corpus](validation/manifest.csv) document agreement in calculated angles as well as differences in classification. For deposited experimental structures, attach the official report for the **same structure and model** when making independent quality assessments. -RamplotR now provides optional **peptide omega and descriptive chi1 -measurements**, imports official **wwPDB rotamer, clash and bond/angle outlier -annotations** as separate evidence, and can overlay **local CCP4/MRC cryo-EM -maps** in NGL. Consistent multi-model structures can be analysed as circular -phi/psi ensembles with residue-level classification agreement. For -reproducible offline studies, `scripts/ramplotr-batch.R` processes a directory -of PDB/mmCIF files and writes CSV, JSON, SVG and standalone HTML reports. -None of the newly computed angle diagnostics is presented as an official -MolProbity or density-fit score. See the -[Phase C guide](docs/phase-c-guide.md) for usage, validation provenance, -resource limits and scientific caveats. +For predictions, pLDDT and PAE describe model confidence rather than experimental verification. ESMFold normally provides pLDDT but not PAE; experimental thermal B-factors are **never** automatically interpreted as prediction confidence. The native ω, χ1 and Cβ measurements are descriptive, and visualising a density map is not a quantitative map–model fit measurement. -## Independent Phase A validation +The default RamplotR teal contour palette provides consistent, recognisable publication figures; changing colours never changes the scientific reference distribution or classification thresholds. Figure and report exports include relevant analysis settings and provenance. -The [independent validation protocol](docs/wwpdb-validation.md) uses official -wwPDB residue-level validation reports to compare RamplotR's angles and -reference-dependent classifications. A [versioned public corpus manifest](validation/manifest.csv) -covers five experimental structures: 1CRN, 1UBQ, 6VXX, 2DQ4 and 1D3Z. The companion -[GitHub Actions workflow](.github/workflows/wwpdb-validation.yml) archives -source XML/mmCIF files, SHA256 hashes, exact software versions, per-residue -results and reference-group contingency matrices. Differences in categories -are explicitly reported instead of falsely claiming the four-group RamplotR -method and six-group MolProbity are identical. The [first five-structure -results](docs/phase-a-results.md), [pinned numerical results](validation/baseline-2026-09-28.csv) -and [pinned official source SHA256 hashes](validation/baseline-source-hashes-2026-09-28.csv) -are available for independent review. In particular, the outlier-rich 2DQ4 -case exposes important differences between RamplotR and wwPDB outlier calls. +## Documentation -AlphaFold and ESMFold predicted-structure ingestion and linked confidence -assessment are implemented separately from Phase A's independent experimental -validation benchmark. Confidence is additional model evidence, not an official -wwPDB/MolProbity quality score. +- [Interactive inspection, colours, comparisons and exports](docs/inspection-user-guide.md) +- [AlphaFold, ColabFold and ESMFold confidence analysis](docs/phase-b-guide.md) +- [Geometry, official wwPDB evidence, cryo-EM overlays, ensembles and batch mode](docs/phase-c-guide.md) +- [Independent wwPDB validation protocol and benchmark results](docs/wwpdb-validation.md) · [Results](docs/phase-a-results.md) +- [Performance and large-structure benchmarks](docs/benchmark-results.md) · [Scaling results](docs/scaling-results.md) -## Regression tests +Developers can run the pure-R scientific regression suite from the repository root with `Rscript tests/scientific.R`. Additional tests cover structure parsing, validation imports, confidence formats, geometry, ensembles and the batch CLI. GitHub Actions also exercises the application in a real browser and runs the scientific tests on Ubuntu and Windows. -Pure-R tests do not require Shiny or Bio3D. From the repository root: +The [`v0.1.0-legacy` tag](https://github.com/BiKC/RamplotR/tree/v0.1.0-legacy) preserves the historical version for reproducing earlier analyses. Record the exact RamplotR revision and reference dataset when publishing results. -```sh -Rscript tests/scientific.R -Rscript tests/peptide.R -Rscript tests/input.R -Rscript tests/classification.R -Rscript tests/inspection.R -``` +## Research use and citation -GitHub Actions runs source parsing, scientific regression tests and inspection/alignment tests on Ubuntu and Windows. Its full-browser job runs the Shiny app with real PDB input, checks table alignment and linked views, and exercises figure/report export and an actual multi-model NMR fixture. The separate structure validation workflow checks real structures and reference classifications. +RamplotR has been used to visualise protein models in the study *[Unveiling Intra-Clonal Diversity of Monkeypox Virus from Brazil's First Outbreak Wave](https://doi.org/10.3390/v18010062)* (Witt et al., *Viruses*, 2026), including supplementary Ramachandran plots of viral polymerase and helicase models. This is an example of its research use, not an independent validation of the software. -## Project files +When using RamplotR in a publication, cite the software repository and the **exact version or commit** you used, and report the selected reference dataset and analysis mode. -- `shinyRam/app.R`: user interface and Shiny server -- `shinyRam/R/`: structure loading, backbone analysis and classifications -- `shinyRam/static/`: reference-density matrices -- `shinyRam/www/`: plotting JavaScript and bundled viewer assets -- `tests/`: isolated scientific and input tests -- `docs/upgrade-worklog.md`: original scientific upgrade plan and verification status -- `docs/upgrade-inspection-worklog.md`: current inspection-upgrade checklist -- `docs/inspection-user-guide.md`: user workflow, colour scheme, export and comparison guidance +## License -MIT license; see LICENSE. +[MIT](LICENSE). The bundled reference datasets and external validation reports retain their respective scientific provenance; consult the linked documentation when reusing those data. diff --git a/docs/screenshots/README.md b/docs/screenshots/README.md new file mode 100644 index 0000000..a716e85 --- /dev/null +++ b/docs/screenshots/README.md @@ -0,0 +1,14 @@ +# Example screenshots + +The screenshots are cropped from real Shiny browser tests, not mock-up renders. +Source: https://github.com/BiKC/RamplotR/actions/runs/36488764177 + +- Overview and linked inspection: uploaded experimental 1CRN structure. +- Multi-chain sequence: 1BBB multimer. +- Prediction PAE: synthetic AlphaFold 2/ColabFold-style confidence test data (illustrative only). +- Ensemble: 1D3Z NMR multi-model structure. + +To regenerate, extract a recent successful interface browser-test artifact +to benchmarks/output/ui-preview, then run +python scripts/curate-readme-screenshots.py. +Review the crops after layout changes. diff --git a/docs/screenshots/all-chains.png b/docs/screenshots/all-chains.png new file mode 100644 index 0000000..60bbf49 Binary files /dev/null and b/docs/screenshots/all-chains.png differ diff --git a/docs/screenshots/ensemble.png b/docs/screenshots/ensemble.png new file mode 100644 index 0000000..2e8f43d Binary files /dev/null and b/docs/screenshots/ensemble.png differ diff --git a/docs/screenshots/overview.png b/docs/screenshots/overview.png new file mode 100644 index 0000000..c150181 Binary files /dev/null and b/docs/screenshots/overview.png differ diff --git a/docs/screenshots/prediction-pae.png b/docs/screenshots/prediction-pae.png new file mode 100644 index 0000000..32450dd Binary files /dev/null and b/docs/screenshots/prediction-pae.png differ diff --git a/docs/screenshots/residue-inspection.png b/docs/screenshots/residue-inspection.png new file mode 100644 index 0000000..1bf14af Binary files /dev/null and b/docs/screenshots/residue-inspection.png differ diff --git a/scripts/curate-readme-screenshots.py b/scripts/curate-readme-screenshots.py new file mode 100644 index 0000000..9e8a38c --- /dev/null +++ b/scripts/curate-readme-screenshots.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +"""Curate real browser-test screenshots for the project README. + +Input: screenshots in benchmarks/output/ui-preview from a successful UI run. +Output: cropped, optimised PNGs in docs/screenshots. + +Review the resulting images before committing them after interface changes. +Prediction examples may use synthetic fixtures; captions must disclose this. +""" +from pathlib import Path +from PIL import Image + +SOURCE = Path("benchmarks/output/ui-preview") +DEST = Path("docs/screenshots") + +# Coordinates refer to the tested 1440x940 / 1366x900 full-page captures. +# Crop the relevant analysis panel, not the compact structure-input toolbar. +EXAMPLES = { + "overview.png": ("desktop-loaded.png", (355, 232, 1405, 1205)), + "residue-inspection.png": ("desktop-residue-zoom.png", (5, 165, 1420, 1120)), + "all-chains.png": ("all-chains-expanded.png", (380, 1030, 1040, 1690)), + "prediction-pae.png": ("prediction-af2-pae.png", (355, 1390, 1300, 2180)), + "ensemble.png": ("phase-c-ensemble.png", (380, 812, 1340, 1570)), +} + +def main(): + DEST.mkdir(parents=True, exist_ok=True) + for name, (original, bounds) in EXAMPLES.items(): + path = SOURCE / original + if not path.is_file(): + raise FileNotFoundError(f"Missing {path}; rerun the real browser tests.") + with Image.open(path) as picture: + if picture.width < bounds[2] or picture.height < bounds[3]: + raise ValueError(f"{original}: unexpected {picture.size}; update crop after reviewing UI.") + crop = picture.convert("RGB").crop(bounds) + crop.thumbnail((1150, 1500), Image.Resampling.LANCZOS) + crop.save(DEST / name, format="PNG", optimize=True) + print(f"{name}: {crop.width}x{crop.height}") + +if __name__ == "__main__": + main()