Command-Line Interface (CLI)

GeometricMedicalPhantoms includes a command-line interface for generating phantoms and signals without writing Julia code. While the preferred method is to use the package within Julia programs for maximum flexibility, the CLI provides a convenient way to generate phantoms quickly.

Installation

Download Pre-built Binary (Recommended for CLI Usage)

Download the latest release for your platform from the Releases page:

  • Linux: geomphantoms-linux-x64-x86_64.zip or geomphantoms-linux-x64-aarch64.zip
  • macOS: geomphantoms-macos-x64-x86_64.zip or geomphantoms-macos-aarch64.zip
  • Windows: geomphantoms-windows-x64-x86_64.zip

Note: You need x86_64 binaries for Intel/AMD CPUs and aarch64 binaries for Apple Silicon or ARM-based Linux systems. If unsure, check your CPU architecture. ARM-based Windows is not currently supported.

Extract and run directly:

# Linux/macOS
<extracted path>/bin/geomphantoms info

# Windows
<extracted path>.\bin\geomphantoms.exe info

Note: The extracted folder is quite large (1-1.5 GB) due to the bundled Julia runtime and dependencies.

Optionally you can add to your PATH for easier access.

Building from Source

The CLI is shipped as a separate app in app/ to avoid adding dependencies to the core package. To build it yourself, install JuliaC.jl Julia app and run:

julia --project=./app -e 'using Pkg; Pkg.instantiate()'
juliac --output-exe geomphantoms --project=./app --bundle app/build app/src/app.jl

The executable will be in app/build/bin/geomphantoms.

Basic Usage

geomphantoms info
geomphantoms phantom shepp-logan --size 256,256 --plane axial --out shepp.npy
geomphantoms phantom shepp-logan --size 256,256 --fov 24,24 --plane axial --out shepp_zoomed.npy

Phantom Generation

# 2D Shepp-Logan slice
geomphantoms phantom shepp-logan --size 256,256 --plane axial --out shepp.npy

# 3D Torso volume
geomphantoms phantom torso --size 128,128,128 --out torso.mat

# 2D Shepp-Logan with explicit field of view (cm)
geomphantoms phantom shepp-logan --size 256,256 --fov 24,24 --plane axial --out shepp_zoomed.npy

# Tubes with custom intensities
geomphantoms phantom tubes --size 256,256,256 \
  --intensity '{"outer_cylinder":0.3,"tube_fillings":[0.2,0.4,0.6,0.8,1.0]}' \
  --out tubes.npy

Output Formats

Supported outputs:

  • npy
  • mat
  • cfl/hdr (BART): use a base path without extension, e.g. --out ./phantom
  • nifti (.nii or .nii.gz)
  • png (2D only)
  • tiff (multi-page for 3D/4D; frame plane follows --plane, default axial)
  • gif (multi-frame 2D only, Linux/macOS only)

On Windows, GIF export is disabled in the CLI app due to GIFImages.jl precompile issues.

If --format is omitted, it is inferred from the --out extension. For BART output, always pass the base path and set --format cfl.

Signals

# Respiratory signal
geomphantoms signals respiratory --duration 10 --fs 24 --rate 12 --out resp.csv

# Cardiac signal
geomphantoms signals cardiac --duration 10 --fs 100 --rate 70 --out cardiac.json

Metadata

By default, a JSON sidecar is written to <out>.json. Disable it with --no-meta or specify a custom path with --meta.


API Reference

This section provides a complete reference for all CLI commands, arguments, and options.

Global Commands

info

Display version and system information.

geomphantoms info

Output:

  • Package version
  • Julia version

Exit Code: 0


phantom Command

Generate phantom images.

geomphantoms phantom <type> --size <dimensions> --out <path> [options]

Phantom Types

  • shepp-logan - Classic Shepp-Logan head phantom for testing imaging algorithms
  • torso - Anatomical torso phantom with heart, lungs, liver, kidneys, and spine
  • tubes - Cylindrical tubes phantom for resolution testing

Required Arguments

