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
2 changes: 0 additions & 2 deletions .github/workflows/gene-essentiality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,6 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ inputs.pr }}
BASE_REF: ${{ inputs.base }}
CSV_URL: ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.head_ref || github.ref_name }}/data/testResults/gene-essential-diff.csv
SUMMARY_URL: ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.head_ref || github.ref_name }}/data/testResults/gene-essential_summary.md
run: |
if [ -z "$BASE_REF" ]; then
Expand All @@ -444,7 +443,6 @@ jobs:
--base-model "$RUNNER_TEMP/base/Human-GEM.yml" \
--base-matrix "$RUNNER_TEMP/base/gene-essential.csv" \
--base-label "$BASE_REF" \
--csv-url "$CSV_URL" \
--summary-url "$SUMMARY_URL" \
--out-summary "$RUNNER_TEMP/gene-essential-diff.md" \
--out-detail "$RUNNER_TEMP/gene-essential-diff-detail.md" \
Expand Down
32 changes: 18 additions & 14 deletions code/test/buildReport.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@
BASE_DIR = os.environ.get("BASE_RESULTS_DIR", "")
BASE_REF = os.environ.get("BASE_REF", "the target branch")
COMMIT_SHA = os.environ.get("COMMIT_SHA", "")
# e.g. https://github.com/OWNER/REPO/blob/<branch>/data/testResults - used to link
# each finding count to its CSV. Empty when run locally (then counts are plain text).
# e.g. https://github.com/OWNER/REPO/blob/<branch>/data/testResults - used by the posted
# comment to link each finding count to its CSV (relative links do not resolve in a
# comment). The full-detail file uses relative links. Empty when run locally (then the
# comment's counts are plain text).
URL_BASE = os.environ.get("RESULTS_URL_BASE", "").rstrip("/")

# Groups whose results are still being computed on this run; their rows show as
Expand All @@ -68,11 +70,11 @@ def _slug(label: str) -> str:


def _labelled(label: str) -> str:
"""The test name, linked to its explanation in the testResults README when the
repo URL is known (in CI); plain text when run locally. Full-detail file only --
the condensed comment links whole sections to the full file instead (see module
docstring)."""
return f"[{label}]({URL_BASE}/README.md#{_slug(label)})" if URL_BASE else label
"""The test name, linked to its explanation in the testResults README. Full-detail
file only, which sits next to the README, so the link is relative and does not
depend on the branch; the condensed comment links whole sections to the full file
instead (see module docstring)."""
return f"[{label}](README.md#{_slug(label)})"


# (label, key, kind, group, detail_file)
Expand Down Expand Up @@ -276,14 +278,17 @@ def _icon(value, base, kind):
return "0", ":white_check_mark:", False, False


def _cell(value, kind, detail, *, bold: bool = False) -> str:
def _cell(value, kind, detail, *, bold: bool = False, relative: bool = False) -> str:
"""The value, linked to its detail CSV when it is a positive count or a growth
failure. relative=True links next to the file (the full-detail file, which sits in
the same folder as the CSVs); otherwise the absolute URL is used, as the posted
comment needs, and the value stays plain when the repo URL is not known."""
text = f"{value:.3g}" if kind == "growth" else (f"{value:.1f}" if kind == "score" else str(int(value)))
if bold:
text = f"**{text}**"
# link a positive count (or a growth failure) to its CSV, if we know the repo URL
linkable = (kind == "count" and value) or (kind == "growth" and value <= 1e-6)
if URL_BASE and detail and linkable:
return f"[{text}]({URL_BASE}/{detail})"
if detail and linkable and (relative or URL_BASE):
return f"[{text}]({detail if relative else f'{URL_BASE}/{detail}'})"
return text


