Command line¶
SMINT's command-line tools, generated from the parsers the commands actually use, so every option, default and choice on this page is the one the code accepts. Each command ends with a worked example; every example on this page is parsed by the real parser when the page is generated. A default of — means the option is unset unless you pass it: the command then falls back to the configuration file or to the built-in value named in the description.
| Command | How it is installed | What it does |
|---|---|---|
smint-alignment |
console script | Register spatial omics modalities: coarse pre-registration, same-section centroid registration and sequential-section STalign LDDMM. |
smint-register |
console script | Registration worker: runs one job spec and reports through status.json. |
python scripts/run_segmentation.py |
script in the repository | Segment cells and nuclei from a YAML configuration, in one process or distributed with Dask. |
smint-segment-distributed |
console script | Distributed whole-slide segmentation with Dask: tiles, workers, stitching and cell / nucleus reconciliation. |
smint-viewer |
console script | Tkinter window that follows a running segmentation tile by tile. |
How the registration commands fit together¶
smint-alignment never runs a registration in its own process. It writes a job
spec and hands it to a worker, on this machine or through SLURM, so the napari
plugin, the command line and Python all share one code path, and STalign
(which needs numpy < 2) stays in its own environment.
flowchart LR
A["smint-alignment st-sm / centroid"] -->|writes| B["job_spec.json"]
B --> C{"--submit?"}
C -- no --> D["local subprocess"]
C -- yes --> E["submit.sh via sbatch"]
D --> F["smint-register job_spec.json"]
E --> F
F -->|rewrites| G["status.json"]
F -->|writes| H["*_transformed.csv"]
A -. "--watch polls" .-> G
smint-alignment¶
smint-alignment builds a registration job and either runs it on this machine or submits it to SLURM (--submit). The st-sm and centroid subcommands write job_spec.json and status.json into --output-dir and launch the smint-register worker; pretransform and columns run immediately. See Data formats for every file these commands read and write.
Options
| Option | Default | Description |
|---|---|---|
-v, --verbose |
off | Debug logging |
smint-alignment st-sm¶
STalign LDDMM for sequential sections (needs manual landmarks).
smint-alignment st-sm [-h] --st ST --sm SM --st-points ST_POINTS --sm-points SM_POINTS
--output-dir OUTPUT_DIR [--dx DX] [--niter NITER] [--epv EPV]
[--orientation {dataset,stalign}] [--st-x-col ST_X_COL]
[--st-y-col ST_Y_COL] [--sm-x-col SM_X_COL] [--sm-y-col SM_Y_COL]
[--scale-xy SCALE_XY] [--rotate-left-90] [--no-keep-positive]
[--submit] [--watch] [--partition PARTITION] [--cpus CPUS]
[--memory MEMORY] [--time-limit TIME_LIMIT] [--gpus GPUS]
[--gpu-type GPU_TYPE] [--worker-python WORKER_PYTHON]
Options
| Option | Default | Description |
|---|---|---|
--st ST |
required | ST annotation CSV (target) |
--sm SM |
required | SM matrix CSV (source) |
--st-points ST_POINTS |
required | ST landmarks .npy |
--sm-points SM_POINTS |
required | SM landmarks .npy |
--output-dir OUTPUT_DIR |
required | Output directory |
--dx DX |
30.0 |
Raster pixel size (float) |
--niter NITER |
1000 |
LDDMM iterations (int) |
--epv EPV |
200.0 |
Velocity regularisation (float) |
--orientation {dataset,stalign} |
dataset |
Output frame: 'stalign' is x/y in the ST frame (overlays ST); 'dataset' reproduces historical outputs, transposed relative to ST |
--st-x-col ST_X_COL |
— | ST column to register (default: auto-detect) |
--st-y-col ST_Y_COL |
— | ST y column to register (default: auto-detect) |
--sm-x-col SM_X_COL |
— | SM column to register (default: the column named 'x') |
--sm-y-col SM_Y_COL |
— | SM y column to register (default: the column named 'y') |
--scale-xy SCALE_XY |
10.0 |
SM coordinate scaling (float) |
--rotate-left-90 |
off | Rotate SM 90 deg CCW |
--no-keep-positive |
off | Do not shift SM coordinates to be non-negative (use with --scale-xy 1 for a table already pre-registered into the ST frame) |
--submit |
off | Submit to SLURM |
--watch |
off | Block until finished |
SLURM (with --submit)
| Option | Default | Description |
|---|---|---|
--partition PARTITION |
regular |
SLURM partition |
--cpus CPUS |
8 |
CPUs per task (int) |
--memory MEMORY |
64G |
Memory request |
--time-limit TIME_LIMIT |
04:00:00 |
Walltime |
--gpus GPUS |
0 |
GPUs to request (int) |
--gpu-type GPU_TYPE |
A30 |
GPU type to request with --gpus (e.g. A30, A100); 'any' for any card |
--worker-python WORKER_PYTHON |
— | Interpreter for the worker; defaults to $SMINT_WORKER_PYTHON or an STalign_env beside the package |
Register a metabolomics section onto a Xenium section on a GPU node and wait for it to finish:
smint-alignment st-sm --st st_cells.csv --sm sm_matrix.csv --st-points landmarks_st_points.npy \
--sm-points landmarks_sm_points.npy --output-dir runs/st_sm --orientation stalign \
--submit --partition gpuq --gpus 1 --time-limit 01:00:00 --watch
Good to know
--st-points/--sm-pointsare landmark files in the point-annotator format (see Data formats); both must hold the same number of landmarks, at least 3, in the same order.- The worker needs an interpreter where STalign imports (numpy < 2). Point
--worker-pythonor$SMINT_WORKER_PYTHONat it. --orientation staligngives true x/y in the ST frame, so the result overlays the ST cells;dataset(the default) reproduces older outputs, which are transposed relative to ST.--submitwith--gpus 1needs a GPU partition (--partition); a GPU request on a CPU partition stays pending rather than failing.--gpu-type(default A30) must be a card that partition offers;anydrops the type.
smint-alignment centroid¶
Correspondence fitting for post-staining on the same section.
smint-alignment centroid [-h] --source SOURCE --target TARGET --output-dir OUTPUT_DIR
[--method {multiround,affine,ransac,tps,ransac+tps}]
[--max-distance MAX_DISTANCE]
[--validation-fraction VALIDATION_FRACTION]
[--n-control N_CONTROL] [--tps-regularization TPS_REGULARIZATION]
[--no-refine] [--snap-radius SNAP_RADIUS] [--no-assign-remaining]
[--source-cols X Y] [--target-cols X Y] [--submit] [--watch]
[--partition PARTITION] [--cpus CPUS] [--memory MEMORY]
[--time-limit TIME_LIMIT] [--gpus GPUS] [--gpu-type GPU_TYPE]
[--worker-python WORKER_PYTHON]
Options
| Option | Default | Description |
|---|---|---|
--source SOURCE |
required | Source centroid CSV (moving) |
--target TARGET |
required | Target centroid CSV (fixed) |
--output-dir OUTPUT_DIR |
required | Output directory |
--method {multiround,affine,ransac,tps,ransac+tps} |
multiround |
Registration model; multiround is recommended (see Choosing a registration method) |
--max-distance MAX_DISTANCE |
100.0 |
Correspondence cutoff, coordinate units (float) |
--validation-fraction VALIDATION_FRACTION |
0.25 |
Pairs held out from fitting; 0 makes the reported TRE meaningless (float) |
--n-control N_CONTROL |
1000 |
TPS control points (int) |
--tps-regularization TPS_REGULARIZATION |
— | Default: 1000 for multiround, 1 for the single-round methods (float) |
--no-refine |
off | Skip snapping matched nuclei onto their cells |
--snap-radius SNAP_RADIUS |
10.0 |
Refinement: maximum nucleus-cell distance for snapping (float) |
--no-assign-remaining |
off | Refinement: leave nuclei that fail the neighbourhood check filled, instead of assigning them to the nearest free cell |
--source-cols X Y |
— | x and y columns in --source (default: the first of x_centroid/y_centroid, centroid_x/centroid_y, x/y present) |
--target-cols X Y |
— | x and y columns in --target (default: as --source-cols) |
--submit |
off | Submit to SLURM |
--watch |
off | Block until finished |
SLURM (with --submit)
| Option | Default | Description |
|---|---|---|
--partition PARTITION |
regular |
SLURM partition |
--cpus CPUS |
8 |
CPUs per task (int) |
--memory MEMORY |
64G |
Memory request |
--time-limit TIME_LIMIT |
04:00:00 |
Walltime |
--gpus GPUS |
0 |
GPUs to request (int) |
--gpu-type GPU_TYPE |
A30 |
GPU type to request with --gpus (e.g. A30, A100); 'any' for any card |
--worker-python WORKER_PYTHON |
— | Interpreter for the worker; defaults to $SMINT_WORKER_PYTHON or an STalign_env beside the package |
Register segmented nuclei onto Xenium cells from the same section (multiround + snapping refinement, the defaults), on this machine:
smint-alignment centroid --source nuclei_centroids.csv --target xenium_cells.csv \
--output-dir runs/centroid --watch
Good to know
- Without
--source-cols/--target-cols, each file's columns are the first pair present ofx_centroid y_centroid,centroid_x centroid_yandx y; if none is, the worker stops andstatus.jsonreportsfailed. - Only the validation TRE (
tre_validationinstatus.json) is meaningful; keep--validation-fractionabove 0. - The
centroidround has no STalign dependency and runs in any SMINT environment.
smint-alignment pretransform¶
Coarse scale / rotate / flip before fine registration.
smint-alignment pretransform [-h] --source SOURCE --target TARGET --output OUTPUT
[--rotation ROTATION] [--flip-x] [--flip-y]
[--scale-mode {extent,max,none}] [--anisotropic] [--search]
Options
| Option | Default | Description |
|---|---|---|
--source SOURCE |
required | Source CSV to transform |
--target TARGET |
required | Reference CSV defining the frame |
--output OUTPUT |
required | Transformed CSV to write |
--rotation ROTATION |
0.0 |
Degrees counter-clockwise (float) |
--flip-x |
off | Mirror horizontally |
--flip-y |
off | Mirror vertically |
--scale-mode {extent,max,none} |
extent |
How the scale is fitted to the target: bounding-box span (extent), maximum coordinate (max) or not at all (none) |
--anisotropic |
off | Allow per-axis scaling (may distort tissue shape) |
--search |
off | Grid-search rotation and flips by overlap score |
Rotate a metabolomics grid by 90 degrees, scale it to the Xenium extent and centre it on the Xenium cells:
smint-alignment pretransform --source sm_matrix.csv --target xenium_cells.csv \
--rotation 90 --output sm_pre.csv
Let SMINT search rotations (15-degree steps) and flips by overlap:
smint-alignment pretransform --source sm_matrix.csv --target xenium_cells.csv \
--search --output sm_pre.csv
Output of the first example on a synthetic grid rotated by -90 degrees and stored at one tenth of the target's scale:
scale : 10.0205, 10.0205
rotation : 90.00 deg
reflects : False
overlap : 0.997
wrote : sm_pre.csv
transform : sm_pre.csv.transform.json
Good to know
- Coordinate columns are auto-detected in both files (see column priority); the detected source columns are overwritten in the output CSV, every other column is kept.
- The 3x3 matrix and its decomposition are saved next to the output as
<output>.transform.json. - Operations are applied flip, then rotate, then scale, about the source centroid, then the source centroid is moved onto the target centroid.
smint-alignment columns¶
List a CSV's columns and the auto-detected pair.
Positional arguments
| Option | Default | Description |
|---|---|---|
file |
required | CSV to inspect |
See which coordinate columns SMINT would pick:
Output on a small synthetic matrix with columns x, y, 72.0796, 88.0399:
Good to know
- Reads only the header, so it is instant even on a 450 MB metabolomics matrix.
smint-register¶
You rarely call smint-register yourself: smint-alignment, the napari plugin and smint.alignment.jobs.submit launch it, locally or inside an sbatch script, as <worker python> -m smint.cli.register <output_dir>/job_spec.json. Run it by hand to re-run a job from its spec or to debug a failed job in the foreground.
Positional arguments
| Option | Default | Description |
|---|---|---|
spec |
required | Path to job_spec.json |
Options
| Option | Default | Description |
|---|---|---|
-v, --verbose |
off | Enable debug logging |
Re-run a job in the foreground with debug logging:
Good to know
- Exit status: 0 completed, 1 the registration failed (the traceback is in
status.json), 2 the spec could not be read.
python scripts/run_segmentation.py¶
scripts/run_segmentation.py merges a YAML configuration with the flags below and runs either the single-process tiler (process_large_image) or, with --distributed, the Dask pipeline (run_distributed_segmentation). It ships in the repository rather than as a console script, so run it from a checkout. Every configuration key is described in Configuration.
python scripts/run_segmentation.py [-h] --image IMAGE --output-dir OUTPUT_DIR
[--config CONFIG] [--distributed] [--use-gpu | --no-gpu]
[--cell-model CELL_MODEL] [--nuclei-model NUCLEI_MODEL]
[--cell-diameter CELL_DIAMETER]
[--nuclei-diameter NUCLEI_DIAMETER]
[--chunk-size CHUNK_SIZE CHUNK_SIZE] [--visualize]
[--live-viewer] [--debug] [--save-config]
Options
| Option | Default | Description |
|---|---|---|
--image IMAGE |
required | Path to the input image file |
--output-dir OUTPUT_DIR |
required | Directory to save segmentation results |
--config CONFIG |
— | Path to configuration file |
--distributed |
off | Run segmentation in distributed mode using Dask |
--use-gpu |
off | Use the GPU (default: the config file, else use one if available) |
--no-gpu |
off | Run on the CPU even if a GPU is available |
--cell-model CELL_MODEL |
— | Path to cell segmentation model |
--nuclei-model NUCLEI_MODEL |
— | Path to nuclei segmentation model |
--cell-diameter CELL_DIAMETER |
— | Diameter of cells for segmentation (float) |
--nuclei-diameter NUCLEI_DIAMETER |
— | Diameter of nuclei for segmentation (float) |
--chunk-size CHUNK_SIZE CHUNK_SIZE |
— | Size of chunks for processing (height width); default from config, else 2048 2048 (int) |
--visualize |
off | Enable visualization |
--live-viewer |
off | Enable live viewer |
--debug |
off | Enable debug logging |
--save-config |
off | Save effective configuration to a file |
Single process, models and diameters on the command line:
python scripts/run_segmentation.py --image slide.ome.tif --output-dir results/seg \
--config configs/segmentation_config.yaml --cell-model cyto3 --nuclei-model nuclei \
--cell-diameter 60 --nuclei-diameter 25
Distributed over Dask workers, everything from the configuration file:
python scripts/run_segmentation.py --image slide.ome.tif --output-dir results/seg \
--config my_config.yaml --distributed
Good to know
- Without
--configthe script looks for./configs/segmentation_config.yaml, then~/.smint/config.yaml, then the repository's ownconfigs/segmentation_config.yaml. The run stops if nomodel_pathsis set by the file or the flags. - The model, diameter and GPU flags apply with and without
--distributed. Without--configor model flags, the distributed run falls back to the built-incyto/nucleimodels with Cellpose defaults. --cell-modeland--nuclei-modeleach replace only their own entry of the config'smodel_paths([cell, nuclei]), so you can override one and keep the other from the file.--use-gpu/--no-gpuoverrideuse_gpufrom the file. With neither, distributed runs default to GPU workers and single-process runs use the GPU whenever Cellpose finds one.--save-configwrites the merged configuration to<output-dir>/segmentation_config.yaml.
smint-segment-distributed¶
The direct entry point to the distributed pipeline. Flags override the YAML file given by --config_path, which overrides the built-in defaults (see Configuration). Workers read the image themselves, so it must be on storage every worker can see. Needs pip install 'smint[distributed]' and Cellpose.
smint-segment-distributed [-h] --image_path IMAGE_PATH --output_dir OUTPUT_DIR
[--config_path CONFIG_PATH] [--backend {local,slurm}]
[--scheduler_address SCHEDULER_ADDRESS] [--n_workers N_WORKERS]
[--use_gpu | --no_gpu] [--tile_size TILE_SIZE]
[--tile_overlap TILE_OVERLAP] [--cell_model CELL_MODEL]
[--nuclei_model NUCLEI_MODEL] [--slurm_gpu_type SLURM_GPU_TYPE]
[--tile_info_path TILE_INFO_PATH]
[--live_update_image_path LIVE_UPDATE_IMAGE_PATH]
Options
| Option | Default | Description |
|---|---|---|
--image_path IMAGE_PATH |
required | Zarr/OME-Zarr store or TIFF/OME-TIFF |
--output_dir OUTPUT_DIR |
required | Output directory |
--config_path CONFIG_PATH |
— | YAML configuration file |
--backend {local,slurm} |
— | Where workers run (default: local) |
--scheduler_address SCHEDULER_ADDRESS |
— | Connect to an existing Dask scheduler |
--n_workers N_WORKERS |
— | Number of workers (int) |
--use_gpu |
off | Use GPU workers (default: the config file, else yes) |
--no_gpu |
off | Use CPU workers |
--tile_size TILE_SIZE |
— | Core tile size in pixels (default 2048) (int) |
--tile_overlap TILE_OVERLAP |
— | Tile overlap in pixels (default 256) (int) |
--cell_model CELL_MODEL |
— | Cell model name or path |
--nuclei_model NUCLEI_MODEL |
— | Nuclei model name or path |
--slurm_gpu_type SLURM_GPU_TYPE |
— | SLURM GPU type, e.g. A30; other SLURM options come from the config |
--tile_info_path TILE_INFO_PATH |
— | Tile-info file for the live viewer |
--live_update_image_path LIVE_UPDATE_IMAGE_PATH |
— | PNG updated as tiles finish |
Four SLURM GPU workers, each on an A30:
smint-segment-distributed --image_path slide.ome.tif --output_dir results/dist \
--config_path my_config.yaml --backend slurm --n_workers 4 --slurm_gpu_type A30
CPU-only on this machine, a quick test on a crop:
smint-segment-distributed --image_path crop.ome.tif --output_dir results/test \
--config_path my_config.yaml --no_gpu --tile_size 1024
Good to know
--use_gpu/--no_gpuforce GPU workers on or off; with neither,use_gpufrom the configuration applies (default on).--tile_overlapmust exceed the radius of the largest cell, so every boundary cell is seen whole by at least one tile.--slurm_gpu_typesetsgpu_typeand keeps the other options of the configuration'sdistributed.slurmsection.- Outputs:
cells_outlines.csv,nuclei_outlines.csv,cells_summary.csv,nuclei_summary.csv,cells.zarr,nuclei.zarrand a timestamped log (see Data formats).
smint-viewer¶
Shows the whole scan with the tile currently being segmented and its latest segmentation image, refreshed on a timer. It reads the tile-info file a segmentation run writes when tile_info_path / live_update_image_path are set (or run_segmentation.py --live-viewer). Needs a display and Pillow.
smint-viewer [-h] [--interval INTERVAL]
full_scan_image_path segmentation_history_dir tile_info_path
Positional arguments
| Option | Default | Description |
|---|---|---|
full_scan_image_path |
required | Path to the full tile scan image (e.g., whole_slide.tif). |
segmentation_history_dir |
required | Directory containing segmentation results (PNG or TIFF files). |
tile_info_path |
required | Path to a text file containing current tile coordinates and scan dimensions. |
Options
| Option | Default | Description |
|---|---|---|
--interval INTERVAL |
1000 |
Update interval in milliseconds. Default: 1000ms (int) |
Follow a run started with run_segmentation.py --live-viewer --output-dir results/seg:
Good to know
- The tile-info file is one line,
y,x,tile_height,tile_width,scan_height,scan_width,image_name(see Data formats).