ArgumentDescriptionFormat
<type>Phantom typeOne of: shepp-logan, torso, tubes
--sizeVoxel dimensionsComma-separated integers: nx,ny (2D) or nx,ny,nz (3D)
--outOutput file pathFile path with extension

--size controls the matrix size, while --fov (below) controls the physical extent in centimeters.

Optional Arguments

OptionDescriptionTypeDefaultNotes
--fovField of view in cmStringPhantom-specific defaultComma-separated numbers: fx,fy (2D) or fx,fy,fz (3D). Dimensionality must match --size.
--planeSlice plane for 2D output and TIFF frame orientation for 3D/4D outputStringaxial for 2D; axial for TIFF if omittedOne of: axial, coronal, sagittal
--slice-positionSlice position in cmFloat0.0Position along the slice axis
--formatOutput formatStringInferred from extensionOne of: npy, mat, cfl, nifti, png, tiff, gif (gif is not available on Windows)
--metaMetadata JSON pathString<out>.jsonCustom location for metadata
--no-metaDisable metadata outputFlagfalseSkips JSON sidecar creation
--intensityIntensity specificationString/JSONDefault presetSee Intensity Specification
--maskMask specificationString/JSONNo maskingSee Mask Specification
--geometryGeometry specificationString/JSONDefault geometrySee Geometry Specification
--stackStack of intensity setsString/JSONSingle intensitySee Stack Specification
--resp-signalRespiratory signal fileFile pathNo motionCSV, JSON, or NPY file
--cardiac-signalCardiac volumes fileFile pathNo motionCSV or JSON file

Output Formats

FormatExtensionDimensionsDescription
npy.npy2D, 3D, 4DNumPy format (default)
mat.mat2D, 3D, 4DMATLAB format
cfl/hdr.cfl + .hdr2D, 3D, 4DBART format (use base path without extension)
nifti.nii, .nii.gz2D, 3D, 4DNIfTI format (compressed supported)
png.png2D onlyPNG image (auto-scaled to 8-bit)
tiff.tif, .tiff2D, 3D, 4DTIFF format (multi-page for 3D/4D; frame plane controlled by --plane)
gif.gif2D onlyGIF image (multi-frame for dynamic phantoms, Linux/macOS only)

Format Inference: If --format is omitted, the format is inferred from the --out extension.

BART Format Special Case: For BART output, provide the base path without extension:

geomphantoms phantom torso --size 128,128,128 --format cfl --out ./phantom
# Creates: ./phantom.cfl and ./phantom.hdr

Intensity Specification

The --intensity option controls tissue intensities. It accepts:

  1. Preset names (case-insensitive):

    • ct, mri, default (for Shepp-Logan)
    • Presets vary by phantom type
  2. JSON string:

    --intensity '{"outer_cylinder":0.3,"tube_fillings":[0.2,0.4,0.6,0.8,1.0]}'
  3. JSON file path:

    --intensity /path/to/intensity.json

Format: JSON object with phantom-specific keys. See phantom-specific documentation for available keys.

Mask Specification

The --mask option applies masking to the phantom. It accepts:

  1. JSON string:

    --mask '{"lv":true,"rv":false}'
  2. JSON file path:

    --mask /path/to/mask.json

Format: JSON object with boolean values for each phantom component.

Geometry Specification

The --geometry option (tubes phantom only) customizes geometric parameters:

  1. JSON string:

    --geometry '{"outer_radius":10.0,"tube_radius":1.5}'
  2. JSON file path:

    --geometry /path/to/geometry.json

Format: JSON object with geometry parameters specific to the phantom type.

Stack Specification

The --stack option (tubes phantom only) provides a stack of intensity sets:

  1. JSON array string:

    --stack '[{"outer_cylinder":0.3},{"outer_cylinder":0.5}]'
  2. JSON file path:

    --stack /path/to/stack.json

Format: JSON array of intensity objects.

Signal File Formats

Respiratory Signal:

  • CSV: t,signal columns (time first; optional header accepted)
  • JSON: {"signal": [values]} or {"t": [times], "signal": [values]}
  • NPY: 1D NumPy array

