Getting started¶
lefsim isn't published yet, so for now each binding builds from a clone of the repository.
Build¶
The core crate builds with a stable Rust toolchain:
cargo build
cargo test
cargo run --example single_lef # prints a single LEF's trajectory
Add features = ["serde"] to read and write models as JSON.
The Python package lives in python/ and builds the bindings in
crates/lefsim-py with maturin. With uv:
cd python
uv sync # venv, dependencies, and the extension, built with maturin
uv run pytest tests # rebuilds the extension first if the Rust code changed
It builds one abi3 wheel for Python 3.9 and later, with no Python dependencies of its own.
The TypeScript package lives in packages/lefsim and wraps the WebAssembly
build of the core, made with wasm-pack. With pnpm:
pnpm install
pnpm build:wasm # wasm-pack → packages/lefsim/wasm
pnpm test # vitest, against the real wasm build
A first run¶
A model is a lattice, the LEFs on it, and their rates. This one has a convergent pair of CTCFs, each capturing legs that arrive from outside the domain between them.
use lefsim::*;
let lattice = Lattice::with_ctcfs(1000, &[
Ctcf { site: 300, captures_from: Direction::Right, strength: 0.9 },
Ctcf { site: 700, captures_from: Direction::Left, strength: 0.9 },
])?;
let rule = SpawnRule::UniformNonCtcf;
let world = populate(lattice, 10, &rule, 1)?; // ten LEFs, placed with seed 1
let model = Model::new(world, Rates::default(), rule)?;
let mut sim = Sim::new(model, 42);
sim.run_until(1000.0);
println!("{:?}", sim.world().lef_states());
import lefsim
import polars as pl
lattice = lefsim.Lattice(1000, {"site": [300, 700], "captures_from": ["right", "left"], "strength": 0.9})
world = lefsim.populate(lattice, 10, seed=1)
model = lefsim.Model(world, lefsim.Rates())
sim = lefsim.Sim(model, seed=42)
rec = sim.record_until(1000.0, dt=1.0) # advance, taking a snapshot every time unit
pl.DataFrame(rec.snapshots) # time, lef_id, left_pos, right_pos, mobilities
import { createLattice, createModel, init, populate, Sim } from "lefsim";
await init(); // load the WebAssembly module
const lattice = createLattice(1000, [
{ site: 300, capturesFrom: "right", strength: 0.9 },
{ site: 700, capturesFrom: "left", strength: 0.9 },
]);
const model = createModel(populate(lattice, 10, { seed: 1 }));
using sim = new Sim(model, { seed: 42 });
sim.runUntil(1000);
const { leftPos, rightPos } = sim.state(); // views into wasm memory
Next, the LEF model explains what happens during that run.