Command Line Interface
EVAnalyzer can be driven entirely from the command line via the evanalyzer cli subcommand, enabling headless batch processing, integration into automated workflows, and remote execution on servers - no GUI/display required.
Overview
Section titled “Overview”The same evanalyzer binary handles both modes:
# Linux./evanalyzer # launch the GUI./evanalyzer cli <command> [options...] # run a one-shot CLI command and exit
# Windowsevanalyzer.exe cli <command> [options...]| Command | Purpose |
|---|---|
analyze | Run a project’s enabled pipelines over its images and write a new results database |
project-info | Print a project’s images, classes, and pipelines without running anything |
validate | Check that every image referenced by a project can be found on disk |
view | Print a quick summary and a page of rows from a results database |
columns | List the column ids available for grouping/chart axes in a results database |
export | Export a results database to CSV, XLSX, or a chart image |
Every command supports --help:
./evanalyzer cli analyze --helpanalyze
Section titled “analyze”Runs a project’s enabled pipelines over its images and writes a new results database.
./evanalyzer cli analyze --project settings.improj| Argument | Description |
|---|---|
--project <path> | Project file to analyze (required) |
--images <dir> | Scan this directory and use it as the project’s image root before running. If omitted, the project’s already-saved image list is used as-is |
--threads <n> | Number of images to process in parallel. If omitted, EVAnalyzer picks the highest thread count that fits within available RAM and CPU cores |
The parallelism is automatically capped to whichever is lower — the number of CPU cores or the number of images that fit in available RAM — so a low-memory machine never launches more parallel workers than it can sustain.
The command prints a progress line per image as it completes, then a summary:
Project: settings.improjImages: 48Pipelines: 1 enabledOutput: ./evanalyzer/EV DetectionRunning with 7 parallel thread(s)...
[48/48] /data/plate1/A1_01.tifDone: 48 image(s) analyzed in 32.4s (0 failed)Results database written under: ./evanalyzer/EV DetectionA project with no images (and no --images override) fails fast with an error instead of running.
Press Ctrl+C to request a graceful stop; in-flight images will finish before the process exits.
project-info
Section titled “project-info”Prints a project’s image count, classes, and pipelines without running anything - useful for sanity-checking a project file before kicking off a long batch run.
./evanalyzer cli project-info --project settings.improj| Argument | Description |
|---|---|
--project <path> | Project file to inspect (required) |
--json | Emit machine-readable JSON instead of human-readable text |
Project: settings.improjName: EV detection screenImage root: /data/plate1Images: 48Reachable: yes
Classes (3): - dapi@nucleus - cy5@spot - cy7@spot
Pipelines (1): - EV Detection [enabled] - 8 step(s)If the configured image root can’t be found on disk, Reachable reports why instead of just “no”.
validate
Section titled “validate”Checks that every image referenced by a project can be found on disk. Useful as a pre-flight step before starting a long headless run.
./evanalyzer cli validate --project settings.improj| Argument | Description |
|---|---|
--project <path> | Project file to check (required) |
The command exits with a non-zero status code if any images are missing, making it suitable for use in CI scripts:
./evanalyzer cli validate --project settings.improj && \ ./evanalyzer cli analyze --project settings.improjResults Database
Section titled “Results Database”analyze writes results to a results.evadb file (DuckDB format) under the project’s job folder - the same file the GUI’s Results view opens. view, columns, and export all read from this file via --db.
duckdb results.evadb "SELECT object_class_name, COUNT(*) FROM objects GROUP BY object_class_name"Prints a database summary (image/class counts, T/Z-stack ranges) followed by a paginated, human-readable table of per-object rows - a quick terminal preview without exporting anything.
./evanalyzer cli view --db results.evadb --limit 10| Argument | Description |
|---|---|
--db <path> | Results database produced by analyze (required) |
--page <n> | Zero-based page index (default 0) |
--limit <n> | Rows per page (default 25) |
--channels | Also show per-channel intensity columns |
--json | Emit machine-readable JSON instead of human-readable text |
--image <name> | Restrict to this image name (repeatable) |
--class <name> | Restrict to this object class (repeatable) |
columns
Section titled “columns”Lists every column id available in a results database - including per-channel intensity columns and per-partner-class colocalization counts - grouped the same way as the GUI’s Columns picker (General, Geometry, Shape, Coloc, Intensity).
./evanalyzer cli columns --db results.evadb| Argument | Description |
|---|---|
--db <path> | Results database to inspect (required) |
--json | Emit machine-readable JSON instead of the formatted table |
ID LABEL GROUPobject_id Object ID Generalimage_name Image Generalobject_class_name Class Generalcount Count Generalarea_px Area [px] Geometryarea_nm2 Area [nm²] Geometrycircularity Circularity Shapesolidity Solidity Shapeeccentricity Eccentricity Shapen_colocalized_class_ch2@spot Coloc with ch2@spot Colocmean_scaled_ch0 Avg Intensity (Ch 0) intensitysum_scaled_ch0 Sum Intensity (Ch 0) intensityRun this first when scripting export - column ids are the values to pass to --group-by-adjacent tooling and to duckdb queries against the same file.
export
Section titled “export”Exports a results database to CSV, XLSX, or Parquet, with the same filtering and (for image grouping) aggregation logic as the GUI’s Results List view. Chart image export (histogram/scatter/boxplot PNGs) isn’t wired up in the CLI yet - use the GUI’s Charts tab for those.
export csv / export xlsx
Section titled “export csv / export xlsx”./evanalyzer cli export csv --db results.evadb --out results.csv./evanalyzer cli export xlsx --db results.evadb --out results.xlsx \ --group-by image --agg avg,median| Argument | Description |
|---|---|
--db <path> | Results database to export (required) |
--out <path> | Output file path (required) |
| filter args | See Filter Arguments |
| group args | See Group Arguments |
export parquet
Section titled “export parquet”Writes the database’s raw objects table straight to a Parquet file via DuckDB’s own COPY ... TO ... (FORMAT parquet) - every column, completely unfiltered. There’s no column selection, image/class filtering, or grouping to apply (that’s the GUI’s Parquet export behavior too), so it takes a plainer set of arguments than csv/xlsx:
./evanalyzer cli export parquet --db results.evadb --out objects.parquet| Argument | Description |
|---|---|
--db <path> | Results database to export (required) |
--out <path> | Output file path (required) |
Filter Arguments
Section titled “Filter Arguments”Shared by view and every export subcommand:
| Argument | Description |
|---|---|
--image <name> | Restrict to this image name (repeatable) |
--class <name> | Restrict to this object class (repeatable) |
Group Arguments
Section titled “Group Arguments”Shared by export csv and export xlsx - mirrors the GUI’s Grouping and Aggregating Rows:
| Argument | Description |
|---|---|
--group-by <image|folder|regex> | Aggregate rows instead of exporting one row per object. Only image has a matching query today - folder/regex are recognized but currently rejected |
--agg <list> | Comma-separated aggregate function(s) applied to every numeric column when grouping: min, max, avg (default), median, stdev, sum |
--split-colocalized | Accepted but currently rejected - no row-level “is this object colocalized at all” split exists in the current backend |
--group-by-class | No-op when grouping by image - image grouping always splits by class already |
Project File
Section titled “Project File”The CLI operates on an EVAnalyzer project file (.improj). Create and configure the project using the GUI, save it, and then use the saved file for headless runs.
The project file is a JSON document - it can be modified programmatically using any scripting language.
Automated Parameter Variation
Section titled “Automated Parameter Variation”A common use case is running the same pipeline with multiple parameter sets. The project file can be modified by a script before each run.
Example: vary blur kernel size with Python
Section titled “Example: vary blur kernel size with Python”import jsonimport subprocess
def set_blur_kernel(filename, kernel_size): with open(filename) as f: data = json.load(f)
for pipeline in data.get("pipelines", []): for step in pipeline.get("steps", []): if step.get("command", {}).get("type") == "blur": step["command"]["kernelSize"] = kernel_size
with open(filename, "w") as f: json.dump(data, f, indent=2)
def run_analysis(project_file): subprocess.run( ["./evanalyzer", "cli", "analyze", "--project", project_file], check=True, )
for size in [3, 5, 7, 9]: set_blur_kernel("settings.improj", size) run_analysis("settings.improj") print(f"Finished kernel_size={size}")Project File Format
Section titled “Project File Format”The project file is a JSON document following the EVAnalyzer schema. Key top-level fields:
{ "metadata": { "name": "My experiment", ... }, "classification": { "classes": [...] }, "plate": { ... }, "images": { "root": "/path/to/images", "list": { ... } }, "pipelines": [ { "id": "...", "name": "EV Detection", "enabled": true, "imageSource": { ... }, "steps": [ { "enabled": true, "command": { "type": "rollingBall", "radius": 4.0, "ballType": "paraboloid" } }, ... ] } ]}File extensions
Section titled “File extensions”| Extension | Description |
|---|---|
.improj | EVAnalyzer project file |
.impt | Project template file |
.evadb | Results database (DuckDB format) |