From cf9d010c6a9fa2d78ccc1157ace72883065de790 Mon Sep 17 00:00:00 2001 From: Doga Gursoy Date: Sun, 21 Jun 2026 22:35:02 +0300 Subject: [PATCH 1/2] docs: flatten facilities nav and generate the asset binding from the site descriptor The facility surface had one hand-authored page left: per-site assets.md. Everything it carried (the beamline root-Asset binding, tier, facility_code) is already in the site descriptor, so fold it into the generated index page and delete the hand-authored files. This makes the whole facility surface descriptor-generated from site.yaml, and lets the nav drop a level: the "Facility envelope" group becomes a flat "Facilities" with APS and MAX IV as single leaves instead of each owning an Assets sub-page. deployments/index.md retires the "facility envelope" framing for plain "facilities" and drops the scope-levels table now that each facility page carries its own Asset binding inline. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../unit/deployments/test_site_descriptor.py | 5 ++++ docs/deployments/aps/assets.md | 11 -------- docs/deployments/index.md | 24 +++++------------ docs/deployments/maxiv/assets.md | 13 --------- mkdocs.yml | 10 +++---- scripts/site_pages.py | 27 ++++++++++++++----- 6 files changed, 35 insertions(+), 55 deletions(-) delete mode 100644 docs/deployments/aps/assets.md delete mode 100644 docs/deployments/maxiv/assets.md diff --git a/apps/api/tests/unit/deployments/test_site_descriptor.py b/apps/api/tests/unit/deployments/test_site_descriptor.py index d34d8e1082..a1fd4fa7ea 100644 --- a/apps/api/tests/unit/deployments/test_site_descriptor.py +++ b/apps/api/tests/unit/deployments/test_site_descriptor.py @@ -202,6 +202,11 @@ def test_renders_single_site_narrative() -> None: assert "beam-flux transients" in page # cautions assert "Institution" in page and "Argonne" in page # facility -> institution (context) assert "../argonne/index.md" not in page # institution is context, not a navigable deployment + # the Asset binding is dissolved into this page, not a separate Assets sub-page + assert "## How APS is modeled" in page + assert "../2-bm/index.md" in page # beamline root Asset binding, folded in + assert "`Unit`" in page # asset tier column rendered inline + assert "assets.md" not in page # no link-out to a hand-authored Assets page def test_practice_method_links_only_known() -> None: diff --git a/docs/deployments/aps/assets.md b/docs/deployments/aps/assets.md deleted file mode 100644 index f722f6a8d2..0000000000 --- a/docs/deployments/aps/assets.md +++ /dev/null @@ -1,11 +0,0 @@ -# Assets - -*Equipment BC Assets bound to the APS Site.* - -APS itself is not an Asset: it is a Federation `Facility` with `FacilityKind = Site` (`FacilityCode = "aps"`), declared on the [APS index](index.md). Sectors are facility-envelope scope, an organizational grouping rather than Asset rows; if modeled they are a `Facility` with `FacilityKind = Area` under the Site. In the pilot, beamlines are root Assets (`tier = Unit`, `parent_id = None`) that bind the Site directly via `facility_code`. See [Model](../../architecture/model.md) for the aggregate shape. - -| Asset | Tier | facility_code | Hosts | -| --- | --- | --- | --- | -| `2-BM` | `Unit` | `aps` | [2-BM](../2-bm/index.md) | - -Sub-systems and devices nested under a beamline are Assets with `tier = Component` or `tier = Device`, linked via `parent_id`. Being non-root, they do not carry `facility_code`; they inherit facility scope through the `parent_id` tree. diff --git a/docs/deployments/index.md b/docs/deployments/index.md index b3273abe67..23591797b5 100644 --- a/docs/deployments/index.md +++ b/docs/deployments/index.md @@ -4,33 +4,23 @@ A deployment is a beamline pilot: one instrument where the recipe ladder, BCs, and trust boundaries meet real users. Vertical before horizontal. CORA's domain model only contains what at least one real deployment forced into it; until a beamline demands a shape, the shape stays out. -CORA's operational pilot today is 2-BM, a bending-magnet micro-CT beamline at APS. A second deployment, TomoWise at MAX IV, is in the design phase: its beamline is modelled from the Technical Design Report ahead of construction, so its pages describe an intended shape, not a running instrument. These pages are framed from the beamline outward: the beamline first, then the site it runs at. +CORA's operational pilot today is 2-BM, a bending-magnet micro-CT beamline at APS. A second deployment, TomoWise at MAX IV, is in the design phase: its beamline is modelled from the Technical Design Report ahead of construction, so its pages describe an intended shape, not a running instrument. These pages are framed from the beamline outward: the beamline first, then the facility it runs at. | Beamline | Site | Status | | --- | --- | --- | | [2-BM](2-bm/index.md) | [APS](aps/index.md), Argonne | Pilot | | [TomoWise](tomowise/index.md) | [MAX IV](maxiv/index.md), Lund | In design | -## The facility envelope +## The facilities -A beamline is never standalone: it sits inside a facility envelope, the Site that operates it and the institution above that. That context is what a beamline points up into for its clearances, principals, practices, and facility-scope supplies. The envelope is not a separate deployment in its own right, so it lives here as context for the beamline rather than as a peer entry above. +A beamline is never standalone: it sits inside a facility, the Site that operates it and the institution above that. The facility is what a beamline points up into for the clearances, principals, practices, and facility-scope supplies it inherits but does not own. CORA carries one page per Site, [APS](aps/index.md) and [MAX IV](maxiv/index.md), and each beamline links up to its own rather than restating it. -CORA models the three scope levels with three different mechanisms. Facility-envelope scope (institution, site, area) is owned by the Federation `Facility` aggregate, whose `FacilityKind` is `{Site, Area}`. Equipment scope is owned by the `Asset` aggregate, whose `tier` is the closed `AssetTier` StrEnum `{Unit, Component, Device}` (ISA-88 equipment tiers). A root Asset binds its owning Facility through `facility_code`; nested Assets inherit that scope through `parent_id`. +Facility scope and equipment scope are two different aggregates. A Site, and a sector or hutch grouping below it, is a Federation `Facility`, whose `FacilityKind` is `{Site, Area}`. A beamline and the sub-systems under it are Equipment `Asset` rows, whose `tier` is the closed `AssetTier` StrEnum `{Unit, Component, Device}` (ISA-88 equipment tiers). A beamline is a root Asset bound to its Site through `facility_code`; its sub-systems inherit that scope through `parent_id`. Each facility page carries that binding for the Site it describes. -| Scope level | Example | Model | -| --- | --- | --- | -| Institution | Argonne; Lund University | Context, not a registered row | -| Site | [APS](aps/index.md); [MAX IV](maxiv/index.md) | Federation `Facility`, `FacilityKind = Site` (`facility_code = "aps"` / `"maxiv"`) | -| Beamline | [2-BM](2-bm/index.md) at APS; [TomoWise](tomowise/index.md) at MAX IV | Equipment `Asset`, root, `tier = Unit`, bound by `facility_code` | - -## The sites they run at +[**APS**](aps/index.md), the Advanced Photon Source, operated by Argonne National Laboratory, is the synchrotron site 2-BM runs at. Its page is the home for the facts a 2-BM experiment inherits but does not own: the Practices (ISA-88 Site Recipes) it runs, the Clearances it must hold, the facility Supplies it draws on, and the people and agents registered facility-wide. -[**APS**](aps/index.md), the Advanced Photon Source, is the synchrotron site 2-BM runs at, operated by Argonne National Laboratory. It is a Federation `Facility` with `FacilityKind = Site` (`facility_code = "aps"`). The APS page is the home for facts the beamline inherits but does not own: the Practices (ISA-88 Site Recipes) it runs, the Clearances it must hold, the facility Supplies it draws on, and the people and agents registered facility-wide. The 2-BM page links up to these rather than restating them. +[**MAX IV**](maxiv/index.md), in Lund, Sweden, is the synchrotron site the planned TomoWise beamline will run at, the second Site CORA models. Its page is thin while TomoWise is in design: most facility facts (safety forms, supplies, the operator pool) are carried pending until MAX IV staff confirm them. -[**MAX IV**](maxiv/index.md), in Lund, Sweden, is the synchrotron site the planned TomoWise beamline will run at, the second Site CORA models. It is a Federation `Facility` with `FacilityKind = Site` (`facility_code = "maxiv"`). Its page is thin while TomoWise is in design: most facility facts (safety forms, supplies, the operator pool) are carried pending until MAX IV staff confirm them. - -The operating institutions, Argonne and Lund University, are context, not modeled rows: there is no Enterprise or Institution kind. A sector or hutch grouping is a `Facility` with `FacilityKind = Area` only if it ever needs modeling, never an Asset row. +The operating institutions, Argonne and Lund University, are context, not modeled rows: there is no Enterprise or Institution kind. Cross-facility vocabulary (Capabilities, Methods) lives in the [Catalog](../catalog/index.md), since it is not bound to any single Site. - -A second Site is what graduates the facility envelope from a single appendix into its own area: the facility pages now carry one page per Site, [APS](aps/index.md) and [MAX IV](maxiv/index.md), with each beamline linking up to its own. diff --git a/docs/deployments/maxiv/assets.md b/docs/deployments/maxiv/assets.md deleted file mode 100644 index 2625742150..0000000000 --- a/docs/deployments/maxiv/assets.md +++ /dev/null @@ -1,13 +0,0 @@ -# Assets - -*Equipment BC Assets bound to the MAX IV Site.* - -MAX IV itself is not an Asset: it is a Federation `Facility` with `FacilityKind = Site` (`FacilityCode = "maxiv"`), declared on the [MAX IV index](index.md). In the pilot pattern, beamlines are root Assets (`tier = Unit`, `parent_id = None`) that bind the Site directly via `facility_code`. See [Model](../../architecture/model.md) for the aggregate shape. - -| Asset | Tier | facility_code | Hosts | -| --- | --- | --- | --- | -| `TomoWISE` | `Unit` | `maxiv` | [TomoWise](../tomowise/index.md) | - -Sub-systems and devices nested under the beamline are Assets with `tier = Component` or `tier = Device`, linked via `parent_id`. Being non-root, they do not carry `facility_code`; they inherit facility scope through the `parent_id` tree. - -TomoWISE is in the design phase: the asset tree above is the planned shape, not a registered inventory. diff --git a/mkdocs.yml b/mkdocs.yml index 9b99ab3103..b638157050 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -120,13 +120,9 @@ nav: - Techniques: deployments/tomowise/techniques.md - Governance: deployments/tomowise/governance.md - Model: deployments/tomowise/model.md - - Facility envelope: - - APS: - - deployments/aps/index.md - - Assets: deployments/aps/assets.md - - MAX IV: - - deployments/maxiv/index.md - - Assets: deployments/maxiv/assets.md + - Facilities: + - APS: deployments/aps/index.md + - MAX IV: deployments/maxiv/index.md - Catalog: - catalog/index.md - Capabilities: catalog/capabilities.md diff --git a/scripts/site_pages.py b/scripts/site_pages.py index 05556426bb..b35920ce8e 100644 --- a/scripts/site_pages.py +++ b/scripts/site_pages.py @@ -177,15 +177,28 @@ def _principals(site: Site, *, site_label: str) -> list[str]: return blocks -def _modeled(site_label: str) -> list[str]: - return [ +def _modeled( + site_label: str, *, facility_code: str, beamlines: list[tuple[str, str]] +) -> list[str]: + blocks = [ f"## How {site_label} is modeled", f"{site_label} itself is not an Asset: it is a Federation `Facility` with " - "`FacilityKind = Site`. The beamlines it hosts are the root Assets, each bound to the Site " - "by `facility_code`; their sub-systems nest below by `parent_id`. See " - f"[Assets](assets.md) for that binding and [the CORA model]({MODEL_PAGE}) for the " - "aggregate shapes.", + f'`FacilityKind = Site` (`facility_code = "{facility_code}"`). The beamlines it hosts are ' + "the root Assets (`tier = Unit`, `parent_id = None`), each bound to the Site directly by " + f"`facility_code`. See [the CORA model]({MODEL_PAGE}) for the aggregate shapes.", ] + if beamlines: + rows = [ + [f"`{label}`", "`Unit`", f"`{facility_code}`", f"[{label}](../{bslug}/index.md)"] + for label, bslug in beamlines + ] + blocks.append(_table(["Asset", "Tier", "facility_code", "Hosts"], rows)) + blocks.append( + "Sub-systems and devices nested under a beamline are Assets with `tier = Component` or " + "`tier = Device`, linked via `parent_id`. Being non-root, they do not carry `facility_code`; " + "they inherit facility scope through the `parent_id` tree." + ) + return blocks def render_all( @@ -208,5 +221,5 @@ def render_all( blocks += _resources(site) blocks += _safety(site) blocks += _principals(site, site_label=site_label) - blocks += _modeled(site_label) + blocks += _modeled(site_label, facility_code=f.code, beamlines=beamlines) return {f"deployments/{slug}/index.md": "\n\n".join(blocks) + "\n"} From 1c0162ac0611416d06fca920d25fa04118abd5f0 Mon Sep 17 00:00:00 2001 From: Doga Gursoy Date: Sun, 21 Jun 2026 22:35:32 +0300 Subject: [PATCH 2/2] docs(tomowise): tabulate the equipment specs and distinguish endstation from enclosure The TomoWise endstations and detector pages listed hardware as bullets while the generated pages (inventory, beamline, site) and 2-BM use tables inside framed sections. Convert the per-station and per-detector enumerations to spec tables (component, family, key specs, model/status) and keep the connective prose. Also clarify that an endstation is an equipment grouping label, not a modeled aggregate: the access-gated hutch is the Enclosure on a separate axis. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../tomowise/equipment/detector.md | 20 +++++++++----- .../tomowise/equipment/endstations.md | 26 ++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/docs/deployments/tomowise/equipment/detector.md b/docs/deployments/tomowise/equipment/detector.md index 1289d57a32..9e862fa26a 100644 --- a/docs/deployments/tomowise/equipment/detector.md +++ b/docs/deployments/tomowise/equipment/detector.md @@ -6,22 +6,28 @@ TomoWISE has a single detector system on a gantry that travels the experiment hu ## Gantry -- **Detector gantry** (Family `Table`): three axes Xd, Yd, Zd, with Zd on the 7 m floor rails. A removable flight tube (1 mbar) reduces air scatter for the long propagation distances. +| Component | Family | Key specs (TDR target) | Notes | +| --- | --- | --- | --- | +| Detector gantry | `Table` | three axes Xd, Yd, Zd, with Zd on the 7 m floor rails | removable flight tube (1 mbar) reduces air scatter for the long propagation distances | ## Microscopes Interchangeable visible-light microscopes couple the scintillator image to the cameras. The optics vendor is a design decision deferred to project year 2 (DET-2); the Optique Peter MICRX080 is the reference. -- **MicLFOV** (Family `Microscope`, not yet in the catalog): large field of view, 1-2x magnification, NA > 0.2. -- **MicHR** (Family `Microscope`, not yet in the catalog): high resolution, 4x / 10x / 20x, NA > 0.4. +| Microscope | Family | Key specs (TDR target) | Status | +| --- | --- | --- | --- | +| MicLFOV | `Microscope` | large field of view, 1-2x magnification, NA > 0.2 | Family not yet in catalog | +| MicHR | `Microscope` | high resolution, 4x / 10x / 20x, NA > 0.4 | Family not yet in catalog | ## Cameras Four cameras span the throughput-versus-speed-versus-resolution trade. The models are chosen in project year 2 (DET-1); the sensors below are the design targets. -- **Camera I** (Family `Camera`): 16-25 Mpix, 16-bit sCMOS, 100-150 fps. General throughput. -- **Camera II** (Family `Camera`): 4 Mpix, 12-bit CMOS, > 50,000 fps. High-speed dynamics. -- **Camera III** (Family `Camera`): ~4 Mpix, > 2,000 fps. Streaming. -- **Camera IV** (Family `Camera`): 150 Mpix, 54 x 40 mm sensor, 3.76 um pixel. Matches the large-sensor device already procured for DanMAX. +| Camera | Family | Sensor / speed (design target) | Use | +| --- | --- | --- | --- | +| Camera I | `Camera` | 16-25 Mpix, 16-bit sCMOS, 100-150 fps | general throughput | +| Camera II | `Camera` | 4 Mpix, 12-bit CMOS, > 50,000 fps | high-speed dynamics | +| Camera III | `Camera` | ~4 Mpix, > 2,000 fps | streaming | +| Camera IV | `Camera` | 150 Mpix, 54 x 40 mm sensor, 3.76 um pixel | matches the large-sensor device already procured for DanMAX | The camera models, the microscope vendor, and the trigger path are the main detector-side [open questions](../questions.md). See [Inventory](../inventory.md) for the Asset tree. diff --git a/docs/deployments/tomowise/equipment/endstations.md b/docs/deployments/tomowise/equipment/endstations.md index deb16a29d3..cb5ebd9ad6 100644 --- a/docs/deployments/tomowise/equipment/endstations.md +++ b/docs/deployments/tomowise/equipment/endstations.md @@ -4,17 +4,21 @@ TomoWISE has two experiment stations in the experiment hutch, sharing one [detector gantry](detector.md). They are modelled as two sample-stage groups in the [descriptor](../inventory.md), each presenting the specimen to the beam in a different way. +An endstation here is a grouping label, not a modeled aggregate: each is a cluster of Equipment `Asset`s (the stages and optics tabled below) inside the experiment hutch. The hutch itself is the access-gated [Enclosure](../../../architecture/modules/enclosure/index.md) on a separate axis; at MAX IV its PSS signals are still pending (see [Open questions](../questions.md)). + ## Microtomography endstation (~45 m) The workhorse station: a fixed sample table about 45 m from the source carrying the rotation and positioning stack. -- **Sample table** (Family `Table`): fixed at 45 m, surface 390 mm above the beam. Coarse table motion Xt (+/-100 mm), Yt (+50/-150 mm), and a beta tilt (1.2 deg). -- **Rotary stage** (Family `RotaryStage`): tomographic rotation up to 1200 rpm, 1 mdeg resolution, with a TTL encoder emitting 3600 pulses per revolution. The TDR names the Lab Motion Systems RT100AX as the target model; CORA leaves the Model unbound until confirmed (STAGE-1). This stage is also the trigger master clock (see [Controls](controls.md)). -- **Sample positioning** (Family `LinearStage`): Xs/Zs centring, +/-6 mm per axis, 0.1 um resolution. Target model XY150B-12 (STAGE-2). -- **Laminography tilt** (Family `TiltStage`): a 25 deg tilt axis for laminography, distinct from tomography rotation. -- **Sample-side slits** (Family `Slit`): a 50 x 5 mm aperture above the rotation axis; JJ X-ray IB-C50-air reference design. -- **Fast shutter** (Family `Shutter`): a sample-side fast shutter; the TDR cites Arinax Colibri (<5 ms) and Innospexion (<10 ms) reference designs. -- **Slip ring** (Family `SlipRing`, not yet in the catalog): 30 to 40 channels for continuous-rotation acquisition up to 1000 rpm. +| Component | Family | Key specs (TDR target) | Model / status | +| --- | --- | --- | --- | +| Sample table | `Table` | fixed at 45 m, surface 390 mm above the beam; Xt +/-100 mm, Yt +50/-150 mm, beta tilt 1.2 deg | - | +| Rotary stage | `RotaryStage` | tomographic rotation to 1200 rpm, 1 mdeg, TTL encoder 3600 pulses/rev; trigger master clock (see [Controls](controls.md)) | RT100AX target (STAGE-1) | +| Sample positioning | `LinearStage` | Xs/Zs centring, +/-6 mm per axis, 0.1 um | XY150B-12 (STAGE-2) | +| Laminography tilt | `TiltStage` | 25 deg tilt axis for laminography, distinct from tomography rotation | - | +| Sample-side slits | `Slit` | 50 x 5 mm aperture above the rotation axis | JJ X-ray IB-C50-air reference | +| Fast shutter | `Shutter` | sample-side fast shutter | Arinax Colibri (<5 ms) / Innospexion (<10 ms) reference | +| Slip ring | `SlipRing` | 30 to 40 channels for continuous-rotation acquisition to 1000 rpm | Family not yet in catalog | Optional modules the TDR anticipates (a horizontal-rotation loading rig for in-situ mechanics, a kHz tomography module) are not yet modelled; they join as confirmed. @@ -22,9 +26,11 @@ Optional modules the TDR anticipates (a horizontal-rotation loading rig for in-s The high-resolution station: the KB mirror pair focuses the undulator beam for 200-nm-class cone-beam imaging. -- **KB pair** (Family `Mirror`): Kirkpatrick-Baez fixed-curvature graded-multilayer focusing mirrors at ~49 m, focal spot 205 x 196 nm at 30 keV. Reused from the `Mirror` Family; the focusing-vs-steering distinction is a setting, not a Family split. -- **Sample stage** (Family `NanoPositioner`, not yet in the catalog): the nanotomography sample positioning. The TDR defers its specification to procurement, requiring only that its Abbe error be compatible with 200-nm resolution. Carried as a question (NANO-1), not a structure. +| Component | Family | Key specs (TDR target) | Model / status | +| --- | --- | --- | --- | +| KB pair | `Mirror` | Kirkpatrick-Baez fixed-curvature graded-multilayer focusing mirrors at ~49 m, focal spot 205 x 196 nm at 30 keV | reused `Mirror` Family | +| Sample stage | `NanoPositioner` | nanotomography sample positioning; Abbe error compatible with 200-nm resolution | deferred to procurement (NANO-1); Family not yet in catalog | -The KB pair and the nano sample stage are the only nano-specific hardware; the shared beam delivery and detector serve both stations. +The `Mirror` Family is reused for the KB pair: the focusing-versus-steering distinction is a setting, not a Family split. The KB pair and the nano sample stage are the only nano-specific hardware; the shared beam delivery and detector serve both stations. See [Open questions](../questions.md) for the deferred items (nano stage, stage models) and [Inventory](../inventory.md) for the Asset tree.