Cardiac Signal:

  • CSV: t,lv,rv,la,ra (time first; optional header accepted)
  • JSON: {"lv": [values], "rv": [values], "la": [values], "ra": [values]}

Important: Respiratory and cardiac signals must have the same length when both are provided.


signals Command

Generate physiological signals (respiratory or cardiac).

geomphantoms signals <type> --out <path> [options]

Signal Types

  • respiratory - Respiratory motion signal
  • cardiac - Cardiac volumetric signals (LV, RV, LA, RA)

Required Arguments

ArgumentDescriptionFormat
<type>Signal typeOne of: respiratory, cardiac
--outOutput file pathFile path with extension

Optional Arguments

OptionDescriptionTypeDefaultNotes
--durationDuration in secondsFloat10.0Total signal length
--fsSampling frequency in HzFloat24.0Samples per second
--ratePhysiological rateFloat15.0 (resp) / 70.0 (cardiac)Breaths/min or beats/min
--physiologyPhysiology parametersString/JSONDefault physiologySee Physiology Specification
--formatOutput formatStringInferred from extensionOne of: csv, json, npy

Signal Output Formats

FormatExtensionContent
csv.csvTime series with headers
json.jsonJSON object with named fields
npy.npyNumPy array (respiratory only)

Respiratory CSV Output:

t,signal
0.0,0.0
0.041667,0.123
...

Cardiac CSV Output:

lv,rv,la,ra
85.0,70.0,55.0,45.0
87.3,71.2,56.1,46.0
...

Respiratory JSON Output:

{
  "t": [0.0, 0.041667, ...],
  "signal": [0.0, 0.123, ...]
}

Cardiac JSON Output:

{
  "t": [0.0, 0.01, ...],
  "lv": [85.0, 87.3, ...],
  "rv": [70.0, 71.2, ...],
  "la": [55.0, 56.1, ...],
  "ra": [45.0, 46.0, ...]
}

Physiology Specification

The --physiology option customizes physiological parameters:

  1. JSON string:

    --physiology '{"amplitude":1.5,"baseline":0.0}'
  2. JSON file path:

    --physiology /path/to/physiology.json

Respiratory Physiology Keys:

  • amplitude - Signal amplitude
  • baseline - Baseline offset
  • Additional model-specific parameters

Cardiac Physiology Keys:

  • lv_systolic, lv_diastolic - Left ventricle volumes
  • rv_systolic, rv_diastolic - Right ventricle volumes
  • la_systolic, la_diastolic - Left atrium volumes
  • ra_systolic, ra_diastolic - Right atrium volumes
  • Additional timing parameters

Metadata JSON Format

When metadata is enabled (default), a JSON sidecar file is created with the following structure:

{
  "command": "phantom",
  "type": "torso",
  "size": [128, 128, 128],
  "plane": null,
  "slice_position": 0.0,
  "format": "nifti",
  "output": "/path/to/output.nii.gz",
  "timestamp": "2026-02-10T15:30:45.123",
  "package_version": "1.0.0",
  "julia_version": "1.12.4"
}

Fields:

  • command - CLI command used (phantom or signals)
  • type - Phantom or signal type
  • size - Array dimensions (phantom command only)
  • plane - Selected plane; used for 2D slicing and TIFF frame orientation
  • slice_position - Slice position in cm
  • format - Output format
  • output - Output file path
  • timestamp - ISO 8601 timestamp
  • package_version - GeometricMedicalPhantoms version
  • julia_version - Julia version used

Exit Codes

CodeMeaning
0Success
1Error (invalid arguments, unsupported format, file I/O error, etc.)

Examples

Basic Phantom Generation

# 2D axial Shepp-Logan (256×256)
geomphantoms phantom shepp-logan --size 256,256 --plane axial --out shepp.npy

# 3D torso (128×128×128)
geomphantoms phantom torso --size 128,128,128 --out torso.mat

# Coronal slice of tubes
geomphantoms phantom tubes --size 256,256 --plane coronal --out tubes.png

Custom Intensities

# Shepp-Logan with CT intensities
geomphantoms phantom shepp-logan --size 256,256 --plane axial \
  --intensity ct --out shepp_ct.npy

