From 718ef21fb2bfb9ae20cc460622190fdffabf2e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAnaPcode=E2=80=9D?= <“anastasiapupo@gmail.com”> Date: Sat, 8 Aug 2026 16:12:26 -0700 Subject: [PATCH 1/4] Hoist level emoji map to LEVEL_EMOJI constant Was duplicated in render_playbook_card (line 159) and generate_playbook (line 267). Moved to a LEVEL_EMOJI constant, placed after PlaybookEntry, and pointed both call sites at it. Part of #1512 cleanup of tooling file (c) --- toolchain/mfc/gen_case_constraints_docs.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/toolchain/mfc/gen_case_constraints_docs.py b/toolchain/mfc/gen_case_constraints_docs.py index 2c7303878..b4c21f721 100644 --- a/toolchain/mfc/gen_case_constraints_docs.py +++ b/toolchain/mfc/gen_case_constraints_docs.py @@ -50,6 +50,9 @@ class PlaybookEntry: tags: List[str] +LEVEL_EMOJI = {"Beginner": "🟢", "Intermediate": "🟡", "Advanced": "🔴"} + + # Curated list of hero examples PLAYBOOK_EXAMPLES = [ PlaybookEntry( @@ -156,7 +159,7 @@ def render_playbook_card(entry: PlaybookEntry, summary: Dict[str, Any]) -> str: lines = [] tags_str = " · ".join(entry.tags) - level_emoji = {"Beginner": "🟢", "Intermediate": "🟡", "Advanced": "🔴"}.get(entry.level, "") + level_emoji = LEVEL_EMOJI.get(entry.level, "") lines.append("
") lines.append(f"{entry.title} {level_emoji} {entry.level} · {entry.case_dir}\n") @@ -264,7 +267,7 @@ def generate_playbook() -> str: if not level_entries: continue - level_emoji = {"Beginner": "🟢", "Intermediate": "🟡", "Advanced": "🔴"}.get(level, "") + level_emoji = LEVEL_EMOJI.get(level, "") lines.append(f"\n### {level_emoji} {level} Examples\n") for entry in level_entries: From 212f2de1b68d980f0c029bf2795ba19bb52f769d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAnaPcode=E2=80=9D?= <“anastasiapupo@gmail.com”> Date: Sat, 8 Aug 2026 17:12:42 -0700 Subject: [PATCH 2/4] Collapse schema-name getters into _named helper get_model_name, get_riemann_solver_name, and get_time_stepper_name (lines 133-151) had byte-identical bodies modulo the schema key string. Replaced all three with a single _named(param, value) helper and updated the three call sites: line 170 (model_eqns), line 222 (riemann_solver), and line 226 (time_stepper). Part of issue 1512 cleanup of tooling file (c) --- toolchain/mfc/gen_case_constraints_docs.py | 28 ++++++---------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/toolchain/mfc/gen_case_constraints_docs.py b/toolchain/mfc/gen_case_constraints_docs.py index b4c21f721..1ab7151f1 100644 --- a/toolchain/mfc/gen_case_constraints_docs.py +++ b/toolchain/mfc/gen_case_constraints_docs.py @@ -133,25 +133,11 @@ def summarize_case_params(params: Dict[str, Any]) -> Dict[str, Any]: } -def get_model_name(model_eqns: int | None) -> str: - """Get human-friendly model name from schema.""" - if model_eqns is None: +def _named(param: str, value: int | None) -> str: + """Get the name from a schema (i.e. model name, Riemann solver name, time stepper name).""" + if value is None: return "Not specified" - return get_value_label("model_eqns", model_eqns) or "Not specified" - - -def get_riemann_solver_name(solver: int | None) -> str: - """Get Riemann solver name from schema.""" - if solver is None: - return "Not specified" - return get_value_label("riemann_solver", solver) or "Not specified" - - -def get_time_stepper_name(stepper: int | None) -> str: - """Get time stepper name from schema.""" - if stepper is None: - return "Not specified" - return get_value_label("time_stepper", stepper) or "Not specified" + return get_value_label(param, value) or "Not specified" def render_playbook_card(entry: PlaybookEntry, summary: Dict[str, Any]) -> str: @@ -167,7 +153,7 @@ def render_playbook_card(entry: PlaybookEntry, summary: Dict[str, Any]) -> str: lines.append(f"**Tags:** {tags_str}\n") lines.append("**Physics Configuration:**\n") - lines.append(f"- **Model:** {get_model_name(summary['model_eqns'])} (`model_eqns = {summary['model_eqns']}`)") + lines.append(f"- **Model:** {_named('model_eqns', summary['model_eqns'])} (`model_eqns = {summary['model_eqns']}`)") if summary["num_fluids"] is not None: lines.append(f"- **Number of fluids:** {summary['num_fluids']}") @@ -219,11 +205,11 @@ def render_playbook_card(entry: PlaybookEntry, summary: Dict[str, Any]) -> str: lines.append(f"- **Reconstruction:** MUSCL (order {summary['muscl_order']})") if summary["riemann_solver"]: - solver_name = get_riemann_solver_name(summary["riemann_solver"]) + solver_name = _named("riemann_solver", summary["riemann_solver"]) lines.append(f"- **Riemann solver:** {solver_name} (`riemann_solver = {summary['riemann_solver']}`)") if summary["time_stepper"]: - stepper_name = get_time_stepper_name(summary["time_stepper"]) + stepper_name = _named("time_stepper", summary["time_stepper"]) lines.append(f"- **Time stepping:** {stepper_name}") # Links From 1d5406eec4e750d75a6c7198fc8460a8b044eeb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAnaPcode=E2=80=9D?= <“anastasiapupo@gmail.com”> Date: Sun, 9 Aug 2026 12:58:17 -0700 Subject: [PATCH 3/4] Read threshold seconds from HEADLESS_THRESHOLDS The seconds were hardcoded at each comparison in notify_long_running_threads, while only the message text indexed the HEADLESS_THRESHOLDS table. Read the seconds from this table too, so they live in one place. Part of issue 1512 cleanup of tooling file (d) --- toolchain/mfc/sched.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolchain/mfc/sched.py b/toolchain/mfc/sched.py index c7158bbbd..8e7b186d2 100644 --- a/toolchain/mfc/sched.py +++ b/toolchain/mfc/sched.py @@ -140,17 +140,17 @@ def notify_long_running_threads(progress: rich.progress.Progress, running_tracke # headless: milestone notifications at 2, 10, 30 minutes else: # 2 minutes - if (not holder.notified_2m) and elapsed >= 2 * 60: + if (not holder.notified_2m) and elapsed >= HEADLESS_THRESHOLDS[0][0]: cons.print(f" {HEADLESS_THRESHOLDS[0][1]} [bold magenta]{case_uuid}[/bold magenta] {case_trace}") holder.notified_2m = True # 10 minutes - if (not holder.notified_10m) and elapsed >= 10 * 60: + if (not holder.notified_10m) and elapsed >= HEADLESS_THRESHOLDS[1][0]: cons.print(f" {HEADLESS_THRESHOLDS[1][1]} [bold magenta]{case_uuid}[/bold magenta] {case_trace}") holder.notified_10m = True # 30 minutes - if (not holder.notified_30m) and elapsed >= 30 * 60: + if (not holder.notified_30m) and elapsed >= HEADLESS_THRESHOLDS[2][0]: cons.print(f" {HEADLESS_THRESHOLDS[2][1]} [bold magenta]{case_uuid}[/bold magenta] {case_trace}") holder.notified_30m = True From 065e86f28280e13c90dc05e2e519541f1be84269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CAnaPcode=E2=80=9D?= <“anastasiapupo@gmail.com”> Date: Sun, 9 Aug 2026 15:34:10 -0700 Subject: [PATCH 4/4] Delete ORG_COLORS and inline "yellow" All 8 entries in ORG_COLORS mapped to "yellow" and the lookup defaulted to "yellow", so every org rendered yellow regardless. Deleted the dictionary and inlined yellow. Part of issue 1512 cleanup of tooling file (e) --- toolchain/mfc/user_guide.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/toolchain/mfc/user_guide.py b/toolchain/mfc/user_guide.py index 6dd608bc8..dd701ec00 100644 --- a/toolchain/mfc/user_guide.py +++ b/toolchain/mfc/user_guide.py @@ -51,18 +51,8 @@ "h": "HiPerGator", # Proper capitalization } -# Display order and colors for organizations +# Display order for organizations ORG_ORDER = ["ORNL", "LLNL", "ACCESS", "Georgia Tech", "Caltech", "Brown", "DoD", "Florida", "CSCS"] -ORG_COLORS = { - "ORNL": "yellow", - "LLNL": "yellow", - "ACCESS": "yellow", - "Georgia Tech": "yellow", - "Caltech": "yellow", - "Brown": "yellow", - "DoD": "yellow", - "Florida": "yellow", -} def _parse_modules_file(): @@ -142,8 +132,7 @@ def _generate_clusters_content(): continue # Format: " [yellow]ORG:[/yellow] [cyan]slug[/cyan]=Name [cyan]slug2[/cyan]=Name2" entries = [f"[cyan]{slug}[/cyan]={_get_cluster_short_name(slug, name)}" for slug, name in org_clusters[org]] - color = ORG_COLORS.get(org, "yellow") - cluster_lines.append(f" [{color}]{org}:[/{color}] " + " ".join(entries)) + cluster_lines.append(f" [yellow]{org}:[/yellow] " + " ".join(entries)) # Handle "Other" if any if org_clusters.get("Other"):