Inventory¶
The 2-BM equipment inventory: the CORA Asset model view (the device tree, settings, vendor Models, drawings, and signal wiring) plus the computed axes. Live condition is served by the app, not this page.
Assets¶
One row per registered Asset under the 2-BM root (tier = Unit, bound to its Site Facility via facility_code). Hutches 2-BM-A (optics) / 2-BM-B (experiment) are Enclosures, not Assets. Condition is served live by the app.
| Asset | Family | Model | Parent | Key settings | Condition |
|---|---|---|---|---|---|
StationShutter |
Shutter |
(none cited) | 2-BM |
- | live |
SampleTable |
Table |
(none) | 2-BM |
axis_layout=translation_xyz |
live |
RotaryDriveChassis |
Housing |
aerotech_tm3a |
2-BM |
serial 160591-A-1-1, order 730578 |
live |
RotaryDrive |
MotionController |
aerotech_ensemble_ml |
RotaryDriveChassis |
serial 730792/1, axis_count=1, Aerotech_Native |
live |
Rotary |
RotaryStage |
aerotech_abrs250mp |
LaminographyPitch |
-360..360 deg, max_speed=720 deg/s (operational), aperture=35 mm, encoder_resolution=0.000676 deg |
live |
SampleStageDrive |
MotionController |
oms_vme58 |
2-BM |
axis_count=91, OMS_VME |
live |
FrontEndDrive |
MotionController |
oms_vme58 |
2-BM |
axis_count=91, OMS_VME |
live |
FrontEndWindow |
Window |
(none) | 2-BM |
OFHC-housed Be window assembly; identity-only (beam-effect deferred) | live |
Window_W4_20 |
Window |
(none) | FrontEndWindow |
Be 0.25 mm, z 28718, aperture 120 x 15 mm | live |
Window_W4_60 |
Window |
(none) | FrontEndWindow |
Be 0.13 mm, z 30804, aperture 25 x 120 mm | live |
Window_DS |
Window |
(none) | FrontEndWindow |
Be 0.25 mm, z 32417, aperture 8.8 x 145 mm (unlabelled, downstream-most) | live |
Mirror |
Mirror |
(none) | MirrorTable |
driven by FrontEndDrive; 4 coating stripes (a/b/c/d), held in Mono, swept per Pink energy (MIRROR-1) |
live |
Mirror_StripeReachX |
PseudoAxis |
(none) | Mirror |
m1_horizontal (2bma:m3); Mono held at stripe a, Pink swept per energy |
live |
MirrorTable |
Table |
(none) | 2-BM |
axis_layout=virtual_pose, virtual_record=2bma:table1 |
live |
Monochromator |
Monochromator |
(none) | 2-BM |
dmm_insertion=inserted (MODE-2); driven by FrontEndDrive |
live |
Monochromator_BraggArmUpstream |
PseudoAxis |
(none) | Monochromator |
energy->upstream Bragg arm (deg) | live |
Monochromator_BraggArmDownstream |
PseudoAxis |
(none) | Monochromator |
energy->downstream Bragg arm (deg) | live |
Monochromator_M2Y |
PseudoAxis |
(none) | Monochromator |
energy->M2 vertical offset (mm) | live |
ConditioningSlit |
Slit |
(none) | 2-BM |
white-beam slits; driven by FrontEndDrive |
live |
Filter |
Filter |
(none) | 2-BM |
foil changer; driven by FrontEndDrive |
live |
Filter_FoilSelector_Upstream |
PseudoAxis |
(none) | Filter |
m17 slot index -> position (Nearest); operational selector | live |
Filter_FoilSelector_Downstream |
PseudoAxis |
(none) | Filter |
m18 slot index -> position (Nearest); bindings retained | Faulted (m18 failed 2026-06-19) |
DiagnosticFlag |
Screen |
(none) | 2-BM |
2bma:m44 at z=32500; raised in Mono, parked in Pink |
live |
DiagnosticFlag_Y |
PseudoAxis |
(none) | DiagnosticFlag |
energy->flag height (Mono); parked out in Pink | live |
SampleSlit |
Slit |
(none) | 2-BM |
B-station slits; driven by FrontEndDrive |
live |
SampleSlit_VerticalTop |
PseudoAxis |
(none) | SampleSlit |
energy->top blade beam position (mm) | live |
SampleSlit_VerticalBottom |
PseudoAxis |
(none) | SampleSlit |
energy->bottom blade beam position (mm) | live |
SampleSlit_VerticalCenter |
PseudoAxis |
(none) | SampleSlit |
derived MidRange(top, bot); beam-walk centre |
live |
SampleSlit_VerticalAperture |
PseudoAxis |
(none) | SampleSlit |
derived Difference(top, bot); constant 20 mm gap |
live |
SampleTop_X |
LinearStage |
kohzu_cyat070 |
Rotary |
-10..10 mm, max_speed=1 mm/s, encoder_resolution=0.0005 mm |
live |
SampleTop_Z |
LinearStage |
kohzu_cyat070 |
SampleTop_X |
same Model/controller as SampleTop_X |
live |
HexapodDrive |
MotionController |
aerotech_automation1_ixr3 |
2-BM |
serial 486125-01, axis_count=6, Aerotech_Native |
live |
Hexapod |
Hexapod |
aerotech_hex300 |
SampleTable |
serial 486060-01; full HEX300 envelope (see Settings) |
live |
Hexapod_X |
PseudoAxis |
(none) | Hexapod |
DoF; translation X | live |
Hexapod_Y |
PseudoAxis |
(none) | Hexapod |
DoF; translation Y | live |
Hexapod_Z |
PseudoAxis |
(none) | Hexapod |
DoF; translation Z; modelled, not wired in current EPICS | modelled (unwired) |
Hexapod_Roll |
PseudoAxis |
(none) | Hexapod |
DoF; rotation A about X | live |
Hexapod_Pitch |
PseudoAxis |
(none) | Hexapod |
DoF; rotation B about Y | live |
Hexapod_Yaw |
PseudoAxis |
(none) | Hexapod |
DoF; rotation C about Z; modelled, not wired in current EPICS | modelled (unwired) |
LaminographyPitch |
TiltStage |
kohzu_sa16a |
Hexapod |
Kohzu SA16A 2bmb:m49; tomo/lamino = tilt setpoint |
live |
PropagationDistanceDrive |
MotionController |
aerotech_ensemble_hle |
2-BM |
serial 228849-02, axis_count=1, Aerotech_Native |
live |
Timing |
TimingController |
(none) | 2-BM |
softGlueZynq trigger box; protocol=EPICS; no controller_id |
live |
ApertureFineDrive |
MotionController |
piezosystem_jena_nv200d |
2-BM |
two Jena NV200D units; fine-positions the Aperture coded-mask; FPGA-stepped via Timing |
live |
DetectorTable |
Table |
(none) | 2-BM |
axis_layout=virtual_pose, virtual_record=2bmb:table3 |
live |
DetectorTable_X |
PseudoAxis |
(none) | DetectorTable |
IOC virtual axis; 2bmb:table3.X |
live |
DetectorTable_Y |
PseudoAxis |
(none) | DetectorTable |
IOC virtual axis; 2bmb:table3.Y |
live |
DetectorTable_Z |
PseudoAxis |
(none) | DetectorTable |
IOC virtual axis; 2bmb:table3.Z |
live |
DetectorTable_Roll |
PseudoAxis |
(none) | DetectorTable |
IOC virtual axis; raw AZ; 2bmb:table3.AZ |
live |
DetectorTable_Pitch |
PseudoAxis |
(none) | DetectorTable |
IOC virtual axis; raw AX; 2bmb:table3.AX |
live |
DetectorTable_Yaw |
PseudoAxis |
(none) | DetectorTable |
IOC virtual axis; raw AY; 2bmb:table3.AY |
live |
Housing |
Housing |
(none) | PropagationDistance |
Microscope chassis; installed into a Mount | live |
Turret |
LinearStage |
(microscope catalog) | Housing |
-60.3784..59.2300 mm (DET-11), encoder_resolution=0.0016 mm |
live |
Objective_10x |
Objective |
(microscope catalog) | Housing |
mag 10.0, NA 0.28, f=20 mm, WD 33.5 mm | live |
Objective_2x |
Objective |
(microscope catalog) | Housing |
mag 2.0, NA 0.055, f=100 mm, WD 34 mm | live |
Objective_1.1x |
Objective |
(microscope catalog) | Housing |
mag 1.1, NA 0.03, f=200 mm, WD 50 mm | live |
Objective_Selector |
PseudoAxis |
(none) | Housing |
writes MCTOptics LensSelect; (lens x camera) turret lookup, Camera 0 column as 1D provenance rule (DET-11) |
live |
PropagationDistance |
LinearStage |
aerotech_pro225sl |
DetectorTable |
sample-to-detector rail; driven by PropagationDistanceDrive |
live |
Camera |
Camera |
(microscope catalog) | Housing |
5 MP FLIR Oryx; 2448x2048, 3.45 um, 12 bit, 162 Hz, CMOS GlobalShutter | live |
Camera_HighRes |
Camera |
flir_oryx_31mp |
Housing |
31 MP FLIR Oryx; pixel 3.45 um; other settings pending | live (settings pending) |
Camera_Selector |
LinearStage |
schunk_lptm_30 |
Housing |
Schunk LPTM 30; Pos.0=20, Pos.1=15; stage settings pending | live (settings pending) |
Scintillator |
Scintillator |
(microscope catalog) | Housing |
thickness 100 um, decay 0.07 us | live |
Microscope-bound Models (turret motor, Mitutoyo MPLAPO kit, FLIR Oryx, Crytur LuAG) live on the Microscope deployment page. The kohzu_sa16a binding for LaminographyPitch is on the Sample tower page.
Settings¶
Per-asset settings the source spells out in prose. Open-item tags (DRIVE-1, DRIVE-2, TIME-1) kept inline.
| Asset | Settings |
|---|---|
SampleTable |
axis_layout=translation_xyz; direct motors 2bmb:m24 Y, 2bmb:m20 Z, 2bmb:m21 X-up, 2bmb:m22 X-down |
DetectorTable |
axis_layout=virtual_pose; virtual_record=2bmb:table3; geometry=SRI: 3 Y-supports, 2 X-supports, 1 Z-support |
MirrorTable |
axis_layout=virtual_pose; virtual_record=2bma:table1; geometry=SRI support table; X axes M0X/M2X driven by energy-change IOC; bind table-X surface only until M1Y=2bma:m3 IOC substitution error fixed |
Monochromator |
dmm_insertion=inserted (closed enum inserted | retracted, MODE-2); DMM Y motors 2bma:m26 / m27 / m29 to 0 in (Mono) / -10 mm out (Pink); driven by FrontEndDrive |
RotaryDrive |
serial_number=730792/1; firmware_version=unknown-pending-confirmation (DRIVE-2); axis_count=1; protocol=Aerotech_Native; installed in RotaryDriveChassis |
RotaryDriveChassis |
altids: serial 160591-A-1-1 (SerialNumber), order 730578 (Other); drawing 630D2079 REV-H; inventory-only, no command surface |
PropagationDistanceDrive |
serial_number=228849-02; firmware_version=unknown-pending-confirmation (DRIVE-2); axis_count=1; protocol=Aerotech_Native; IOC handle 2bmbAERO (EPICS_PV altid); addressed 2bmbAERO:m1 |
SampleStageDrive |
serial_number=unknown-pending-confirmation (DRIVE-1); firmware_version=unknown-pending-confirmation (DRIVE-2); axis_count=91; protocol=OMS_VME; crate ioc2bmb, no IP (VME-bus) |
FrontEndDrive |
serial_number=unknown-pending-confirmation (DRIVE-1); firmware_version=unknown-pending-confirmation (DRIVE-2); axis_count=91; protocol=OMS_VME; crate ioc2bma, no IP (VME-bus) |
HexapodDrive |
serial_number=486125-01; firmware_version=unknown-pending-confirmation (DRIVE-2); axis_count=6; protocol=Aerotech_Native; Automation1-iXR3 in separate rack |
Timing |
firmware_version=2.0 (softGlueZynq gateware/bitstream); serial_number=unknown (IOC-admin only, not beamline-retrievable); output_channel_count=unknown (IOC-admin only, not beamline-retrievable); protocol=EPICS; 2bmbMZ1:SG: |
Rotary |
min_position=-360 deg; max_position=360 deg; max_speed=720 deg/s (operational soft limit); max_speed_datasheet=3000 deg/s (500 rpm); encoder_resolution=0.000676 deg; homing_offset=0 deg; aperture=35 mm; accuracy_rotation=2 arcsec; repeatability_rotation=1 arcsec; load_capacity_axial=66 kg; load_capacity_radial=36 kg; load_capacity_tilt=28 Nm; stage_mass=15.6 kg; altid serial 146853-A-1-1-X; part ABRS-250MP-M-AS; datasheet on file (#164) |
SampleTop_X |
min_position=-10 mm; max_position=10 mm; max_speed=1 mm/s; encoder_resolution=0.0005 mm; channel 2bmb:m18 |
SampleTop_Z |
same Model kohzu_cyat070 + controller as SampleTop_X; channel 2bmb:m17 |
Hexapod |
travel_x=55 mm, travel_y=60 mm, travel_z=25 mm, travel_a=15 deg, travel_b=15 deg, travel_c=30 deg; max_speed_translation=25 mm/s, max_speed_rotation=15 deg/s; resolution_translation=20 nm, resolution_rotation=0.2 urad; accuracy_translation=1 um, accuracy_rotation=10 urad; load_capacity_vertical=45 kg, load_capacity_horizontal=21 kg; stage_mass=12 kg; altid serial 486060-01 |
Scintillator |
thickness=100 um; decay_time=0.07 us |
Camera |
sensor_width=2448 pixel; sensor_height=2048 pixel; pixel_size=3.45 um; bit_depth=12 bit; max_framerate_hz=162 Hz; sensor_kind=CMOS; readout_mode=GlobalShutter; altids model Oryx ORX-10G-51S5M, serial 19173710, firmware 1710.0.0.0, EPICS 2bmSP1: |
Camera_HighRes |
model Oryx ORX-10G-310S9M; serial 22150530; firmware 1904.0.72.0; EPICS 2bmSP2:; pixel_size=3.45 um; remaining Camera-schema settings pending |
Camera_Selector |
Schunk LPTM 30 (2bmb:m5); Pos.0=20, Pos.1=15; min/max/max_speed/encoder_resolution pending |
Turret |
min_position=-60.3784 mm; max_position=59.2300 mm; encoder_resolution=0.0016 mm; Nanotec ST4118M1404-B, Heidenhain ERO 1420 encoder; MCTOptics resolves the (lens x camera) position (DET-11), Camera 0 column: 1.1x=-59.8184 mm, 2x=-0.5734 mm, 10x=58.8707 mm |
Objective_10x |
magnification=10.0; numerical_aperture=0.28; focal_length=20 mm; working_distance=33.5 mm |
Objective_2x |
magnification=2.0; numerical_aperture=0.055; focal_length=100 mm; working_distance=34 mm |
Objective_1.1x |
magnification=1.1; numerical_aperture=0.03; focal_length=200 mm; working_distance=50 mm |
Vendor catalog¶
Models bound to non-microscope 2-BM Assets. Model ids are derived from (manufacturer, part number), so one vendor product converges on one id. Microscope-housing Models are on the Microscope deployment page.
Generated from the catalog
This table is generated from catalog/catalog.yaml. Edit the catalog, not this table.
| Model | Manufacturer | Part number | Used by |
|---|---|---|---|
aerotech_hex300 |
Aerotech | HEX300-230HL-E1-PL4-TAS |
Hexapod |
aerotech_abrs250mp |
Aerotech | ABRS-250MP-M-AS |
Rotary |
aerotech_ensemble_ml |
Aerotech | ENSEMBLEML 10-40-IO-MXH |
RotaryDrive |
aerotech_automation1_ixr3 |
Aerotech | Automation1-iXR3-VL1-VB4-VB4-SB0CT222222-P1P1P1P1P1P1-CO-LC1MT1PSO6-SI0-TAS |
HexapodDrive |
aerotech_ensemble_hle |
Aerotech | EnsembleHLe10-40-A-IO-MXH |
PropagationDistanceDrive |
aerotech_pro225sl |
Aerotech | PRO225SL-1000 |
PropagationDistance |
aerotech_tm3a |
Aerotech | TM3-A-20B VDC-20B VDC / NO SPLIT / PS24-1 / C1ML-06 / C2ML-09 / US-115VAC |
RotaryDriveChassis |
oms_vme58 |
Oregon Micro Systems | VME58 |
SampleStageDrive, FrontEndDrive |
kohzu_cyat070 |
Kohzu | CYAT-070 |
SampleTop_X, SampleTop_Z |
piezosystem_jena_nv200d |
Piezosystem Jena | NV200D/NET |
ApertureFineDrive |
Controller back-references: RotaryDrive->Rotary.controller_id; HexapodDrive->Hexapod.controller_id; PropagationDistanceDrive->PropagationDistance.controller_id (IOC 2bmbAERO); SampleStageDrive->SampleTop_X (2bmb:m18) / SampleTop_Z (2bmb:m17) + 89 further motors on ioc2bmb; FrontEndDrive->Mirror, Monochromator, ConditioningSlit, SampleSlit, Filter on ioc2bma. The Objective_Selector (2bmb:m1) and Camera_Selector (2bmb:m5) steppers run through the SampleStageDrive OMS crate, not distinct controller Assets. The six Hexapod_* DoF facets bind no Model (the physical Hexapod carries aerotech_hex300).
Engineering drawings¶
One canonical (system, number, revision) triple per Asset, except Rotary, which cites both its per-unit vendor drawing and the ABRS family datasheet. Optique Peter MAN-11863 (rev 0521-0465-A) is the shared housing manual covering every Microscope-bound constituent.
| Asset | Drawing | System |
|---|---|---|
Hexapod |
Hex300-Data-Sheet rev D20250203 |
EDMS |
Rotary |
630C2125 rev (-) |
EDMS |
Rotary |
ABRS series datasheet (2021-01) | Aerotech |
RotaryDriveChassis |
630D2079 rev H |
EDMS |
PropagationDistance |
MAN-11863 rev 0521-0465-A |
EDMS |
Turret |
MAN-11863 rev 0521-0465-A |
EDMS |
Objective_10x |
MAN-11863 rev 0521-0465-A |
EDMS |
Objective_2x |
MAN-11863 rev 0521-0465-A |
EDMS |
Objective_1.1x |
MAN-11863 rev 0521-0465-A |
EDMS |
Scintillator |
MAN-11863 rev 0521-0465-A |
EDMS |
StationShutter |
41050401-410003 rev (-) (P6-50 shutter element; assembly 41050401-500000) |
ICMS |
Mask |
4102020101-240000 (M3-24 front-end exit mask; RSS 02-BM-A-F-01) |
ICMS |
Window_W4_20 |
4105090804-200000 (front-end Be window W4-20) |
ICMS |
Window_W4_60 |
4105090804-600000 (front-end Be window W4-60) |
ICMS |
Window_DS |
4102020106-400000 (front-end Be window, unlabelled, downstream-most) |
ICMS |
Not yet cited: Kohzu CYAT-070 datasheet (SampleTop_*), a FLIR Oryx datasheet (Camera).
Signal wiring¶
Trigger and step signals are modelled as typed ports plus wires resolved at Plan-bind time. Executable model: apps/api/tests/integration/scenarios/test_2bm_trigger_wiring.py.
Fine-positioning piezo controllers¶
ApertureFineDrive= two Piezosystem Jena NV200D/NET single-channel controllers (staff item_028), one per axis (X10.54.113.126, Y10.54.113.125), EPICS IOCJenaNV200Don hostarcturus. They fine-position theAperturecoded-mask via a nanoSXY 120 CAP XY flexure stage (partT-223-06D, 120 um nominal / 100 um closed-loop per axis, 12.5 mm clear aperture); the axes step under FPGA trigger for compressive-sensing dithered sampling (PIEZO-1/2/4).- The Jena NV100D (formerly the provisional
OpticsFineDrive, IOCJenaNV100D) is physically present but not in operational use at 2-BM: it lacks the external trigger mode tomoscan fly-scan needs, so no Run drives it. Recorded as provenance, not modelled as an active controller. - The driven X/Y
LinearStageaxis Assets and theApertureidentity registration are deferred to a follow-up slice; the FPGAout2/out3-> X/Y cable map needs operator confirmation (PIEZO-5).
NV200D trigger wiring¶
| Asset | Port | Direction | signal_type |
|---|---|---|---|
Timing |
out2, out3 |
OUTPUT | step_trigger_ttl |
ApertureFineDrive |
step_x_in, step_y_in |
INPUT | step_trigger_ttl |
- Wires:
Timing.out2 -> ApertureFineDrive.step_x_in,Timing.out3 -> ApertureFineDrive.step_y_in(JenaX/JenaY land on FPGAout2/out3, item_028); up to 1024 positions/axis. - Gate-delay PVs:
2bmbMZ1:SG:GateDly-3_DLY(labelled "X axis delay"),2bmbMZ1:SG:GateDly-2_DLY(labelled "Y axis delay"); the label-to-cable map appears crossed, recorded verbatim and flagged for confirmation. - Ports sit on the controller box today; they migrate onto per-axis Assets when registered.
Camera trigger wiring¶
| Asset | Port | Direction | signal_type |
|---|---|---|---|
Timing |
camera_trigger_out |
OUTPUT | frame_trigger_ttl |
Camera |
trigger_in |
INPUT | frame_trigger_ttl |
- One wire:
Timing.camera_trigger_out -> Camera.trigger_in(item_060).frame_trigger_ttl(start exposure) is distinct from the piezostep_trigger_ttl(advance a motion step). - Two labels open for staff: the exact FPGA output channel feeding the camera (path ends at camera
Line2, no box-side output named), and theGateDly1block name (unconfirmed vs the source-groundedGateDly-2/GateDly-3). - softGlue
Width/DLYcount 10 MHz clock cycles (100 ns/count, soWidth=100= 10 us pulse); per-scan values are Method/Plan config.
Computed axes¶
The PseudoAxis Assets whose position is computed from the motors underneath, divided by who owns the math: firmware SolverReference (hexapod), an edge IOC with no rule (detector table), or a Calibration-backed LookupTable (energy axes and foil selector). Executable models cited per subsection.
Hexapod DoF model¶
One physical Device (vendor-sealed Aerotech HEX300; inverse kinematics in firmware solver 2bmHXP). Six DoF surfaced as PseudoAxis sub-modules, each carrying a SolverReference partition rule; per-DoF envelope stays on the Hexapod settings, not duplicated onto facets.
| DoF Asset | Kind | Axis | Vendor label | EPICS channel |
|---|---|---|---|---|
Hexapod_X |
translation | along X | n/a | 2bmHXP:m1 |
Hexapod_Y |
translation | along Y | n/a | 2bmHXP:m2 |
Hexapod_Z |
translation | along Z | n/a | none (no operator handle) |
Hexapod_Roll |
rotation | about X | A (travel_a) |
2bmHXP:m5 |
Hexapod_Pitch |
rotation | about Y | B (travel_b) |
2bmHXP:m4 |
Hexapod_Yaw |
rotation | about Z | C (travel_c) |
none (no operator handle) |
- Z and Yaw exist physically but are not exposed as operator channels in 2-BM's current EPICS (no
m3/m6); CORA still models all six (deployment-configuration limit, not a device one). - Constituent-port wiring: each DoF reads feedback from
HexapodviaPlan.wires(not a partition-rule field).Hexapodexposesx/y/z_feedback_out(position_feedback_linear_mm) androll/pitch/yaw_feedback_out(position_feedback_rotation_deg); each facet has oneconstituent_inINPUT plus one<axis>_outsetpoint OUTPUT. Six wires, one per DoF (Hexapod.<axis>_feedback_out -> Hexapod_<Axis>.constituent_in).validate_pseudoaxis_fanoutexemptsSolverReferencefrom the arity check; decomposition is owned by the firmware solver.
Detector table axes¶
Six virtual axes on the 2bmb:table3 record, modelled as PseudoAxis sub-Assets of DetectorTable. No partition rule and no constituent wiring: the table_full IOC computes the pose from six support motors (M0X / M0Y / M1Y / M2X / M2Y / M2Z) in SRI geometry. Addressing is a direct ControlPort write to the table3.* PV (spine/edge seam). Model: apps/api/tests/integration/scenarios/test_2bm_optical_tables_setup.py.
| Axis Asset | Kind | table3 field |
Raw label |
|---|---|---|---|
DetectorTable_X |
translation | .X |
n/a |
DetectorTable_Y |
translation | .Y |
n/a |
DetectorTable_Z |
translation | .Z |
n/a |
DetectorTable_Pitch |
rotation | .AX |
AX |
DetectorTable_Yaw |
rotation | .AY |
AY |
DetectorTable_Roll |
rotation | .AZ |
AZ |
Angular mapping (AX=pitch, AY=yaw, AZ=roll) is staff-confirmed (STAGE-9).
Energy-tracking optic axes¶
Setting energy is a discrete coordinated move. The staff energy-change IOC stores per-energy positions (store_0 saved table) and drives ~15 motors. Each per-axis relationship is modelled as a continuous curve: a PseudoAxis carrying a LookupTable partition rule converting energy (unit_in=keV) to axis position, pinning a Calibration revision by id (energy_position_curve quantity). Each axis carries a Mono curve (beam_mode=mono, the active rule) and a sibling Pink curve (beam_mode=pink, parked constant). invertible is per-axis: the Bragg arms + M2Y are monotonic in energy (invertible=True); the slit blades (constant 20 mm aperture, non-monotonic centre walk) and the flag Y (flat at the top of its range) are invertible=False with readback_aggregator_kind=Identity. Coordinating operation = the energy_setting Procedure, which accepts a free keV value between saved points. Models: test_2bm_energy_curves_setup.py (curves) + test_2bm_energy_setting.py (operation).
Configured Mono energies (the curve x-points, real): 13.374, 13.574, 18.0, 20.0, 25.0, 25.584 keV; Pink: 30, 40, 50, 60 keV (axes parked). Pink mode bypasses the monochromator. Beam-mode switching itself is on the Procedures page, not a virtual axis.
| Axis Asset | Motors / handle | Curve | unit_out |
|---|---|---|---|
Monochromator_BraggArmUpstream |
dmm_us_arm |
energy -> upstream Bragg arm | deg |
Monochromator_BraggArmDownstream |
dmm_ds_arm |
energy -> downstream Bragg arm | deg |
Monochromator_M2Y |
dmm_m2_y |
energy -> M2 vertical offset compensator | mm |
SampleSlit_VerticalTop |
b_slit_top |
energy -> top blade beam-walk | mm |
SampleSlit_VerticalBottom |
b_slit_bot |
energy -> bottom blade beam-walk | mm |
DiagnosticFlag_Y |
energy_move_flag (2bma:m44) |
energy -> flag height (Mono), parked out in Pink | mm |
Mirror_StripeReachX |
m1_horizontal (2bma:m3) |
held at stripe a in Mono (m3 1.0), swept per Pink energy (3.039/13/39/49) | mm |
- Slit aperture is held constant at 20 mm; only the centre tracks the beam walk (non-monotonically). The centre and aperture are modelled as derived axes:
SampleSlit_VerticalCenter(AggregationMidRange) andSampleSlit_VerticalAperture(AggregationDifference) over the two blades.Aggregationis one-way (computed from constituents), so they are read-only views. The rules declare the relationship; binding the two specific blades via constituent port wiring (the hexapod-pose pattern) is deferred with the rest of the per-facet conduct wiring. - DMM insert/bypass (MODE-2): the DMM is physically inserted in Mono and retracted in Pink. This two-state, mode-keyed position is NOT a per-energy curve; it is the
dmm_insertionsetting on theMonochromator(closed enuminserted|retracted, theTable.axis_layoutpattern), with the three DMM Y motors (2bma:m26/m27/m29, driven together to0in /-10mm out) documentary inbeamline.yaml. The coordinated move that drives it is the deferredbeam_mode_change(MODE-3 / MIRROR-1). - Mirror coating stripe (MIRROR-1 / MODE-3): the stripe selector
m1_horizontal(2bma:m3) is held at stripe a in Mono (constant m3 1.0) and swept per Pink energy (3.039 / 13 / 39 / 49 mm at 30 / 40 / 50 / 60 keV), modelled as theMirror_StripeReachXfacet (constant Mono curve + swept Pink sibling,invertible=False). The named-stripe-to-position map (a Pt / b,c,d W-Si) is in theMirrorstripeslist inbeamline.yaml. The coordinated mirror-table X move (m1mox/m1m2x=2bma:m1/m4) that stripe d needs at 60 keV stays deferred to itsMirrorTablevirtual_pose axes (2bm-docs#171); the mirror angle is constant 2.615 mrad across all modes/energies. - Not energy axes:
crystal2_z(M2 Z,2bma:m8) is a setup translation the IOC does not drive, so it carries no curve. - DMM substrate stripe is a one-time setup, not a per-energy selector (ENERGY-6, settled): the substrate carries two W-B4C/Si multilayer stripes (periods 24 and 13.8 angstrom, 4 mm apart), recorded as the
Monochromatorstripeslist withactive_stripe=24.0inbeamline.yaml. The 24 angstrom stripe is the in-beam one (inferred from Bragg-arm geometry); the 13.8 angstrom stripe is never calibrated intostore_0. The lateral X motors2bma:m25/2bma:m28are constant alignment positions in both modes (ENERGY-5), not stripe selectors, so CORA models no DMM stripe-selector axis. Switching stripes would be a 4 mm lateral move plus a full recalibration, outside any current move. - Curves carry the REAL saved
store_0positions (ENERGY-1/2, FLAG-1): full 6-energy Mono curves plus parked Pink curves. Runtimeeval_lookup_tableis wired; out-of-range refuses (extrapolation_kind=Error, staff-confirmed ENERGY-4: the inter-mode band 25.584-30 keV is not bridgeable by interpolation). - Recalibration updates these curves in place: the
energy_characterizationProcedure (channel-cut rocking curve, item_022) re-saves the corrected positions as a new revision of the affectedenergy_position_curve,MeasuredSource-cited, preserving the prior revision as history. There is no separate energy offset (ENERGY-8).
Filter foil selection¶
Discrete "pick one of N" move. Two PseudoAxis facets under Filter (Filter_FoilSelector_Upstream for the operational 2bma:m17, Filter_FoilSelector_Downstream for the 2bma:m18), each carrying a LookupTable rule with interpolation_kind=Nearest backed by its own index_position_table Calibration. extrapolation_kind=Error (cannot select an absent foil); invertible=False with readback_aggregator_kind=Identity. The downstream m18 paddle failed 2026-06-19 (parked 107.19 mm), modelled condition Faulted with bindings retained and lifecycle still Active; m17 is the sole operational selector. Runtime proven end-to-end in apps/api/tests/integration/test_pseudoaxis_roundtrip.py; model: test_2bm_filter_foil_setup.py.
Downstream-paddle slot positions (REAL, staff-published):
| Slot index | Material | Position |
|---|---|---|
| 0 | 600 um Al |
0 |
| 26 | 150 um Al |
26 |
| 53 | 300 um C |
53 |
| 80 | 50 um C |
80 |
| 106 | None |
106 |
The position unit is mm, staff-confirmed (caget 2bma:m18.EGU, FOIL-1). Foil ATTENUATION (Attenuable) and the energy-dependent mirror coating stripe (2bma:m3) are deliberately out of scope here (the stripe is modelled with the beam-mode work).