Advanced case grouping¶
The common path covers most layouts with
name=, key=, and shorthand roles ("mesh", required(...), optional(...)).
Use this page when you need finer control over case identity, membership, or
admission rules.
Import advanced authoring types from miura.nexus.case_grouping.advanced.
API reference: Case grouping (advanced).
When this page applies¶
| You need… | Parameter / type | Why |
|---|---|---|
| Case identity with a platform semantic id or unit different from the path key | coordinates= + CaseCoordinate, and primary_key= |
Downstream selection and CAP identity should use a stable semantic id (and optionally units), not only the path placeholder name |
| Multi-axis identity (e.g. geometry + angle of attack) | coordinates= / primary_key= listing each axis |
One case is uniquely identified by several dimensions together |
| Membership role name different from the resource name | Full MemberRole |
Resource keys stay file-oriented; role names stay how the case uses the file |
| A content selector or shareability on a role | Full MemberRole (plus selectors such as CsvRowSelector) |
Shorthand roles only bind name to resource; selectors pick rows or shared members |
| An admission rule that lists exactly which roles must be present | composition= + CompositionRule |
You decide which roles are mandatory for a valid case when mixing helpers and full roles |
If none of these apply, stay on
explicit grouping controls /
content-linked cases. Path-shaped
multi-root layouts with shareability or Folder(...) resources can also use
CaseStructure.compose; content
selectors and joins stay on CaseGrouping.content_join.
Explicit coordinates and composition¶
Use case: path key is case_id, but admitted cases should carry a stable
semantic id (openfoam_case_id) for later selection.
| Parameter | Role in this example |
|---|---|
name= |
Spec id for this grouping (versioned label you pass to plan / CaseSet) |
resources= |
Path templates and components that locate member files |
coordinates= |
Declares each identity axis: path component name, semantic id, value kind |
primary_key= |
Which coordinate names form the case key |
roles= |
Full MemberRoles: role name, resource_ref, join axis, cardinality |
composition= |
Which roles must all be present for a case to admit |
from miura.nexus.case_grouping import CaseGrouping, MemberRole
from miura.nexus.case_grouping.advanced import CaseCoordinate, CompositionRule
from miura.sdk.resources import ResourceMap
from miura.nexus.collection.structured_schema import Cardinality, File, Number, Ref
case_id = Ref("case_id")
resources = ResourceMap(
components={"case_id": Number(min_digits=6, max_digits=6)},
resources={
"control_dict": File("case_" + case_id + "/system/controlDict"),
"velocity": File("case_" + case_id + "/0/U"),
"pressure": File("case_" + case_id + "/0/p"),
},
)
case_grouping = CaseGrouping.role_based(
name="openfoam_case_roles_v1",
resources=resources,
coordinates=[CaseCoordinate("case_id", "openfoam_case_id", "string")],
primary_key=["case_id"],
roles=[
MemberRole("control_dict", "control_dict", "case_id", Cardinality.exactly(1)),
MemberRole("velocity", "velocity", "case_id", Cardinality.exactly(1)),
MemberRole("pressure", "pressure", "case_id", Cardinality.exactly(1)),
],
composition=CompositionRule.require_all(
["control_dict", "velocity", "pressure"]
),
)
Full MemberRole in a mixed list¶
Use case: most roles match resource names, but one resource must appear under a different membership role (or carry a selector). You still want a clear rule for which roles make a complete case.
| Parameter | Role in this example |
|---|---|
key= |
Shared join axis when you are not spelling out coordinates= |
roles= |
Mix of shorthand ("control_dict", one_or_more(...)) and full MemberRole |
composition= |
Lists every role that must be present — including the explicit MemberRole |
from miura.nexus.case_grouping import CaseGrouping, MemberRole, one_or_more, optional
from miura.nexus.case_grouping.advanced import CompositionRule
from miura.sdk.resources import ResourceMap
from miura.nexus.collection.structured_schema import Cardinality, File, Number, Ref
case_id = Ref("case_id")
resources = ResourceMap(
components={"case_id": Number(min_digits=6, max_digits=6)},
resources={
"control_dict": File("case_" + case_id + "/system/controlDict"),
"velocity": File("case_" + case_id + "/0/U"),
"pressure": File("case_" + case_id + "/0/p"),
"force_coeffs": File("case_" + case_id + "/forces.csv"),
},
)
case_grouping = CaseGrouping.role_based(
name="mixed_roles_v1",
resources=resources,
key="case_id",
roles=[
"control_dict",
one_or_more("velocity"),
optional("pressure"),
MemberRole(
name="forces",
resource_ref="force_coeffs",
join_on="case_id",
cardinality=Cardinality.exactly(1),
),
],
composition=CompositionRule.require_all(
["control_dict", "velocity", "forces"]
),
)
Content join with explicit roles¶
Use case: same CSV join as the content-linked cases path, but case identity or membership needs the same controls as above (semantic coordinates, renamed roles, or a row selector).
| Parameter | Role in this example |
|---|---|
name= |
Spec id for this content-join grouping |
coordinates= |
Identity axis for the join key (semantic id / kind) |
join_key= |
Column / axis that links members into one case |
evidence= |
How to read the join key from content (here a CSV column) |
roles= |
Full MemberRoles for mesh and parameters |
composition= |
Both roles required for a valid design case |
from miura.nexus.case_grouping import CaseGrouping, MemberRole
from miura.nexus.case_grouping.advanced import CaseCoordinate, CompositionRule, CsvRowSelector
from miura.sdk.resources import ResourceMap
from miura.nexus.collection.structured_schema import AnyString, Cardinality, File, Ref
design_id = Ref("design_id")
resources = ResourceMap(
components={"design_id": AnyString()},
resources={
"mesh": File("meshes/" + design_id + ".stl"),
"parameters": File("tables/design_params.csv"),
},
)
case_grouping = CaseGrouping.content_join(
name="design_csv_join_v1",
resources=resources,
coordinates=[CaseCoordinate("design_id", "design_id", "string")],
join_key="design_id",
evidence=[
CsvRowSelector(resource_ref="parameters", key_column="design_id"),
],
roles=[
MemberRole("mesh", "mesh", "design_id", Cardinality.exactly(1)),
MemberRole("parameters", "parameters", "design_id", Cardinality.exactly(1)),
],
composition=CompositionRule.require_all(["mesh", "parameters"]),
)