Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ alphajudge PATH [PATH ...] \
--ipsae_pae_cutoff 10.0 \
[-r|--recursive] \
[-o|--summary SUMMARY.csv] \
[--cores]
[--cores] \
[--report | --no-report] \
[--aggregate_report AGGREGATE.pdf]
```

- **PATH**: One or more run directories or roots to search
Expand All @@ -93,11 +95,24 @@ alphajudge PATH [PATH ...] \
- **-r / --recursive**: Recursively discover runs under each PATH
- **-o / --summary**: Write an aggregated CSV across all processed runs
- **--cores**: Number of processes to use across run directories (0 = all available cores)
- **--report / --no-report**: Write an RCSB-style `report.pdf` next to each per-run `interfaces.csv`. Default is on for single-run scoring and off when `--summary` is used, so benchmark aggregations stay fast.
- **--aggregate_report AGGREGATE.pdf**: After scoring, build a multi-page validation PDF from the `--summary` CSV with one slider page per interface ranked by meta score (requires `--summary`).

Outputs:
- Always writes `interfaces.csv` inside each processed run directory.
- For each processed model, also writes a PAE heatmap PNG `pae_<model>.png` next to `interfaces.csv`.
- If `--report` is on, also writes `report.pdf` next to `interfaces.csv` -- an RCSB-style validation report with a percentile slider panel for every detected interface.
- If `--summary` is provided, also writes a union-header CSV at the given path containing rows from all runs.
- If `--aggregate_report` is provided, also writes a multi-page PDF with one slider page per interface across the whole cohort, plus a cover with the meta-score histogram, summary statistics, and a top-N interfaces table.

Report generation is backend-agnostic: AF2, AF3, and Boltz-2 runs all flow through the same scoring path, so `--report` and `--aggregate_report` work identically for any mix of supported predictions in one cohort. Multimers contribute one slider page per detected chain pair; dimers contribute one.

A separate `alphajudge-report` console entry is also available; it dispatches to per-run mode when given a run directory and to aggregate mode when given a summary CSV:

```bash
alphajudge-report path/to/run_dir --out-pdf path/to/report.pdf
alphajudge-report path/to/summary.csv --out-pdf path/to/aggregate.pdf
```

Examples

Expand All @@ -118,6 +133,12 @@ alphajudge test_data/af2/pos_dimers/Q13148+Q92900 \

# Recursively discover runs under roots and write a combined summary
alphajudge test_data/af2/pos_dimers test_data/af3/pos_dimers -r -o interfaces_summary.csv

# Score a cohort (any mix of AF2 / AF3 / Boltz-2 run dirs) and emit a cohort-wide
# validation PDF with one slider page per detected interface
alphajudge test_data/af2/pos_dimers test_data/af3/pos_dimers -r \
-o interfaces_summary.csv \
--aggregate_report aggregate_report.pdf
```

---
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ test = [

[project.scripts]
alphajudge = "alphajudge.cli:main"
alphajudge-report = "alphajudge.report:main_aggregate"

[project.urls]
Homepage = "https://github.com/KosinskiLab/AlphaJudge"
Expand Down
70 changes: 54 additions & 16 deletions src/alphajudge/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import argparse
import logging

from .report import generate_aggregate_report
from .runner import process_many


Expand Down Expand Up @@ -41,26 +42,63 @@ def main() -> None:
default=1,
help="Number of processes to use across run directories (0 = all available cores)",
)
report_group = p.add_mutually_exclusive_group()
report_group.add_argument(
"--report",
dest="report",
action="store_true",
help="Write an RCSB-style report.pdf next to each per-run interfaces.csv "
"(default on for single-run scoring, off when --summary is used).",
)
report_group.add_argument(
"--no-report",
dest="report",
action="store_false",
help="Skip per-run report.pdf generation.",
)
p.set_defaults(report=None)
p.add_argument(
"--aggregate_report",
default=None,
help="If set, write an aggregate validation PDF to this path. "
"Reads the --summary CSV after scoring.",
)
args = p.parse_args()
logging.basicConfig(level=logging.INFO, format="%(levelname)s:%(message)s")
if args.paths:
process_many(
args.paths,
args.contact_thresh,
args.pae_filter,
args.models_to_analyse,
recursive=args.recursive,
summary_csv=args.summary,
cores=args.cores,
ipsae_pae_cutoff=args.ipsae_pae_cutoff,
force_recompute=args.force_recompute,
per_run_csv_name=args.per_run_csv_name,
skip_pae_png=args.skip_pae_png,
skip_biophysical_scores=args.skip_biophysical_scores,
)
else:
if not args.paths:
p.error("Provide PATHS")

write_per_run_report = args.report
if write_per_run_report is None:
write_per_run_report = args.summary is None

summary_path = process_many(
args.paths,
args.contact_thresh,
args.pae_filter,
args.models_to_analyse,
recursive=args.recursive,
summary_csv=args.summary,
cores=args.cores,
ipsae_pae_cutoff=args.ipsae_pae_cutoff,
force_recompute=args.force_recompute,
per_run_csv_name=args.per_run_csv_name,
skip_pae_png=args.skip_pae_png,
skip_biophysical_scores=args.skip_biophysical_scores,
write_per_run_report=write_per_run_report,
)

if args.aggregate_report:
if not args.summary:
p.error("--aggregate_report requires --summary")
if summary_path is None:
p.error(
f"--aggregate_report requested but no summary was written to "
f"{args.summary}; refusing to build a report from a possibly "
"stale CSV"
)
generate_aggregate_report(summary_path, out_pdf=args.aggregate_report)


if __name__ == "__main__":
main()
Loading
Loading