# Tubes with custom filling intensities
geomphantoms phantom tubes --size 256,256,256 \
  --intensity '{"outer_cylinder":0.3,"tube_fillings":[0.2,0.4,0.6,0.8,1.0]}' \
  --out tubes.npy

Multiple Output Formats

# NIfTI with compression
geomphantoms phantom torso --size 128,128,128 --out torso.nii.gz

# BART format
geomphantoms phantom torso --size 128,128,128 --format cfl --out phantom_base

# Multi-page TIFF (axial frames by default)
geomphantoms phantom torso --size 128,128,128 --out torso.tiff

# Multi-page TIFF with coronal frames
geomphantoms phantom torso --size 128,128,128 --plane coronal --out torso_coronal.tiff

Dynamic Phantoms with Motion

# Generate respiratory signal
geomphantoms signals respiratory --duration 10 --fs 24 --rate 15 --out resp.csv

# Generate cardiac signal
geomphantoms signals cardiac --duration 10 --fs 100 --rate 70 --out cardiac.json

# Create torso with respiratory motion
geomphantoms phantom torso --size 128,128,128 \
  --resp-signal resp.csv --out torso_resp.npy

# Create torso with both respiratory and cardiac motion
geomphantoms phantom torso --size 128,128,128 \
  --resp-signal resp.csv --cardiac-signal cardiac.json \
  --out torso_dynamic.npy

Signal Generation

# Respiratory signal, 30 seconds at 24 Hz, 12 breaths/min
geomphantoms signals respiratory --duration 30 --fs 24 --rate 12 --out resp.csv

# Cardiac signal, 10 seconds at 100 Hz, 75 beats/min
geomphantoms signals cardiac --duration 10 --fs 100 --rate 75 --out cardiac.json

# Respiratory signal with custom physiology
geomphantoms signals respiratory --duration 10 --fs 24 \
  --physiology '{"amplitude":1.5,"baseline":0.5}' --out resp.csv

Metadata Control

# Disable metadata
geomphantoms phantom shepp-logan --size 256,256 --plane axial \
  --out shepp.npy --no-meta

# Custom metadata path
geomphantoms phantom torso --size 128,128,128 --out torso.mat \
  --meta ./metadata/torso_info.json

Tips and Best Practices

  1. Format Inference: Let the CLI infer the format from the file extension when possible:

    geomphantoms phantom shepp-logan --size 256,256 --plane axial --out shepp.npy
    # Format is inferred as 'npy'
  2. BART Format: Always provide the base path without extension when using BART format:

    geomphantoms phantom torso --size 128,128,128 --format cfl --out phantom
    # Creates phantom.cfl and phantom.hdr
  3. Plane behavior: --plane controls 2D slice orientation and TIFF frame orientation for 3D/4D outputs:

    # 2D (defaults to axial if omitted)
    geomphantoms phantom shepp-logan --size 256,256 --plane axial --out shepp.npy
    
    # 3D TIFF with coronal frames
    geomphantoms phantom torso --size 128,128,128 --plane coronal --out torso.tiff
  4. Signal Length Matching: When using both respiratory and cardiac signals, ensure they have the same number of samples:

    # Both 10 seconds at different sampling rates is OK if they end up with same length
    geomphantoms signals respiratory --duration 10 --fs 24 --out resp.csv
    geomphantoms signals cardiac --duration 10 --fs 24 --out cardiac.csv
  5. Large Volumes: For large 3D volumes, use compressed formats:

    geomphantoms phantom torso --size 512,512,512 --out torso.nii.gz
  6. Multi-page TIFF: For 3D data that needs to be opened in standard image viewers, use --plane to choose frame orientation:

    geomphantoms phantom torso --size 256,256,256 --out torso.tiff
    # Creates multi-page TIFF with axial frames (default)
    
    geomphantoms phantom torso --size 256,256,256 --plane coronal --out torso_coronal.tiff
    # Creates multi-page TIFF with coronal frames
  7. Version Information: Check the version before reporting issues:

    geomphantoms info