Expand description
§imodfile
Decode, encode, and inspect IMOD model files — from Rust and Python.
Read and write .mod files used by the IMOD
electron microscopy toolkit, in both binary and ASCII formats.
§Install
§Rust crate
cargo add imodfile§Python package
pip install git+https://github.com/elemeng/imodfile.git
# Or build from source:
pip install maturin
maturin build --features python
pip install target/wheels/imodfile-*.whl§CLI tool
cargo install imodfile§Quick start (Rust)
use imodfile::Imod;
let model = Imod::load("cells.mod").unwrap();
println!("{} objects, {} views", model.obj.len(), model.view.len());
// Iterate over every point with indices
for (oi, ci, pi, pt) in model.points() {
println!("[obj {oi}][cont {ci}][pt {pi}] {} {} {}", pt.x, pt.y, pt.z);
}
// Dump all points as text
model.save_points("points.txt").unwrap();
// Save back as binary or ASCII (chosen by extension)
model.save("output.mod").unwrap();
model.save("output.txt").unwrap();§Quick start (Python)
import imodfile
import numpy as np
model = imodfile.load("cells.mod")
print(model.name, model.image_size)
for obj in model.objects:
for cont in obj.contours:
pts = cont.points # (N, 3) float32 array
xs, ys, zs = pts[:, 0], pts[:, 1], pts[:, 2]
# Create new objects and contours
obj = model.add_object()
obj.name = "mitochondria"
obj.color = (1.0, 0.0, 0.0)
cont = obj.add_contour()
cont.points = np.array([[0,0,0],[1,0,0],[0,1,0]], dtype=np.float32)
model.save("output.mod")
model.save("output.txt") # ASCII format
model.save_points("points.txt") # point dump§Testing
# Full test suite (Rust + Python)
bash tests/test.sh
# Rust tests only
cargo test
# Python tests only (requires built wheel)
python -m pytest tests/test_python.py -v
# Property-based tests (randomized model generation)
cargo test --test proptests
# Fuzz the binary parser (runs indefinitely)
cargo fuzz run fuzz_binaryThe test suite covers:
| Suite | Tests |
|---|---|
| Rust integration | 13 tests — binary/ASCII round-trip, labels, point sizes, clip planes, views, edge cases, real-file round-trip |
| Property-based | 2 tests — randomized model generation verifies write→read consistency and field invariants |
| Doc-tests | 9 tests — API documentation examples that compile and run |
| Raw byte verification | Binary writer magic, tags, field layout, IEOF marker |
| Python bindings | 15 tests — load, read, create, modify, save, error handling, round-trip |
| Fuzz testing | cargo-fuzz target for the binary parser (crash-resistant input handling) |
The CI pipeline (GitHub Actions) runs all Rust tests, clippy (zero-warnings enforced), Python bindings build + pytest, and documentation build on every push and pull request.
§Data model
Imod (top-level model)
├── name, flags, pixsize, units
├── obj: Vec<Iobj>
│ ├── Iobj (object)
│ │ ├── name, color, flags, drawmode
│ │ ├── cont: Vec<Icont>
│ │ │ └── Icont (contour)
│ │ │ ├── pts: Vec<Ipoint> ← 3-D coordinates
│ │ │ ├── sizes, flags, time, surf
│ │ │ └── label, store
│ │ ├── mesh: Vec<Imesh>
│ │ │ └── Imesh (mesh)
│ │ │ ├── vert: Vec<Ipoint>
│ │ │ ├── list: Vec<i32> (indices + sentinels)
│ │ │ └── flag, time, surf
│ │ ├── clips: IclipPlanes
│ │ ├── label, mesh_param
│ │ └── store: Istore
│ └── ...
├── view: Vec<Iview> (camera positions)
├── slicer_angles: Vec<SlicerAngles>
├── ref_image: Option<IrefImage>
└── store: Istore
Ipoint { x: f32, y: f32, z: f32 }§Key types
Most users primarily work with Imod (model), Iobj (object), Icont (contour),
and Ipoint (3-D coordinate). All types, flag constants, and reader/writer
functions are re-exported at the crate root for convenience, and also available
under their respective modules for qualified access.
| Type | Description |
|---|---|
Imod / Model | Top-level model — image dimensions, transforms, views, objects |
Iobj / Object | A named object with colour, material, contours, and meshes |
Icont / Contour | A contour — open or closed series of Ipoints |
Imesh / Mesh | Triangle/quad mesh with vertex and index lists |
Ipoint | Single 3-D coordinate { x, y, z } |
For secondary types (Iview, IclipPlanes, Ilabel, Istore, ImeshParams,
IrefImage, SlicerAngles, flag constants, and the low-level
read_binary / write_binary / read_ascii / write_ascii functions),
import from imodfile::model or imodfile::binary / imodfile::ascii as needed.
§Rust API
| Use case | API |
|---|---|
| Load a file | Imod::load(path) — auto-detects binary vs ASCII |
| Save a file | model.save(path) — binary, or ASCII if path ends with .txt |
| Iterate points | model.points() → (obj, cont, pt, &Ipoint) |
| Format as text | model.to_points() → String |
| Write to writer | model.write_points(&mut writer) |
| Low-level read | read_binary(&mut reader) / read_ascii(&mut reader) |
| Low-level write | write_binary(&mut writer, &model) / write_ascii(...) |
§Python API
| Python | What it does |
|---|---|
imodfile.load(path) → Model | Load a file (auto-detect format) |
model.save(path) | Save (binary, or ASCII if .txt) |
model.objects → list[Object] | All objects |
obj.contours → list[Contour] | All contours in an object |
cont.points → ndarray(N, 3) | Point coordinates (read/write) |
cont.surface, cont.time, cont.flags | Contour metadata (read/write) |
obj.add_contour() → Contour | Create a new contour |
model.add_object() → Object | Create a new object |
The .pyi stub is bundled in the wheel for IDE autocomplete.
§CLI
imodfile <input.mod> # dump model info
imodfile <input.mod> <output.mod> # copy / convert
imodfile <input.mod> output.txt # convert to ASCII
imodfile <input.mod> output.txt --points # extract point coordinates
imodfile <input.mod> --points # print points to stdout§Format support
| Format | Read | Write |
|---|---|---|
| Binary (big-endian) | ✓ | ✓ |
| ASCII text | ✓ | ✓ |
| Legacy V0.1 | ✓ | — |
All chunk types are supported: objects, contours, meshes, materials, clip planes, labels, point sizes, views, slicer angles, reference transforms, meshing parameters, and general-purpose storage.
The binary parser is fuzz-tested via cargo-fuzz for crash-resistant handling of
arbitrary or corrupted input. Property-based tests with proptest verify write→read
round-trip correctness across randomly generated models.
§Read/write flow
┌──────────────────┐
│ imodfile crate │
└─────────┬────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Imod::load() │ │ Imod::save() │
│ / read() │ │ / write() │
└───────┬───────┘ └───────┬───────┘
│ │
┌───────┴───────┐ ┌───────┴───────┐
│ detect │ │ path ends │
│ format │ │ with .txt? │
└───────┬───────┘ └───────┬───────┘
│ │
┌───────┴───────┐ ┌───────┴───────┐
▼ ▼ ▼ ▼
┌──────┐ ┌──────────┐ ┌──────────┐ ┌──────┐
│binary│ │ ASCII │ │ ASCII │ │binary│
│reader│ │ reader │ │ writer │ │writer│
└──────┘ └──────────┘ └──────────┘ └──────┘
│ │ │ │
▼ ▼ ▼ ▼
.mod file .txt file .txt file .mod file
(binary) (ASCII) (ASCII) (binary)§Modules
| Crate module | Contents |
|---|---|
model | Data types — Imod, Iobj, Icont, Imesh, Ipoint, … |
binary | Binary format reader and writer |
ascii | ASCII format reader and writer |
chunk_ids | 4-byte magic constants |
error | ImodError / ImodResult |
store | General-purpose storage helpers |
§License
MIT — see LICENSE for the full text.
Re-exports§
pub use ascii::read_ascii;pub use ascii::write_ascii;pub use binary::read_binary;pub use binary::write_binary;pub use error::ImodError;pub use error::ImodResult;pub use model::IclipPlanes;pub use model::Icont;pub use model::Iindex;pub use model::Imesh;pub use model::ImeshParams;pub use model::Imod;pub use model::Iobj;pub use model::IobjPointsIter;pub use model::ImodPointsIter;pub use model::Iplane;pub use model::Ipoint;pub use model::IrefImage;pub use model::Istore;pub use model::IstoreItem;pub use model::Iview;pub use model::Ilabel;pub use model::IlabelItem;pub use model::SlicerAngles;pub use model::IMODF_FLIPYZ;pub use model::IMODF_HAS_MESH_THICK;pub use model::IMODF_MAT1_IS_BYTES;pub use model::IMODF_MULTIPLE_CLIP;pub use model::IMODF_NEW_TO_3DMOD;pub use model::IMODF_OTRANS_ORIGIN;pub use model::IMODF_ROT90X;pub use model::IMODF_TILTOK;pub use model::IMODF_Z_FROM_MINUSPT5;pub use model::IMOD_OBJFLAG_ANTI_ALIAS;pub use model::IMOD_OBJFLAG_DRAW_LABEL;pub use model::IMOD_OBJFLAG_FCOLOR;pub use model::IMOD_OBJFLAG_FCOLOR_PNT;pub use model::IMOD_OBJFLAG_FILL;pub use model::IMOD_OBJFLAG_MCOLOR;pub use model::IMOD_OBJFLAG_MESH;pub use model::IMOD_OBJFLAG_NOLINE;pub use model::IMOD_OBJFLAG_OFF;pub use model::IMOD_OBJFLAG_OPEN;pub use model::IMOD_OBJFLAG_OUT;pub use model::IMOD_OBJFLAG_PNT_ON_SEC;pub use model::IMOD_OBJFLAG_SCAT;pub use model::IMOD_OBJFLAG_SCALE_WDTH;pub use model::IMOD_OBJFLAG_TIME;pub use model::IMOD_OBJFLAG_TWO_SIDE;pub use model::IMOD_OBJFLAG_USE_VALUE;
Modules§
- ascii
- ASCII IMOD format reader and writer.
- binary
- chunk_
ids - Four-byte chunk IDs used in the IMOD binary format — all UPPERCASE.
- error
- model
- Data model types mirroring the IMOD C structures.
- python
- Python bindings (requires feature
python). PyO3 bindings for the imodfile library. - store
- General-purpose storage (Istore).