Skip to content

Commit 13010c8

Browse files
sbryngelsonclaude
andcommitted
Refactor doc annotations to be data-driven from definitions.py
Move hard-coded annotation dicts (BC, patch_bc, simplex, fluid_pp, tag labels, prefix labels) from docs_gen.py into definitions.py as HINTS, TAG_DISPLAY_NAMES, and PREFIX_HINTS. Add `hint` field to ParamDef and auto-populate it at registration time via _lookup_hint(), so new params get documented without editing the doc generator. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a80bb8a commit 13010c8

File tree

3 files changed

+116
-118
lines changed

3 files changed

+116
-118
lines changed

toolchain/mfc/params/definitions.py

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,108 @@ def _auto_describe(name: str) -> str:
346346
}
347347

348348

349+
# =============================================================================
350+
# Data-driven Annotations for Doc Generation
351+
# =============================================================================
352+
# These dicts are the single source of truth for parameter hints in the docs.
353+
# To annotate a new param, add an entry here instead of editing docs_gen.py.
354+
355+
HINTS = {
356+
"bc": {
357+
"grcbc_in": "Enables GRCBC subsonic inflow (bc type -7)",
358+
"grcbc_out": "Enables GRCBC subsonic outflow (bc type -8)",
359+
"grcbc_vel_out": "GRCBC velocity outlet (requires `grcbc_out`)",
360+
"vel_in": "Inlet velocity component (used with `grcbc_in`)",
361+
"vel_out": "Outlet velocity component (used with `grcbc_vel_out`)",
362+
"pres_in": "Inlet pressure (used with `grcbc_in`)",
363+
"pres_out": "Outlet pressure (used with `grcbc_out`)",
364+
"alpha_rho_in": "Inlet partial density per fluid (used with `grcbc_in`)",
365+
"alpha_in": "Inlet volume fraction per fluid (used with `grcbc_in`)",
366+
"vb1": "Boundary velocity component 1 at domain begin",
367+
"vb2": "Boundary velocity component 2 at domain begin",
368+
"vb3": "Boundary velocity component 3 at domain begin",
369+
"ve1": "Boundary velocity component 1 at domain end",
370+
"ve2": "Boundary velocity component 2 at domain end",
371+
"ve3": "Boundary velocity component 3 at domain end",
372+
},
373+
"patch_bc": {
374+
"geometry": "Patch shape: 1=line, 2=circle, 3=rectangle",
375+
"type": "BC type applied within patch region",
376+
"dir": "Patch normal direction (1=x, 2=y, 3=z)",
377+
"loc": "Domain boundary (-1=begin, 1=end)",
378+
"centroid": "Patch center coordinate",
379+
"length": "Patch dimension",
380+
"radius": "Patch radius (geometry=2)",
381+
},
382+
"simplex_params": {
383+
"perturb_dens": "Enable simplex density perturbation",
384+
"perturb_dens_freq": "Density perturbation frequency",
385+
"perturb_dens_scale": "Density perturbation amplitude",
386+
"perturb_dens_offset": "Density perturbation offset seed",
387+
"perturb_vel": "Enable simplex velocity perturbation",
388+
"perturb_vel_freq": "Velocity perturbation frequency",
389+
"perturb_vel_scale": "Velocity perturbation amplitude",
390+
"perturb_vel_offset": "Velocity perturbation offset seed",
391+
},
392+
"fluid_pp": {
393+
"gamma": "Specific heat ratio (EOS)",
394+
"pi_inf": "Stiffness pressure (EOS)",
395+
"cv": "Specific heat at constant volume",
396+
"qv": "Heat of formation",
397+
"qvp": "Heat of formation derivative",
398+
},
399+
}
400+
401+
# Tag → display name for docs. Dict order = priority when a param has multiple tags.
402+
TAG_DISPLAY_NAMES = {
403+
"bubbles": "Bubble model",
404+
"mhd": "MHD",
405+
"chemistry": "Chemistry",
406+
"time": "Time-stepping",
407+
"grid": "Grid",
408+
"weno": "WENO",
409+
"viscosity": "Viscosity",
410+
"elasticity": "Elasticity",
411+
"surface_tension": "Surface tension",
412+
"acoustic": "Acoustic",
413+
"ib": "Immersed boundary",
414+
"probes": "Probe/integral",
415+
"riemann": "Riemann solver",
416+
"relativity": "Relativity",
417+
"output": "Output",
418+
"bc": "Boundary condition",
419+
}
420+
421+
# Prefix → hint for untagged simple params
422+
PREFIX_HINTS = {
423+
"mixlayer_": "Mixing layer parameter",
424+
"nv_uvm_": "GPU memory management",
425+
"ic_": "Initial condition parameter",
426+
}
427+
428+
429+
def _lookup_hint(name):
430+
"""Auto-derive constraint hint from HINTS dict using family+attribute matching."""
431+
if '%' not in name:
432+
# Check PREFIX_HINTS for simple params
433+
for prefix, label in PREFIX_HINTS.items():
434+
if name.startswith(prefix):
435+
return label
436+
return ""
437+
# Compound name: extract family and attribute
438+
prefix, attr_full = name.split('%', 1)
439+
# Normalize family: "bc_x" → "bc", "patch_bc(1)" → "patch_bc"
440+
family = re.sub(r'[_(].*', '', prefix) # "bc_x" → "bc", "patch_bc" stays
441+
if family not in HINTS:
442+
# Try with underscore-joined prefix: "simplex_params" stays
443+
family = re.match(r'^[a-zA-Z_]+', prefix).group(0)
444+
if family not in HINTS:
445+
return ""
446+
# Strip index from attr: "vel_in(1)" → "vel_in"
447+
attr = re.match(r'^[a-zA-Z_0-9]+', attr_full).group(0)
448+
return HINTS[family].get(attr, "")
449+
450+
349451
# ============================================================================
350452
# Schema Validation for Constraints and Dependencies
351453
# ============================================================================
@@ -707,8 +809,10 @@ def get_value_label(param_name: str, value: int) -> str:
707809
},
708810
}
709811

