Skip to content

cli

dreem.cli

DREEM CLI - Global Tracking Transformer for biological multi-object tracking.

Functions:

Name Description
build_config

Build config with priority: defaults < config_file < cli_args.

convert

Convert external tracking formats to .slp files.

load_default_config

Load default config for a command.

main

DREEM: Global Tracking Transformer for biological multi-object tracking.

print_config

Print config summary as Rich table and optionally save to YAML.

train

Train a DREEM model.

build_config(command, config_file, overrides, **cli_args)

Build config with priority: defaults < config_file < cli_args.

Source code in dreem/cli.py
def build_config(
    command: str,
    config_file: Path | None,
    overrides: list[str] | None,
    **cli_args,
) -> DictConfig:
    """Build config with priority: defaults < config_file < cli_args."""
    cfg = load_default_config(command)

    if config_file:
        user_cfg = OmegaConf.load(config_file)
        cfg = OmegaConf.merge(cfg, user_cfg)

    if overrides:
        cfg = OmegaConf.merge(cfg, OmegaConf.from_dotlist(overrides))

    for key, value in cli_args.items():
        if value is not None:
            OmegaConf.update(cfg, key, value, merge=True)

    return cfg

convert(format, labels=None, videos=None, output=Path('.'), to_npy=False, to_mp4=False)

Convert external tracking formats to .slp files.

Usage: dreem convert trackmate -l labels1.csv -l labels2.csv -v video1.tif -v video2.tif

Source code in dreem/cli.py
@app.command()
def convert(
    format: Annotated[
        str, typer.Argument(help="Source format to convert from (e.g. 'trackmate')")
    ],
    labels: Annotated[
        list[Path] | None,
        typer.Option("--labels", "-l", help="Paths to label files (CSV/XLSX)"),
    ] = None,
    videos: Annotated[
        list[Path] | None,
        typer.Option("--videos", "-v", help="Paths to video files (TIF, ND2, etc.)"),
    ] = None,
    output: Annotated[
        Path,
        typer.Option("--output", "-o", help="Output directory for converted files"),
    ] = Path("."),
    to_npy: Annotated[
        bool,
        typer.Option("--to-npy", "-n", help="Convert TIF videos to .npy format"),
    ] = False,
    to_mp4: Annotated[
        bool,
        typer.Option("--to-mp4", "-m", help="Convert videos to .mp4 format"),
    ] = False,
) -> None:
    """Convert external tracking formats to .slp files.

    Usage: dreem convert trackmate -l labels1.csv -l labels2.csv -v video1.tif -v video2.tif
    """
    supported_formats = ["trackmate"]
    if format not in supported_formats:
        console.print(
            f"[red]Error: Unknown format '{format}'. "
            f"Supported formats: {', '.join(supported_formats)}[/red]"
        )
        raise typer.Exit(1)

    if not labels or not videos:
        console.print("[red]Error: Both --labels and --videos are required.[/red]")
        raise typer.Exit(1)

    if format == "trackmate":
        from dreem.utils.convert import convert_trackmate

        convert_trackmate(
            label_files=[str(f) for f in labels],
            vid_files=[str(f) for f in videos],
            out_dir=str(output),
            to_npy=to_npy,
            to_mp4=to_mp4,
        )

    console.print("[green]Conversion complete.[/green]")

load_default_config(command)

Load default config for a command.

Source code in dreem/cli.py
def load_default_config(command: str) -> DictConfig:
    """Load default config for a command."""
    config_path = Path(__file__).parent / "configs" / "defaults" / f"{command}.yaml"
    return OmegaConf.load(config_path)

main(version=typer.Option(None, '--version', '-v', callback=version_callback, is_eager=True, help='Show version and exit.'))

DREEM: Global Tracking Transformer for biological multi-object tracking.

Source code in dreem/cli.py
@app.callback()
def main(
    version: bool = typer.Option(
        None,
        "--version",
        "-v",
        callback=version_callback,
        is_eager=True,
        help="Show version and exit.",
    ),
) -> None:
    """DREEM: Global Tracking Transformer for biological multi-object tracking."""
    pass

print_config(cfg, title='Configuration', save_path=None)

Print config summary as Rich table and optionally save to YAML.

Source code in dreem/cli.py
def print_config(
    cfg: DictConfig,
    title: str = "Configuration",
    save_path: Path | None = None,
) -> None:
    """Print config summary as Rich table and optionally save to YAML."""
    table = Table.grid(padding=(0, 2))
    table.add_column(style="bold cyan")
    table.add_column()

    # Save to YAML if save_path is provided
    if save_path:
        save_path.parent.mkdir(parents=True, exist_ok=True)
        with open(save_path, "w") as f:
            OmegaConf.save(cfg, f)
        console.print(f"[green]Configuration saved to: {save_path}[/green]")

    # Show only key settings (backward compatible)
    if OmegaConf.select(cfg, "ckpt_path"):
        table.add_row("Checkpoint:", str(cfg.ckpt_path))
    if OmegaConf.select(cfg, "outdir"):
        table.add_row("Output:", str(cfg.outdir))
    if OmegaConf.select(cfg, "dataset.test_dataset.dir.path"):
        table.add_row("Input:", str(cfg.dataset.test_dataset.dir.path))

    console.print(Panel(table, title=title))

