Converts segmented shape definitions (multi-label NRRD mask) and point sets (MPS) into physical vector polygons formatted for specific mass spectrometry imaging (MSI) instrument interfaces.
Supported formats:
| Format | Instrument | Use case |
|---|---|---|
xml |
Leica LMD | Laser microdissection |
csv |
MMI (Molecular Machines & Industries) | Laser microdissection |
mis |
Bruker flexImaging | MALDI imaging |
- Docker (recommended) — must be installed and running.
- Python 3.11+ (optional, for local use) — install dependencies via
pip install -r requirements.txt.
docker build -t shape2instrument:latest .The image is ~370 MB (slim Debian base, no OpenGL dependencies).
Mount your data directory so the container can read inputs and write results:
docker run --rm -v "${PWD}:/data" shape2instrument:latest [arguments]| Argument | Description |
|---|---|
--mask |
Path to the input multi-label .nrrd image mask |
--output |
Output directory inside the mounted volume |
--format |
Target format: xml, csv, or mis |
| Argument | Required for | Description |
|---|---|---|
--mps |
csv, xml |
Path to the .mps calibration points file (3-point set) |
--mis_template |
mis |
Path to a template .mis file (Bruker slide optical mappings) |
| Argument | Default | Description |
|---|---|---|
--cap_ids |
auto-generated | Comma-separated capture IDs, one per unique label in the mask |
--mis_image |
mask.tif |
Image filename for flexImaging (mis format only) |
--mis_raster |
20,20 |
Raster spacing in µm for flexImaging (mis format only) |
--offset_x |
0.0 |
X offset |
--offset_y |
0.0 |
Y offset |
--scale |
1.0 |
Global scaling factor |
--invert_x |
1.0 |
X invert factor (-1.0 to mirror) |
--invert_y |
1.0 |
Y invert factor (-1.0 to mirror) |
Capture IDs label each segment group in the output. They work identically for both xml and csv formats.
- One ID per unique label — the NRRD mask contains labeled regions (e.g., label 2 = tumor, label 3 = stroma). You supply one capture ID per unique label.
- Auto-expansion — if a single label produces multiple disconnected contours, all of them get the same capture ID.
- Auto-generation — if
--cap_idsis omitted, IDs are generated automatically using the 96-well-plate naming convention:A1, B1, C1, ..., H1, A2, B2, ...
| Unique labels | --cap_ids |
Result |
|---|---|---|
| 1 | (omitted) | A1 → all segments |
| 2 | (omitted) | A1, B1 → one per label |
| 2 | TUMOR,STROMA |
Custom names, one per label |
| 46 | (omitted) | A1 through H6 (wraps columns) |
XML — each <Shape_N> contains a <CapID> element.
CSV — each segment group is labelled with # Group: <cap_id>:
# reference 0
1.1203,1.2922
# reference 1
43.7406,1.3146
# reference 2
43.6189,15.1379
# Group: A1
18.24,5.92
18.28,5.92
18.28,5.98
18.24,5.98
# Group: A1
18.20,5.00
18.24,5.00docker run --rm \
-v "${PWD}:/data" \
shape2instrument:latest \
--mask /data/01-labels.nrrd \
--mps /data/pointset.mps \
--output /data/results \
--format xml \
--cap_ids TUMOR,STROMAdocker run --rm \
-v "${PWD}:/data" \
shape2instrument:latest \
--mask /data/01-labels.nrrd \
--mps /data/pointset.mps \
--output /data/results \
--format xmldocker run --rm \
-v "${PWD}:/data" \
shape2instrument:latest \
--mask /data/01-labels.nrrd \
--mps /data/pointset.mps \
--output /data/results \
--format csv \
--cap_ids TUMOR,STROMAdocker run --rm \
-v "${PWD}:/data" \
shape2instrument:latest \
--mask /data/01-labels.nrrd \
--mps /data/pointset.mps \
--output /data/results \
--format csvdocker run --rm \
-v "${PWD}:/data" \
shape2instrument:latest \
--mask /data/01-labels.nrrd \
--mis_template "/data/Bruker_Slide_Template.mis" \
--output /data/results \
--format mis \
--mis_image "mask.tif" \
--mis_raster 20,20from main import extract_segments_from_nrrd, parse_mps_calibration
from shape2xml_v2 import shape2xml
from shape2csv_v2 import shape2csv
# 1. Extract segments from NRRD
segments, segment_labels, valid_labels = extract_segments_from_nrrd(
"examples/01_tic_tenzl-labels.nrrd", physical_space=True
)
# 2. Parse calibration points
calib = parse_mps_calibration("examples/PointSet.mps")
# 3. Generate XML (auto-generated well-plate IDs)
shape2xml(segments, calibration_points=calib, folder_name="example_results")
# 4. Generate CSV (custom capture IDs)
shape2csv(segments, calib, capture_ids=["TUMOR", "STROMA"], folder_name="example_results")| File | Purpose |
|---|---|
main.py |
CLI entry point, argument parsing, segment extraction |
shape2xml_v2.py |
Leica XML export |
shape2csv_v2.py |
MMI CSV export |
mis_maker_class.py |
Bruker MIS export |
utils.py |
Shared utilities (e.g., well-plate ID generation) |
Dockerfile |
Container definition |
examples/ |
Sample NRRD mask and MPS calibration |
example_results/ |
Generated output files |