Skip to main content

Module columns

Module columns 

Source
Expand description

Stable columnar boundary for WASM, FFI, and GPU consumers.

The Model layer is already struct-of-arrays, but its public fields are Rust types (Vec<String>, Option<char>, Element, Arc, borrowed views) that cannot cross a wasm-bindgen or C ABI boundary, or be uploaded to a GPU, as they are. This module is the contract for doing so. It adds no dependencies: bindings crates (wasm-bindgen, PyO3, a C header) and renderers (bevy, wgpu) build on it.

§What crosses the boundary

§Ownership, borrowing, and invalidation

DataSourceCopy or borrowValid until
x, y, z, occupancy, b_iso, confidenceFrameColumnsborrow of the model’s conformationthe model is dropped or its conformation mutated
sequence ids, segment offsets, bondsTopologyColumnsborrow of the pinned hierarchythe snapshot is dropped
element, alt_loc, charge, ins_code, group, dictionariesTopologyColumnsowned, encoded once per hierarchythe snapshot is dropped
interleaved positions, bond line indicesGpuBufferowned copynever (independent of the model)

Inside Rust the borrow checker enforces the “valid until” column. Across FFI it is the caller’s obligation: a raw pointer from ColumnData::as_ptr is valid exactly as long as the Rust borrow it came from.

A TopologyColumns snapshot keeps its Arc<AtomicHierarchy> alive and therefore immutable (Arc::make_mut will clone rather than mutate). A topology edit thus produces a new hierarchy, and pairing a frame with the old snapshot fails with StaleTopology rather than exporting mismatched columns. All frames of a trajectory share one hierarchy, so one snapshot serves every frame.

§wasm-bindgen

A zero-copy JS typed-array view over a borrowed column (e.g. js_sys::Float32Array::view) points into wasm linear memory and is detached by any allocation that grows that memory, including allocations made later by ferritin itself. Use views only for an immediate copy or upload within the same call; copy (Float32Array::from) anything JS keeps.

§Example

let topology = TopologyColumns::from_model(&model)?;   // once per hierarchy
let frame = topology.frame(&model)?;                   // per frame, zero-copy
upload(frame.positions(PositionLayout::Padded4));      // owned, 16-byte stride
upload(GpuBuffer::from_column(column)?);               // borrowed scalar column
upload(topology.bond_line_indices());                  // owned [a, b] pairs

Structs§

AtomHandle
Handle to one atom row.
BoundaryError
An error raised while exporting columns across the WASM/FFI/GPU boundary.
BufferLayout
Memory layout of one GPU buffer.
ChainHandle
Handle to one chain row.
Column
A named column, as listed by TopologyColumns::columns and FrameColumns::columns.
FrameColumns
Borrowed per-frame columns: coordinates and per-atom scalars.
GpuBuffer
Bytes ready to upload, with their layout.
ResidueHandle
Handle to one residue row.
StringDictionary
A dictionary-encoded string column.
TopologyColumns
Boundary-ready, frame-independent topology columns.

Enums§

BoundaryErrorKind
Category of a BoundaryError.
ColumnData
A borrowed, contiguous, typed numeric column.
PositionLayout
How to interleave atom positions for upload.
ScalarType
Scalar element type of an exported column.

Constants§

NO_ALT_LOC
atom.alt_loc value for atoms without an alternate-location indicator.
NO_FORMAL_CHARGE
atom.formal_charge value for atoms without a recorded formal charge.
NO_INS_CODE
residue.ins_code value for residues without an insertion code.
RESIDUE_GROUP_NON_POLYMER
residue.group value for non-polymer residues.
RESIDUE_GROUP_POLYMER
residue.group value for polymer residues.