train(train_dir, val_dir, crop_size, video_type='mp4', epochs=20, lr=0.0001, d_model=128, nhead=1, num_encoder_layers=1, num_decoder_layers=1, anchor='centroid', clip_length=32, gpu=True, config=None, logger=None, run_name='dreem_train', set_=None, quiet=False, verbose=False)

Train a DREEM model.

Source code in dreem/cli.py
@app.command()
def train(
    train_dir: Annotated[Path, typer.Argument(help="Training data directory")],
    val_dir: Annotated[
        Path, typer.Option("--val-dir", "-vd", help="Validation data directory")
    ],
    crop_size: Annotated[
        int | None, typer.Option("--crop-size", "-cs", help="Crop size")
    ],
    video_type: Annotated[
        str | None,
        typer.Option(
            "--video-type",
            "-vt",
            help="Raw video file extension: For masks, use tif or tiff. For videos, use mp4, avi, mov, mkv, wmv, m4v, m4a",
        ),
    ] = "mp4",
    epochs: Annotated[
        int | None, typer.Option("--epochs", "-e", help="Max epochs")
    ] = 20,
    lr: Annotated[float | None, typer.Option("--lr", help="Learning rate")] = 0.0001,
    d_model: Annotated[
        int | None, typer.Option("--d-model", help="Model dimension")
    ] = 128,
    nhead: Annotated[
        int | None, typer.Option("--nhead", help="Number of attention heads")
    ] = 1,
    num_encoder_layers: Annotated[
        int | None, typer.Option("--encoder-layers", help="Encoder layers")
    ] = 1,
    num_decoder_layers: Annotated[
        int | None, typer.Option("--decoder-layers", help="Decoder layers")
    ] = 1,
    anchor: Annotated[
        str | None, typer.Option("--anchor", "-a", help="Anchor type")
    ] = "centroid",
    clip_length: Annotated[
        int | None, typer.Option("--clip-length", "-cl", help="Clip length")
    ] = 32,
    gpu: Annotated[
        bool, typer.Option("--gpu/--no-gpu", "-g", help="Use GPU for training")
    ] = True,
    config: Annotated[
        Path | None,
        typer.Option("--config", "-c", help="Config file (overrides defaults)"),
    ] = None,
    logger: Annotated[
        str | None,
        typer.Option(
            "--logger",
            "-l",
            help="Logger type (any Lightning logger e.g. WandbLogger, TensorBoardLogger)",
        ),
    ] = None,
    run_name: Annotated[
        str | None,
        typer.Option(
            "--run-name",
            "-rn",
            help="Name of model run (creates subdirectory ./models/run_name)",
        ),
    ] = "dreem_train",
    set_: Annotated[
        list[str] | None, typer.Option("--set", "-s", help="Config overrides")
    ] = None,
    quiet: Annotated[
        bool, typer.Option("--quiet", "-q", help="Suppress progress output")
    ] = False,
    verbose: Annotated[
        bool, typer.Option("--verbose", help="Enable verbose logging")
    ] = False,
) -> None:
    """Train a DREEM model."""
    if verbose:
        logging.getLogger("dreem").setLevel(logging.INFO)

    if not train_dir.exists():
        console.print(f"[red]Error: Training directory not found: {train_dir}[/red]")
        raise typer.Exit(1)

    if not val_dir.exists():
        console.print(f"[red]Error: Validation directory not found: {val_dir}[/red]")
        raise typer.Exit(1)

    cli_overrides = {
        "dataset.train_dataset.dir.path": str(train_dir),
        "dataset.val_dataset.dir.path": str(val_dir),
        "dataset.train_dataset.dir.labels_suffix": f".{video_type}"
        if "tif" in video_type
        else ".slp",
        "dataset.val_dataset.dir.labels_suffix": f".{video_type}"
        if "tif" in video_type
        else ".slp",
        "dataset.train_dataset.dir.vid_suffix": f".{video_type}",
        "dataset.val_dataset.dir.vid_suffix": f".{video_type}",
        "trainer.max_epochs": epochs,
        "optimizer.lr": lr,
        "model.d_model": d_model,
        "model.nhead": nhead,
        "model.num_encoder_layers": num_encoder_layers,
        "model.num_decoder_layers": num_decoder_layers,
        "dataset.train_dataset.anchors": anchor,
        "dataset.val_dataset.anchors": anchor,
        "dataset.train_dataset.clip_length": clip_length,
        "dataset.train_dataset.crop_size": crop_size,
        "dataset.val_dataset.crop_size": crop_size,
        "logging.name": run_name,
        "logging.logger_type": logger,
        "trainer.accelerator": "cpu" if gpu is False else "gpu",
        "logging.name": run_name,
    }

    cfg = build_config("train", config, set_, **cli_overrides)

    # Determine save path for config YAML
    save_path = None
    save_dir = Path("./logs")
    save_dir.mkdir(parents=True, exist_ok=True)
    timestamp = get_timestamp()
    run_name = OmegaConf.select(cfg, "logging.name") or "train"
    save_path = save_dir / f"config.{run_name}.{timestamp}.yaml"

    from dreem.training.train import run as run_training

    if not quiet:
        print_config(cfg, "Train Configuration", save_path=save_path)
        console.print("[cyan]Starting training...[/cyan]")

    run_training(cfg)
    console.print("[green]Training complete.[/green]")