Expand Down Expand Up @@ -314,7 +319,7 @@ def _full_table(computed: list[dict]) -> list[str]:
if r["pending"]:
lines.append(f"| {_labelled(r['label'])} | _running_ | | :hourglass_flowing_sand: |")
else:
lines.append(f"| {_labelled(r['label'])} | {_cell(r['value'], r['kind'], r['detail'])} | "
lines.append(f"| {_labelled(r['label'])} | {_cell(r['value'], r['kind'], r['detail'], relative=True)} | "
f"{r['delta']} | {r['icon']} |")
return lines

Expand Down Expand Up @@ -573,8 +578,7 @@ def main() -> int:
"## Model quality report -- full detail",
"",
"_This is the full, per-check breakdown behind the pull-request comment's summary table._ "
+ (f"_Row names link to their explanation in the [testResults README]({URL_BASE}/README.md)._"
if URL_BASE else ""),
"_Row names link to their explanation in the [testResults README](README.md)._",
"",
"### Model & network checks",
"_Duplicate keys (model unloadable) and no growth block the merge; every other row "
Expand Down
14 changes: 6 additions & 8 deletions code/test/diffGeneEssentiality.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
--base-model /path/to/base/Human-GEM.yml \\
--base-matrix /path/to/base/gene-essential.csv \\
[--head-model model/Human-GEM.yml] [--head-matrix data/testResults/gene-essential.csv] \\
[--growth-tolerance 0.01] [--csv-url URL] [--summary-url URL] \\
[--growth-tolerance 0.01] [--summary-url URL] \\
[--out-summary PATH] [--out-detail PATH] [--out-csv PATH]

The base model/matrix are typically pulled from the target branch with ``git show``,
Expand Down Expand Up @@ -308,7 +308,6 @@ def build_report(
*,
growth_tolerance: float = 0.01,
base_label: str = "the target branch",
csv_url: str = "",
summary_url: str = "",
) -> tuple[str, str, str]:
"""Returns ``(comment_text, detail_text, detail_csv_text)``.
Expand All @@ -317,9 +316,9 @@ def build_report(
request comment: icons and counts only, no gene names. ``detail_text`` is the
per-gene breakdown behind it (which genes, what changed), meant to be appended to
the committed ``gene-essential_summary.md`` rather than posted in the comment --
``comment_text`` links to it instead of duplicating it. ``csv_url`` is the
committed blob URL of the per-gene, per-line CSV this call is about to write (e.g.
from ``--out-csv``), linked from ``detail_text``. ``summary_url`` is the committed
``comment_text`` links to it instead of duplicating it. ``detail_text`` links to the
per-gene, per-line CSV (``--out-csv``) by file name, since both sit in
data/testResults; ``summary_url`` is the committed
blob URL of ``gene-essential_summary.md`` (with ``detail_text`` appended to it),
linked from ``comment_text``.
"""
Expand Down Expand Up @@ -455,7 +454,7 @@ def _neutral_status(rows: list[dict]) -> str:
summary = "\n".join(summary_lines) + "\n"

# --- detail: per-gene breakdown, appended to the committed gene-essential_summary.md ---
csv_ref = f"[gene-essential-diff.csv]({csv_url})" if csv_url else "the per-gene detail CSV"
csv_ref = "[gene-essential-diff.csv](gene-essential-diff.csv)"
detail_lines = [
f"### Gene essentiality: effect of this change (vs `{base_label}`)",
"",
Expand Down Expand Up @@ -517,7 +516,6 @@ def main(argv: list[str] | None = None) -> int:
parser.add_argument("--head-matrix", type=Path, default=DEFAULT_HEAD_MATRIX, help="gene-essential.csv for this branch (default: data/testResults/gene-essential.csv)")
parser.add_argument("--growth-tolerance", type=float, default=0.01, help="minimum |growth ratio delta| to flag independent of task-based flips (default: 0.01)")
parser.add_argument("--base-label", type=str, default="the target branch", help="name shown for the base branch, e.g. 'develop' (default: 'the target branch')")
parser.add_argument("--csv-url", type=str, default="", help="committed blob URL of --out-csv, linked from --out-detail instead of duplicating its content there")
parser.add_argument("--summary-url", type=str, default="", help="committed blob URL of gene-essential_summary.md (with --out-detail appended to it), linked from --out-summary")
parser.add_argument("--out-summary", type=Path, default=None, help="write the condensed, pull-request-comment text here instead of only stdout")
parser.add_argument("--out-detail", type=Path, default=None, help="write the per-gene detail text here (meant to be appended to gene-essential_summary.md)")
Expand All @@ -527,7 +525,7 @@ def main(argv: list[str] | None = None) -> int:
summary, detail_text, detail_csv = build_report(
args.base_model, args.head_model, args.base_matrix, args.head_matrix,
growth_tolerance=args.growth_tolerance, base_label=args.base_label,
csv_url=args.csv_url, summary_url=args.summary_url,
summary_url=args.summary_url,
)
print(summary)
if args.out_summary:
Expand Down
7 changes: 7 additions & 0 deletions data/deprecatedIdentifiers/deprecatedMetabolites.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -2395,3 +2395,10 @@ MAM01182m MAM01182 xol7aone C05455 HMDB0001993 CHEBI:17899 123743 LMST04030123
MAM00592m MAM00592 20ahchsterol C05500 HMDB0006283 CHEBI:1296 440711 LMST01010201 20ahchsterol MNXM1364606 m00592m
MAM02754r MAM02754 4nph C00870 HMDB0001232 CHEBI:16836 980 MNXM526
MAM01019r MAM01019 24nph C02235 HMDB0002916 CHEBI:16318 MNXM1982
MAM03586c MAM03586 galgluside_hs C01290 CHEBI:17950 LMSP0501AB00 galgluside_hs MNXM1108011 galgluside_hs_c
MAM03586e MAM03586 galgluside_hs C01290 CHEBI:17950 LMSP0501AB00 galgluside_hs MNXM1108011 galgluside_hs_s
MAM03586g MAM03586 galgluside_hs C01290 CHEBI:17950 LMSP0501AB00 galgluside_hs MNXM1108011 galgluside_hs_g
MAM03586l MAM03586 galgluside_hs C01290 CHEBI:17950 LMSP0501AB00 galgluside_hs MNXM1108011 galgluside_hs_l
MAM01999c MAM01999 fuc14galacglcgalgluside_hs MNXM8835 m01999c m01999c
MAM01999e MAM01999 fuc14galacglcgalgluside_hs MNXM8835 m01999s m01999s
MAM01999g MAM01999 fuc14galacglcgalgluside_hs MNXM8835 m01999g m01999g
12 changes: 12 additions & 0 deletions data/deprecatedIdentifiers/deprecatedReactions.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -533,3 +533,15 @@ MAR20031 MNXR102281 0 RHEA:26205
MAR00117 C4STMO2Pr C4STMO2Pr MNXR96419 0 C4STMO2Pr
MAR00118 C4STMO2r C4STMO2r MNXR96420 0 C4STMO2r
MAR02302 r1146 r1146 0 r1146
MAR01348 GALGLUSIDEtg GALGLUSIDEtg 0 GALGLUSIDEtg
MAR01349 GALGLUSIDEtl GALGLUSIDEtl 0 GALGLUSIDEtl
MAR01351 GALGT1 GALGT1 0 GALGT1
MAR12053 GLA2l GLA2l 0 GLA2l
MAR12065 NEU11l NEU11l 0 NEU11l
MAR12132 EX_galgluside_hs_e EX_galgluside_hs[e] 0 EX_galgluside_hs[e]
MAR01118 FUT34g FUT34g MNXR99739 0 FUT34g
MAR01078 FUCFUCGALACGLCGALGLUSIDEtg FUCFUCGALACGLCGALGLUSIDEtg MNXR99694 0 FUCFUCGALACGLCGALGLUSIDEtg
MAR01076 FUCFUCGALACGLCGALGLUSIDEte FUCFUCGALACGLCGALGLUSIDEte MNXR99694 0 FUCFUCGALACGLCGALGLUSIDEte
MAR00595 EX_fucfucgalacglcgalgluside_hs_e EX_fucfucgalacglcgalgluside_hs[e] 0 EX_fucfucgalacglcgalgluside_hs[e]
MAR01141 FUT93g FUT93g MNXR99751 0 FUT93g
MAR00766 r1410 HMR_0766 0 HMR_0766
12 changes: 6 additions & 6 deletions data/testResults/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ own files. The pull request in each row is the one whose run last wrote those fi

| Result file(s) | Produced by | Last updated by |
| --- | --- | --- |
| `qc_duplicate_keys.csv`, `qc_empty_reactions.csv`, `qc_annotation_consistency.csv`, `qc_deprecation_completeness.csv`, `qc_metabolite_completeness.csv`, `qc_reaction_sanity.csv`, `qc_duplicate_reactions.csv`, `qc_unused_entities.csv`, `qc_growth_blockers.csv` | `qcModelChecks.py` | **PR #1106** (model QC checks) |
| `qc_annotation_issues.csv` | `annotationTest.py` | **PR #1106** (model QC checks) |
| `qc_status.tsv` (round-trip, YAML lint, metabolic tasks, growth) | `testYamlConversion.py`, `testMetabolicTasks.py`, `action-yamllint`, `qcModelChecks.py` (via `qcStatus.py`) | **PR #1106** (model QC checks) |
| `macaw_results.tsv`, `balance_results.csv`, `qc_structure_consistency.csv` | `macawTests.py`, `balanceTest.py`, `structureConsistencyTest.py` | **PR #1106** (MACAW and balance) |
| `memote_score.md` | `memoteSnapshot.py` (fast subset every PR; full suite via `/run memote`) | **PR #1106** (MEMOTE) |
| `gene-essential.csv`, `gene-essential_summary.md` | `gradedEssentiality.py` via `/run gene-essentiality` | **PR #1106** (gene essentiality) |
| `qc_duplicate_keys.csv`, `qc_empty_reactions.csv`, `qc_annotation_consistency.csv`, `qc_deprecation_completeness.csv`, `qc_metabolite_completeness.csv`, `qc_reaction_sanity.csv`, `qc_duplicate_reactions.csv`, `qc_unused_entities.csv`, `qc_growth_blockers.csv` | `qcModelChecks.py` | **PR #1107** (model QC checks) |
| `qc_annotation_issues.csv` | `annotationTest.py` | **PR #1107** (model QC checks) |
| `qc_status.tsv` (round-trip, YAML lint, metabolic tasks, growth) | `testYamlConversion.py`, `testMetabolicTasks.py`, `action-yamllint`, `qcModelChecks.py` (via `qcStatus.py`) | **PR #1107** (model QC checks) |
| `macaw_results.tsv`, `balance_results.csv`, `qc_structure_consistency.csv` | `macawTests.py`, `balanceTest.py`, `structureConsistencyTest.py` | **PR #1107** (MACAW and balance) |
| `memote_score.md` | `memoteSnapshot.py` (fast subset every PR; full suite via `/run memote`) | **PR #1107** (MEMOTE) |
| `gene-essential.csv`, `gene-essential_summary.md` | `gradedEssentiality.py` via `/run gene-essentiality` | **PR #1107** (gene essentiality) |

## 2. What each check means

Expand Down
3 changes: 0 additions & 3 deletions data/testResults/balance_results.csv
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,6 @@ MAR10036,acyl-CoA pool formation and breakdown,C:16.9524;H:31.9518;R:-1,
MAR10037,cholesterol-ester pool formation and breakdown,C:16.9524;H:31.9518;R:-1,
MAR10038,cholesterol-ester pool formation and breakdown,C:16.9524;H:31.9518;R:-1,
MAR10061,fatty acyl-CoA reduction,C:-1;H:-2,
MAR12991,3HPVSCOAhc,,-1
MAR12992,3HPVSTEThc,,1
MAR12994,FVSCOAhc,,-1
MAR12995,MDZGLChr,,-1
MAR13078,PROTEIN_BS,C:-32.5694;H:-66.0418;N:-9.3852;O:-16.5863;S:-0.283;X:1,-0.202
MAR13081,CYOOm3i,,0.06
Loading