710-
def _r(name, ptype, tags=None, desc=None):
812+
def _r(name, ptype, tags=None, desc=None, hint=None):
711813
"""Register a parameter with optional feature tags and description."""
814+
if hint is None:
815+
hint = _lookup_hint(name)
712816
description = desc if desc else _auto_describe(name)
713817
constraint = CONSTRAINTS.get(name)
714818
if constraint and "value_labels" in constraint:
@@ -723,6 +827,7 @@ def _r(name, ptype, tags=None, desc=None):
723827
constraints=constraint,
724828
dependencies=DEPENDENCIES.get(name),
725829
tags=tags if tags else set(),
830+
hint=hint,
726831
))
727832

728833

toolchain/mfc/params/generators/docs_gen.py

Lines changed: 8 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -215,109 +215,6 @@ def _get_reverse_deps():
215215
return _REVERSE_DEPS
216216

217217

218-
# Feature tag → human-readable label, in priority order
219-
_TAG_LABELS = [
220-
("bubbles", "Bubble model parameter"),
221-
("mhd", "MHD parameter"),
222-
("chemistry", "Chemistry parameter"),
223-
("time", "Time-stepping parameter"),
224-
("grid", "Grid parameter"),
225-
("weno", "WENO parameter"),
226-
("viscosity", "Viscosity parameter"),
227-
("elasticity", "Elasticity parameter"),
228-
("surface_tension", "Surface tension parameter"),
229-
("acoustic", "Acoustic parameter"),
230-
("ib", "Immersed boundary parameter"),
231-
("probes", "Probe/integral parameter"),
232-
("riemann", "Riemann solver parameter"),
233-
("relativity", "Relativity parameter"),
234-
("output", "Output parameter"),
235-
]
236-
237-
# Prefix → label for untagged params
238-
_PREFIX_LABELS = [
239-
("mixlayer_", "Mixing layer parameter"),
240-
("nv_uvm_", "GPU memory management"),
241-
("ic_", "Initial condition parameter"),
242-
]
243-
244-
# BC sub-parameter attribute → usage annotation
245-
# Keyed by the attribute name after % (without index suffix)
246-
_BC_ATTR_ANNOTATIONS = {
247-
"grcbc_in": "Enables GRCBC subsonic inflow (bc type -7)",
248-
"grcbc_out": "Enables GRCBC subsonic outflow (bc type -8)",
249-
"grcbc_vel_out": "GRCBC velocity outlet (requires `grcbc_out`)",
250-
"vel_in": "Inlet velocity component (used with `grcbc_in`)",
251-
"vel_out": "Outlet velocity component (used with `grcbc_vel_out`)",
252-
"pres_in": "Inlet pressure (used with `grcbc_in`)",
253-
"pres_out": "Outlet pressure (used with `grcbc_out`)",
254-
"alpha_rho_in": "Inlet partial density per fluid (used with `grcbc_in`)",
255-
"alpha_in": "Inlet volume fraction per fluid (used with `grcbc_in`)",
256-
"vb1": "Boundary velocity component 1 at domain begin",
257-
"vb2": "Boundary velocity component 2 at domain begin",
258-
"vb3": "Boundary velocity component 3 at domain begin",
259-
"ve1": "Boundary velocity component 1 at domain end",
260-
"ve2": "Boundary velocity component 2 at domain end",
261-
"ve3": "Boundary velocity component 3 at domain end",
262-
}
263-
264-
# patch_bc attribute → usage annotation
265-
_PATCH_BC_ANNOTATIONS = {
266-
"geometry": "Patch shape: 1=line, 2=circle, 3=rectangle",
267-
"type": "BC type applied within patch region",
268-
"dir": "Patch normal direction (1=x, 2=y, 3=z)",
269-
"loc": "Domain boundary (-1=begin, 1=end)",
270-
"centroid": "Patch center coordinate",
271-
"length": "Patch dimension",
272-
"radius": "Patch radius (geometry=2)",
273-
}
274-
275-
# simplex_params attribute → usage annotation
276-
_SIMPLEX_ANNOTATIONS = {
277-
"perturb_dens": "Enable simplex density perturbation",
278-
"perturb_dens_freq": "Density perturbation frequency",
279-
"perturb_dens_scale": "Density perturbation amplitude",
280-
"perturb_dens_offset": "Density perturbation offset seed",
281-
"perturb_vel": "Enable simplex velocity perturbation",
282-
"perturb_vel_freq": "Velocity perturbation frequency",
283-
"perturb_vel_scale": "Velocity perturbation amplitude",
284-
"perturb_vel_offset": "Velocity perturbation offset seed",
285-
}
286-
287-
# fluid_pp attribute → usage annotation (EOS params only)
288-
_FLUID_PP_ANNOTATIONS = {
289-
"gamma": "Specific heat ratio (EOS)",
290-
"pi_inf": "Stiffness pressure (EOS)",
291-
"cv": "Specific heat at constant volume",
292-
"qv": "Heat of formation",
293-
"qvp": "Heat of formation derivative",
294-
}
295-
296-
297-
def _get_attr_annotation(param_name: str) -> str:
298-
"""Look up annotation for compound param names (e.g. bc_x%vel_in(1) → 'Inlet velocity')."""
299-
if '%' not in param_name:
300-
return ""
301-
# Extract attribute after last %: "bc_x%vel_in(1)" → "vel_in(1)"
302-
attr_full = param_name.split('%')[-1]
303-
# Strip index suffix: "vel_in(1)" → "vel_in", "centroid(2)" → "centroid"
304-
attr_base = re.match(r'^([a-zA-Z_0-9]+)', attr_full)
305-
if not attr_base:
306-
return ""
307-
attr_key = attr_base.group(1)
308-
# Determine family prefix: "bc_x%..." → "bc_", "patch_bc(1)%..." → "patch_bc"
309-
prefix = param_name.split('%')[0]
310-
if re.match(r'bc_[xyz]', prefix):
311-
return _BC_ATTR_ANNOTATIONS.get(attr_key, "")
312-
if prefix.startswith("patch_bc"):
313-
return _PATCH_BC_ANNOTATIONS.get(attr_key, "")
314-
if prefix.startswith("simplex_params"):
315-
return _SIMPLEX_ANNOTATIONS.get(attr_key, "")
316-
if prefix.startswith("fluid_pp"):
317-
return _FLUID_PP_ANNOTATIONS.get(attr_key, "")
318-
return ""
319-
320-
321218
def _format_tag_annotation(param_name: str, param) -> str: # pylint: disable=too-many-locals
322219
"""
323220
Return a short annotation for params with no schema constraints and no AST rules.
@@ -360,20 +257,15 @@ def _format_tag_annotation(param_name: str, param) -> str: # pylint: disable=to
360257
else f"Recommended for `{source}`")
361258
return "; ".join(parts)
362259

363-
# 4. Feature tag labels (broader tag-based annotation)
364-
for tag, label in _TAG_LABELS:
365-
if tag in param.tags:
366-
return label
367-
368-
# 5. Prefix group labels (for untagged params with common prefixes)
369-
for prefix, label in _PREFIX_LABELS:
370-
if param_name.startswith(prefix):
371-
return label
260+
# 4. ParamDef hint (data-driven from definitions.py)
261+
if param.hint:
262+
return param.hint
372263

373-
# 6. Compound-name attribute annotations (bc_x%vel_in, patch_bc%geometry, etc.)
374-
attr_ann = _get_attr_annotation(param_name)
375-
if attr_ann:
376-
return attr_ann
264+
# 5. Tag-based label (from TAG_DISPLAY_NAMES in definitions.py)
265+
from ..definitions import TAG_DISPLAY_NAMES # pylint: disable=import-outside-toplevel
266+
for tag, display_name in TAG_DISPLAY_NAMES.items():
267+
if tag in param.tags:
268+
return f"{display_name} parameter"
377269

378270
return ""
379271

toolchain/mfc/params/schema.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def json_schema(self) -> Dict[str, Any]:
4040

4141

4242
@dataclass
43-
class ParamDef:
43+
class ParamDef: # pylint: disable=too-many-instance-attributes
4444
"""
4545
Definition of a single MFC parameter.
4646
@@ -60,6 +60,7 @@ class ParamDef:
6060
constraints: Optional[Dict[str, Any]] = None # {"choices": [...], "min": N, "max": N}
6161
dependencies: Optional[Dict[str, Any]] = None # {"requires": [...], "recommends": [...]}
6262
tags: Set[str] = field(default_factory=set) # Feature tags: "mhd", "bubbles", etc.
63+
hint: str = "" # Constraint/usage hint for docs (e.g. "Used with grcbc_in")
6364

6465
def __post_init__(self):
6566
# Validate name

0 commit comments

Comments
 (0)