Skip to content

aimbat._cli

Modules:

Name Description
align

Align seismograms using ICCS or MCCC.

common
data

Manage data sources in an AIMBAT project.

event

View and manage events in the AIMBAT project.

pick

Interactively pick phase arrival times and processing parameters.

plot

Create plots for seismograms and ICCS results.

project

Manage AIMBAT projects.

seismogram

View and manage seismograms in the AIMBAT project.

shell

Interactive AIMBAT shell with tab-completion and command history.

snapshot

View and manage snapshots of processing parameters.

station

View and manage stations.

utils

Utilities for AIMBAT.

align

Align seismograms using ICCS or MCCC.

This command aligns seismograms using either the ICCS or MCCC algorithm. Both commands update the pick stored in t1. If t1 is None, t0 is used as starting point instead, with the resulting pick stored in t1.

Functions:

Name Description
cli_iccs_run

Run the ICCS algorithm to align seismograms for an event.

cli_mccc_run

Run the MCCC algorithm to refine arrival time picks for an event.

cli_iccs_run

cli_iccs_run(
    event_id: Annotated[UUID, event_parameter()],
    *,
    autoselect: Annotated[
        bool,
        Parameter(
            name=autoselect,
            help="Whether to automatically de-select seismograms whose cross-correlation with the stack falls below `min_cc`, and re-select them if the cross-correlation later exceeds `min_cc`.",
        ),
    ] = False,
    autoflip: Annotated[
        bool,
        Parameter(
            name=autoflip,
            help="Whether to automatically flip seismograms (multiply data by -1) when the cross-correlation is negative.",
        ),
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None

Run the ICCS algorithm to align seismograms for an event.

Iteratively cross-correlates seismograms against a running stack to refine arrival time picks (t1). If t1 is not yet set, t0 is used as the starting point.

Source code in src/aimbat/_cli/align.py
@app.command(name="iccs")
@simple_exception
def cli_iccs_run(
    event_id: Annotated[UUID, event_parameter()],
    *,
    autoselect: Annotated[
        bool,
        Parameter(
            name="autoselect",
            help="Whether to automatically de-select seismograms whose"
            " cross-correlation with the stack falls below `min_cc`, and"
            " re-select them if the cross-correlation later exceeds `min_cc`.",
        ),
    ] = False,
    autoflip: Annotated[
        bool,
        Parameter(
            name="autoflip",
            help="Whether to automatically flip seismograms (multiply data"
            " by -1) when the cross-correlation is negative.",
        ),
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Run the ICCS algorithm to align seismograms for an event.

    Iteratively cross-correlates seismograms against a running stack to refine
    arrival time picks (`t1`). If `t1` is not yet set, `t0` is used as the
    starting point.
    """
    from sqlmodel import Session

    from aimbat.core import create_iccs_instance, resolve_event, run_iccs
    from aimbat.db import engine

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        run_iccs(session, event, iccs, autoflip, autoselect)

cli_mccc_run

cli_mccc_run(
    event_id: Annotated[UUID, event_parameter()],
    *,
    all_seismograms: Annotated[
        bool,
        Parameter(
            name=all,
            help="Include all seismograms of an event in MCCC processing, not just the currently selected ones.",
        ),
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None

Run the MCCC algorithm to refine arrival time picks for an event.

Multi-channel cross-correlation simultaneously determines the optimal time shifts for all seismograms. Results are stored in t1.

Source code in src/aimbat/_cli/align.py
@app.command(name="mccc")
@simple_exception
def cli_mccc_run(
    event_id: Annotated[UUID, event_parameter()],
    *,
    all_seismograms: Annotated[
        bool,
        Parameter(
            name="all",
            help="Include all seismograms of an event in MCCC processing, "
            "not just the currently selected ones.",
        ),
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Run the MCCC algorithm to refine arrival time picks for an event.

    Multi-channel cross-correlation simultaneously determines the optimal time
    shifts for all seismograms. Results are stored in `t1`.
    """
    from sqlmodel import Session

    from aimbat.core import create_iccs_instance, resolve_event, run_mccc
    from aimbat.db import engine

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        run_mccc(session, event, iccs, all_seismograms)

common

Classes:

Name Description
DebugParameter

DebugParameter(debug: bool = False)

EventDebugParameters

Parameters for commands that operate on individual events, with optional debug mode.

IccsPlotParameters

IccsPlotParameters(context: Annotated[bool, Parameter(help='Plot seismograms with extra context instead of the short tapered ones used for cross-correlation')] = True, all_seismograms: Annotated[bool, Parameter(name=('all',), help='Include all seismograms in the plot, even if not used in stack.')] = False)

JsonDumpParameters

JsonDumpParameters(debug: bool = False, by_alias: Annotated[bool, Parameter(name=('alias',), help='Dump records using their alias instead of attribute names.')] = False)

TableParameters

TableParameters(debug: bool = False, raw: bool = False)

Functions:

Name Description
json_to_table

Print a JSON dict or list of dicts as a rich table driven by a Pydantic model.

print_error_panel

Print an exception to the console in a red panel.

simple_exception

Decorator to handle exceptions and print them to the console.

DebugParameter dataclass

Bases: _DebugTrait

DebugParameter(debug: bool = False)

Parameters:

Name Type Description Default
debug bool

Enable verbose logging for troubleshooting.

False

Attributes:

Name Type Description
debug bool

Enable verbose logging for troubleshooting.

Source code in src/aimbat/_cli/common/_parameters.py
@Parameter(name="*")
@dataclass
class DebugParameter(_DebugTrait):
    pass

debug class-attribute instance-attribute

debug: bool = False

Enable verbose logging for troubleshooting.

EventDebugParameters dataclass

Bases: _DebugTrait, _EventContextTrait

Parameters for commands that operate on individual events, with optional debug mode.

Parameters:

Name Type Description Default
event_id UUID
required
debug bool

Enable verbose logging for troubleshooting.

False

Attributes:

Name Type Description
debug bool

Enable verbose logging for troubleshooting.

Source code in src/aimbat/_cli/common/_parameters.py
@Parameter(name="*")
@dataclass
class EventDebugParameters(_DebugTrait, _EventContextTrait):
    """Parameters for commands that operate on individual events, with optional debug mode."""

    pass

debug class-attribute instance-attribute

debug: bool = False

Enable verbose logging for troubleshooting.

IccsPlotParameters dataclass

IccsPlotParameters(context: Annotated[bool, Parameter(help='Plot seismograms with extra context instead of the short tapered ones used for cross-correlation')] = True, all_seismograms: Annotated[bool, Parameter(name=('all',), help='Include all seismograms in the plot, even if not used in stack.')] = False)

Parameters:

Name Type Description Default
context bool
True
all_seismograms bool
False
Source code in src/aimbat/_cli/common/_parameters.py
@Parameter(name="*")
@dataclass
class IccsPlotParameters:
    context: Annotated[
        bool,
        Parameter(
            help="Plot seismograms with extra context instead of the short tapered ones used for cross-correlation"
        ),
    ] = True
    all_seismograms: Annotated[
        bool,
        Parameter(
            name="all",
            help="Include all seismograms in the plot, even if not used in stack.",
        ),
    ] = False

JsonDumpParameters dataclass

Bases: _ByAliasTrait, _DebugTrait

JsonDumpParameters(debug: bool = False, by_alias: Annotated[bool, Parameter(name=('alias',), help='Dump records using their alias instead of attribute names.')] = False)

Parameters:

Name Type Description Default
debug bool

Enable verbose logging for troubleshooting.

False
by_alias bool
False

Attributes:

Name Type Description
debug bool

Enable verbose logging for troubleshooting.

Source code in src/aimbat/_cli/common/_parameters.py
@Parameter(name="*")
@dataclass
class JsonDumpParameters(_ByAliasTrait, _DebugTrait):
    pass

debug class-attribute instance-attribute

debug: bool = False

Enable verbose logging for troubleshooting.

TableParameters dataclass

Bases: _TableParametersTrait, _DebugTrait

TableParameters(debug: bool = False, raw: bool = False)

Parameters:

Name Type Description Default
debug bool

Enable verbose logging for troubleshooting.

False
raw bool
False

Attributes:

Name Type Description
debug bool

Enable verbose logging for troubleshooting.

Source code in src/aimbat/_cli/common/_parameters.py
@Parameter(name="*")
@dataclass
class TableParameters(_TableParametersTrait, _DebugTrait):
    pass

debug class-attribute instance-attribute

debug: bool = False

Enable verbose logging for troubleshooting.

json_to_table

json_to_table(
    data: dict[str, Any] | list[dict[str, Any]],
    model: type[BaseModel],
    title: str | None = None,
    raw: bool = False,
    col_specs: dict[str, RichColSpec] | None = None,
    column_order: list[str] | None = None,
    key_header: str = "Property",
    value_header: str = "Value",
) -> None

Print a JSON dict or list of dicts as a rich table driven by a Pydantic model.

Parameters:

Name Type Description Default
data dict[str, Any] | list[dict[str, Any]]

A single row (dict) or list of rows to display.

required
model type[BaseModel]

Pydantic model whose field metadata drives column configuration.

required
title str | None

Optional table title.

None
raw bool

If True, ignore RichColSpec metadata and render using only type-based heuristics. Useful for a quick unformatted view.

False
col_specs dict[str, RichColSpec] | None

Optional per-field overrides. Each entry is merged on top of the spec derived from the model field, so only the attributes that differ need to be set. Ignored when raw=True.

None
column_order list[str] | None

Optional list of field names that should appear first, in that order. Fields not listed appear after in model-declaration order.

None
key_header str

Header for the property-name column in vertical (dict) tables.

'Property'
value_header str

Header for the value column in vertical (dict) tables.

'Value'
Source code in src/aimbat/_cli/common/_table.py
def json_to_table(
    data: dict[str, Any] | list[dict[str, Any]],
    model: type[BaseModel],
    title: str | None = None,
    raw: bool = False,
    col_specs: dict[str, RichColSpec] | None = None,
    column_order: list[str] | None = None,
    key_header: str = "Property",
    value_header: str = "Value",
) -> None:
    """Print a JSON dict or list of dicts as a rich table driven by a Pydantic model.

    Args:
        data: A single row (dict) or list of rows to display.
        model: Pydantic model whose field metadata drives column configuration.
        title: Optional table title.
        raw: If `True`, ignore `RichColSpec` metadata and render using only
            type-based heuristics. Useful for a quick unformatted view.
        col_specs: Optional per-field overrides. Each entry is merged on top of
            the spec derived from the model field, so only the attributes that
            differ need to be set. Ignored when `raw=True`.
        column_order: Optional list of field names that should appear first, in
            that order. Fields not listed appear after in model-declaration order.
        key_header: Header for the property-name column in vertical (dict) tables.
        value_header: Header for the value column in vertical (dict) tables.
    """
    console = Console()
    table = Table(title=title)

    data_list = [data] if isinstance(data, dict) else data
    if not data_list:
        console.print(table)
        return

    # Build specs from model field metadata (skipped in raw mode).
    specs: dict[str, RichColSpec] = {}
    if not raw:
        for name, field in model.model_fields.items():
            spec: RichColSpec | None = None
            # Pydantic Field uses json_schema_extra; SQLModel Field uses schema_extra
            # which spreads its keys directly into _attributes_set on the FieldInfo.
            for source in (
                field.json_schema_extra,
                getattr(field, "_attributes_set", None),
            ):
                if isinstance(source, dict):
                    candidate = source.get("rich")
                    if isinstance(candidate, RichColSpec):
                        spec = candidate
                        break
            specs[name] = spec if spec is not None else RichColSpec()

        # Apply caller-supplied overrides. model_fields_set tracks which fields
        # were explicitly provided, so only those replace the model-derived spec.
        if col_specs:
            for name, override in col_specs.items():
                base = specs.get(name, RichColSpec())
                specs[name] = base.model_copy(
                    update={k: getattr(override, k) for k in override.model_fields_set}
                )

    def _ordered(names: list[str]) -> list[str]:
        if not column_order:
            return names
        ordered = [n for n in column_order if n in names]
        rest = [n for n in names if n not in set(column_order)]
        return ordered + rest

    def _fmt_val(name: str, val: Any) -> str:
        if raw:
            return "" if val is None else str(val)
        if val is None or val is NaT:
            return _MISSING_MARKER
        spec = specs.get(name)
        if spec and spec.formatter:
            return spec.formatter(val)
        if isinstance(val, bool):
            return fmt_bool(val)
        if isinstance(val, float):
            return fmt_float(val)
        if isinstance(val, Timedelta):
            return fmt_timedelta(val)
        if isinstance(val, (Timestamp, datetime)):
            return fmt_timestamp(val)
        low_key = name.lower()
        if (
            isinstance(val, str)
            and val.strip()
            and any(k in low_key for k in ("time", "date", "modified"))
        ):
            try:
                dt = to_datetime(val)
                return fmt_timestamp(dt)
            except (ValueError, TypeError):
                return str(val)
        return str(val)

    field_names = _ordered(list(model.model_fields.keys()))

    if isinstance(data, dict):
        # Vertical table
        table.add_column(key_header, style="cyan")
        table.add_column(value_header)
        for name in field_names:
            if name not in data:
                continue
            spec = specs.get(name)
            if spec and spec.display_title:
                label = spec.display_title
            else:
                field = model.model_fields[name]
                label = field.title if field.title else name
            table.add_row(label, _fmt_val(name, data[name]))
    else:
        # Horizontal table — restrict to fields present in data.
        data_keys: set[str] = set()
        for item in data_list:
            data_keys.update(item.keys())
        visible_fields = [n for n in field_names if n in data_keys]

        for name in visible_fields:
            spec = specs.get(name)
            field = model.model_fields[name]
            header = (
                spec.display_title
                if spec and spec.display_title
                else field.title or name
            )
            kwargs: dict[str, Any] = {}
            default_justify = _justify_for_annotation(field.annotation)
            if default_justify:
                kwargs["justify"] = default_justify
            if spec:
                if spec.justify:
                    kwargs["justify"] = spec.justify
                if spec.style:
                    kwargs["style"] = spec.style
                if spec.no_wrap is not None:
                    kwargs["no_wrap"] = spec.no_wrap
                if spec.highlight is not None:
                    kwargs["highlight"] = spec.highlight
            table.add_column(header, **kwargs)

        for item in data:
            table.add_row(*[_fmt_val(n, item.get(n)) for n in visible_fields])

    console.print(table)

print_error_panel

print_error_panel(e: Exception) -> None

Print an exception to the console in a red panel.

Source code in src/aimbat/_cli/common/_decorators.py
def print_error_panel(e: Exception) -> None:
    """Print an exception to the console in a red panel."""
    from rich.console import Console
    from rich.panel import Panel

    console = Console(stderr=True)
    panel = Panel(
        f"{e}",
        title="Error",
        title_align="left",
        border_style="red",
        expand=True,
    )
    console.print(panel)

simple_exception

simple_exception(func: F) -> F

Decorator to handle exceptions and print them to the console.

Using this decorator prints only the exception to the console without traceback, and then exits. In debugging mode this decorator returns the callable unchanged.

Source code in src/aimbat/_cli/common/_decorators.py
def simple_exception[F: Callable[..., Any]](func: F) -> F:
    """Decorator to handle exceptions and print them to the console.

    Using this decorator prints only the exception to the console without
    traceback, and then exits. In debugging mode this decorator returns the
    callable unchanged.
    """
    import sys
    from functools import wraps

    @wraps(func)
    def wrapper(*args: Any, **kwargs: Any) -> Any:
        if settings.log_level in ("TRACE", "DEBUG"):
            return func(*args, **kwargs)
        try:
            return func(*args, **kwargs)
        except Exception as e:
            print_error_panel(e)
            sys.exit(1)

    return wrapper  # type: ignore

data

Manage data sources in an AIMBAT project.

A data source is a file that AIMBAT reads seismogram waveforms and metadata from. When a data source is added, AIMBAT extracts and stores the associated station, event, and seismogram records in the project database — provided the data type supports it.

Supported data types (--type):

  • sac (default): SAC waveform file. Extracts station, event, and seismogram data automatically.
  • json_station: JSON file containing station metadata only. No seismogram is created.
  • json_event: JSON file containing event metadata only. No seismogram is created.

Typical workflow:

aimbat project create
aimbat data add *.sac
aimbat event list          # list events created from SAC headers
aimbat snapshot create "initial import" --event-id <ID>

Re-adding a data source that is already in the project is safe — existing records are reused rather than duplicated.

Functions:

Name Description
cli_data_add

Add or update data sources in the AIMBAT project.

cli_data_dump

Dump AIMBAT datasources table as a JSON string.

cli_data_list

Print a table of data sources registered in the AIMBAT project.

cli_data_add

cli_data_add(
    data_sources: Annotated[
        list[Path],
        Parameter(
            name="sources",
            help="One or more data source paths to add.",
            consume_multiple=1,
            negative_iterable=(),
            validator=Path(exists=True),
        ),
    ],
    *,
    data_type: Annotated[
        DataType,
        Parameter(
            name="type",
            help="Format of the data sources. Determines which metadata (station, event, seismogram) can be extracted automatically.",
        ),
    ] = SAC,
    station_id: Annotated[
        UUID | None, use_station_parameter()
    ] = None,
    event_id: Annotated[
        UUID | None, use_event_parameter()
    ] = None,
    dry_run: Annotated[
        bool,
        Parameter(
            name="dry-run",
            help="Preview which records would be added without modifying the database.",
        ),
    ] = False,
    show_progress_bar: Annotated[
        bool,
        Parameter(
            name="progress",
            help="Display a progress bar while ingesting sources.",
        ),
    ] = True,
    _: DebugParameter = DebugParameter(),
) -> None

Add or update data sources in the AIMBAT project.

Each data source is processed according to --type. For sac (the default), AIMBAT extracts station, event, and seismogram metadata directly from the file. For types that cannot extract a station or event (e.g. a format that only carries waveform data), supply --use-station and/or --use-event to link to records that already exist in the project.

Station and event deduplication is automatic: if a matching record already exists it is reused. Re-running data add on the same files is safe.

Use --dry-run to preview what would be added without touching the database.

Source code in src/aimbat/_cli/data.py
@app.command(name="add")
@simple_exception
def cli_data_add(
    data_sources: Annotated[
        list[Path],
        Parameter(
            name="sources",
            help="One or more data source paths to add.",
            consume_multiple=1,
            negative_iterable=(),
            validator=validators.Path(exists=True),
        ),
    ],
    *,
    data_type: Annotated[
        DataType,
        Parameter(
            name="type",
            help="Format of the data sources. Determines which metadata"
            " (station, event, seismogram) can be extracted automatically.",
        ),
    ] = DataType.SAC,
    station_id: Annotated[uuid.UUID | None, use_station_parameter()] = None,
    event_id: Annotated[uuid.UUID | None, use_event_parameter()] = None,
    dry_run: Annotated[
        bool,
        Parameter(
            name="dry-run",
            help="Preview which records would be added without modifying the database.",
        ),
    ] = False,
    show_progress_bar: Annotated[
        bool,
        Parameter(
            name="progress", help="Display a progress bar while ingesting sources."
        ),
    ] = True,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Add or update data sources in the AIMBAT project.

    Each data source is processed according to `--type`. For `sac` (the
    default), AIMBAT extracts station, event, and seismogram metadata directly
    from the file. For types that cannot extract a station or event (e.g. a
    format that only carries waveform data), supply `--use-station` and/or
    `--use-event` to link to records that already exist in the project.

    Station and event deduplication is automatic: if a matching record already
    exists it is reused. Re-running `data add` on the same files is safe.

    Use `--dry-run` to preview what would be added without touching the
    database.
    """
    from aimbat.core import add_data_to_project
    from aimbat.db import engine

    disable_progress_bar = not show_progress_bar

    with Session(engine) as session:
        if dry_run:
            results = add_data_to_project(
                session,
                data_sources,
                data_type,
                station_id=station_id,
                event_id=event_id,
                dry_run=True,
                disable_progress_bar=disable_progress_bar,
            )
            _print_dry_run_results(*results)
        else:
            add_data_to_project(
                session,
                data_sources,
                data_type,
                station_id=station_id,
                event_id=event_id,
                dry_run=False,
                disable_progress_bar=disable_progress_bar,
            )

cli_data_dump

cli_data_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump AIMBAT datasources table as a JSON string.

Output can be piped or redirected for use in external tools or scripts.

Source code in src/aimbat/_cli/data.py
@app.command(name="dump")
@simple_exception
def cli_data_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None:
    """Dump AIMBAT datasources table as a JSON string.

    Output can be piped or redirected for use in external tools or scripts.
    """
    from rich import print_json

    from aimbat.core import dump_data_table
    from aimbat.db import engine

    with Session(engine) as session:
        print_json(data=dump_data_table(session, by_alias=dump_parameters.by_alias))

cli_data_list

cli_data_list(
    event_id: Annotated[
        UUID | Literal["all"], event_parameter_with_all()
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None

Print a table of data sources registered in the AIMBAT project.

Source code in src/aimbat/_cli/data.py
@app.command(name="list")
@simple_exception
def cli_data_list(
    event_id: Annotated[uuid.UUID | Literal["all"], event_parameter_with_all()],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """Print a table of data sources registered in the AIMBAT project."""
    from aimbat.core import dump_data_table, resolve_event
    from aimbat.db import engine
    from aimbat.logger import logger
    from aimbat.models import AimbatDataSource, AimbatSeismogram, RichColSpec
    from aimbat.utils import uuid_shortener

    from .common import json_to_table

    raw = table_parameters.raw

    with Session(engine) as session:
        logger.debug("Printing data sources table.")

        if event_parameter_is_all(event_id):
            data = dump_data_table(session)
            title = "Data sources for all events"
        else:
            event = resolve_event(session, event_id)
            data = dump_data_table(session, event.id)
            _time = event.time.strftime("%Y-%m-%d %H:%M:%S") if not raw else event.time
            _id = uuid_shortener(session, event) if not raw else event.id
            title = f"Data sources for event {_time} (ID={_id})"

        col_specs = {
            "id": RichColSpec(
                formatter=lambda x: uuid_shortener(
                    session, AimbatDataSource, str_uuid=x
                )
            ),
            "seismogram_id": RichColSpec(
                formatter=lambda x: uuid_shortener(
                    session, AimbatSeismogram, str_uuid=x
                )
            ),
        }

        json_to_table(
            model=AimbatDataSource,
            data=data,
            title=title,
            raw=raw,
            col_specs=col_specs,
        )

event

View and manage events in the AIMBAT project.

Functions:

Name Description
cli_event_delete

Delete existing event.

cli_event_dump

Dump the contents of the AIMBAT event table to JSON.

cli_event_list

Print a table of events stored in the AIMBAT project.

cli_event_parameter_dump

Dump event parameter table to json.

cli_event_parameter_get

Get parameter value for an event.

cli_event_parameter_list

List processing parameter for an event or all events.

cli_event_parameter_set

Set parameter value for an event.

cli_event_delete

cli_event_delete(
    event_id: Annotated[UUID, event_parameter()],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Delete existing event.

Source code in src/aimbat/_cli/event.py
@app.command(name="delete")
@simple_exception
def cli_event_delete(
    event_id: Annotated[uuid.UUID, event_parameter()],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Delete existing event."""
    from aimbat.core import delete_event, resolve_event
    from aimbat.db import engine

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        delete_event(session, event.id)

cli_event_dump

cli_event_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump the contents of the AIMBAT event table to JSON.

Output can be piped or redirected for use in external tools or scripts.

Source code in src/aimbat/_cli/event.py
@app.command(name="dump")
@simple_exception
def cli_event_dump(
    *, dump_parameters: JsonDumpParameters = JsonDumpParameters()
) -> None:
    """Dump the contents of the AIMBAT event table to JSON.

    Output can be piped or redirected for use in external tools or scripts.
    """
    from rich import print_json

    from aimbat.core import dump_event_table
    from aimbat.db import engine

    with Session(engine) as session:
        print_json(dump_event_table(session, by_alias=dump_parameters.by_alias))

cli_event_list

cli_event_list(
    *, table_parameters: TableParameters = TableParameters()
) -> None

Print a table of events stored in the AIMBAT project.

Source code in src/aimbat/_cli/event.py
@app.command(name="list")
@simple_exception
def cli_event_list(
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """Print a table of events stored in the AIMBAT project."""

    from aimbat.core import dump_event_table
    from aimbat.db import engine
    from aimbat.logger import logger
    from aimbat.models import AimbatEventRead

    from .common import json_to_table

    if raw := table_parameters.raw:
        exclude = {"short_id"}
    else:
        exclude = {"id"}

    with Session(engine) as session:
        logger.info("Printing AIMBAT events table.")

        json_to_table(
            data=dump_event_table(
                session, from_read_model=True, by_title=False, exclude=exclude
            ),
            model=AimbatEventRead,
            title="AIMBAT Events",
            raw=raw,
        )

cli_event_parameter_dump

cli_event_parameter_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump event parameter table to json.

Source code in src/aimbat/_cli/event.py
@_parameter.command(name="dump")
@simple_exception
def cli_event_parameter_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None:
    """Dump event parameter table to json."""
    from rich import print_json
    from sqlmodel import Session

    from aimbat.core import dump_event_parameter_table
    from aimbat.db import engine

    by_alias = dump_parameters.by_alias

    with Session(engine) as session:
        print_json(data=dump_event_parameter_table(session, by_alias=by_alias))

cli_event_parameter_get

cli_event_parameter_get(
    name: EventParameter,
    *,
    event_debug_parameters: EventDebugParameters,
) -> None

Get parameter value for an event.

Parameters:

Name Type Description Default
name EventParameter

Event parameter name.

required
Source code in src/aimbat/_cli/event.py
@_parameter.command(name="get")
@simple_exception
def cli_event_parameter_get(
    name: EventParameter, *, event_debug_parameters: EventDebugParameters
) -> None:
    """Get parameter value for an event.

    Args:
        name: Event parameter name.
    """

    from sqlmodel import Session

    from aimbat.core import resolve_event
    from aimbat.db import engine

    event_id = event_debug_parameters.event_id

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        value = event.parameters.model_dump(mode="json").get(name)
        print(value)

cli_event_parameter_list

cli_event_parameter_list(
    event_id: Annotated[
        UUID | Literal["all"], event_parameter_with_all()
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None

List processing parameter for an event or all events.

Displays all event-level parameters (e.g. time window, bandpass filter settings, minimum cc) in a table.

Source code in src/aimbat/_cli/event.py
@_parameter.command(name="list")
@simple_exception
def cli_event_parameter_list(
    event_id: Annotated[uuid.UUID | Literal["all"], event_parameter_with_all()],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """List processing parameter for an event or all events.

    Displays all event-level parameters (e.g. time window, bandpass filter
    settings, minimum cc) in a table.
    """

    from aimbat.core import dump_event_parameter_table, resolve_event
    from aimbat.db import engine
    from aimbat.models import AimbatEventParameters, RichColSpec
    from aimbat.utils import uuid_shortener

    from .common import json_to_table

    raw = table_parameters.raw

    with Session(engine) as session:
        if event_parameter_is_all(event_id):
            title = "Event parameters for all events"
            data = dump_event_parameter_table(session)
        else:
            event = resolve_event(session, event_id)
            title = f"Event parameters for event: {uuid_shortener(session, event) if not raw else str(event.id)}"
            data = dump_event_parameter_table(
                session, event_id=event.id, exclude={"event_id"}
            )

        column_order = ["id"]
        col_specs = {
            "id": RichColSpec(
                formatter=lambda x: uuid_shortener(
                    session, AimbatEventParameters, str_uuid=x
                )
            ),
            "event_id": RichColSpec(
                formatter=lambda x: uuid_shortener(session, AimbatEvent, str_uuid=x)
            ),
        }

        json_to_table(
            model=AimbatEventParameters,
            title=title,
            data=data,
            raw=raw,
            col_specs=col_specs,
            column_order=column_order,
        )

cli_event_parameter_set

cli_event_parameter_set(
    name: EventParameter,
    value: str,
    *,
    event_debug_parameters: EventDebugParameters,
) -> None

Set parameter value for an event.

Parameters:

Name Type Description Default
name EventParameter

Event parameter name.

required
value str

New parameter value.

required
Source code in src/aimbat/_cli/event.py
@_parameter.command(name="set")
@simple_exception
def cli_event_parameter_set(
    name: EventParameter, value: str, *, event_debug_parameters: EventDebugParameters
) -> None:
    """Set parameter value for an event.

    Args:
        name: Event parameter name.
        value: New parameter value.
    """
    from sqlmodel import Session

    from aimbat.core import resolve_event, set_event_parameter
    from aimbat.db import engine

    event_id = event_debug_parameters.event_id

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        set_event_parameter(session, event.id, name, value, validate_iccs=True)

pick

Interactively pick phase arrival times and processing parameters.

These commands open an interactive matplotlib plot for an event. Use --event-id or set the DEFAULT_EVENT_ID environment variable to choose which event to pick. Click on the plot to set the chosen value, then close the window to save it.

Functions:

Name Description
cli_pick_min_cc

Interactively pick a new minimum cross-correlation for auto-selection.

cli_pick_timewindow

Interactively pick a new cross-correlation time window for an event.

cli_update_phase_pick

Interactively pick a new phase arrival time (t1) for an event.

cli_pick_min_cc

cli_pick_min_cc(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_matrix_image: Annotated[
        bool, use_matrix_image()
    ] = True,
    _: DebugParameter = DebugParameter(),
) -> None

Interactively pick a new minimum cross-correlation for auto-selection.

Opens an interactive plot; click to set the cc threshold. Seismograms whose cross-correlation with the stack falls below this value will be automatically de-selected when running ICCS with --autoselect.

Source code in src/aimbat/_cli/pick.py
@app.command(name="cc")
@simple_exception
def cli_pick_min_cc(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_matrix_image: Annotated[bool, use_matrix_image()] = True,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Interactively pick a new minimum cross-correlation for auto-selection.

    Opens an interactive plot; click to set the cc threshold. Seismograms
    whose cross-correlation with the stack falls below this value will be
    automatically de-selected when running ICCS with `--autoselect`.
    """
    from sqlmodel import Session

    from aimbat.core import create_iccs_instance, resolve_event
    from aimbat.db import engine
    from aimbat.plot import update_min_cc

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        update_min_cc(
            session,
            event,
            iccs,
            iccs_plot_parameters.context,
            all_seismograms=iccs_plot_parameters.all_seismograms,
            return_fig=False,
        )

cli_pick_timewindow

cli_pick_timewindow(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_matrix_image: Annotated[
        bool, use_matrix_image()
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None

Interactively pick a new cross-correlation time window for an event.

Opens an interactive plot; click to set the left and right window boundaries, then close the window to save. The window controls which portion of each seismogram is used during ICCS alignment.

Source code in src/aimbat/_cli/pick.py
@app.command(name="window")
@simple_exception
def cli_pick_timewindow(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_matrix_image: Annotated[bool, use_matrix_image()] = False,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Interactively pick a new cross-correlation time window for an event.

    Opens an interactive plot; click to set the left and right window boundaries,
    then close the window to save. The window controls which portion of each
    seismogram is used during ICCS alignment.
    """
    from sqlmodel import Session

    from aimbat.core import create_iccs_instance, resolve_event
    from aimbat.db import engine
    from aimbat.plot import update_timewindow

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        update_timewindow(
            session,
            event,
            iccs,
            iccs_plot_parameters.context,
            all_seismograms=iccs_plot_parameters.all_seismograms,
            use_matrix_image=use_matrix_image,
            return_fig=False,
        )

cli_update_phase_pick

cli_update_phase_pick(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_matrix_image: Annotated[
        bool, use_matrix_image()
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None

Interactively pick a new phase arrival time (t1) for an event.

Opens an interactive plot; click to place the new pick, then close the window to save. The pick is stored as t1 for each seismogram in the ICCS instance.

Source code in src/aimbat/_cli/pick.py
@app.command(name="phase")
@simple_exception
def cli_update_phase_pick(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_matrix_image: Annotated[bool, use_matrix_image()] = False,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Interactively pick a new phase arrival time (t1) for an event.

    Opens an interactive plot; click to place the new pick, then close the window
    to save. The pick is stored as `t1` for each seismogram in the ICCS instance.
    """
    from sqlmodel import Session

    from aimbat.core import create_iccs_instance, resolve_event
    from aimbat.db import engine
    from aimbat.plot import update_pick

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        update_pick(
            session,
            iccs,
            context=iccs_plot_parameters.context,
            all_seismograms=iccs_plot_parameters.all_seismograms,
            use_matrix_image=use_matrix_image,
            return_fig=False,
        )

plot

Create plots for seismograms and ICCS results.

Available plots:

  • data: raw seismograms sorted by epicentral distance.
  • stack: the ICCS cross-correlation stack for an event.
  • matrix: seismograms displayed as a matrix image.

Most plot commands support --context / --no-context to toggle extra waveform context, and --all to include deselected seismograms.

Functions:

Name Description
cli_plot_matrix_image

Plot the ICCS seismograms of an event as a matrix image.

cli_plot_stack

Plot the ICCS stack of an event.

cli_seismogram_plot

Plot input seismograms in an event sorted by epicentral distance.

cli_plot_matrix_image

cli_plot_matrix_image(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    _: DebugParameter = DebugParameter(),
) -> None

Plot the ICCS seismograms of an event as a matrix image.

The matrix is assembled from individual waveforms, with each row representing a different seismogram.

Source code in src/aimbat/_cli/plot.py
@app.command(name="matrix")
@simple_exception
def cli_plot_matrix_image(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    _: DebugParameter = DebugParameter(),
) -> None:
    """Plot the ICCS seismograms of an event as a matrix image.

    The matrix is assembled from individual waveforms, with each row
    representing a different seismogram.
    """
    from sqlmodel import Session

    from aimbat.core import (
        create_iccs_instance,
        resolve_event,
    )
    from aimbat.db import engine
    from aimbat.plot import plot_matrix_image

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        plot_matrix_image(
            iccs,
            iccs_plot_parameters.context,
            all_seismograms=iccs_plot_parameters.all_seismograms,
            return_fig=False,
        )

cli_plot_stack

cli_plot_stack(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    _: DebugParameter = DebugParameter(),
) -> None

Plot the ICCS stack of an event.

Source code in src/aimbat/_cli/plot.py
@app.command(name="stack")
@simple_exception
def cli_plot_stack(
    event_id: Annotated[UUID, event_parameter()],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    _: DebugParameter = DebugParameter(),
) -> None:
    """Plot the ICCS stack of an event."""
    from sqlmodel import Session

    from aimbat.core import create_iccs_instance, resolve_event
    from aimbat.db import engine
    from aimbat.plot import plot_stack

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        iccs = create_iccs_instance(session, event).iccs
        plot_stack(
            iccs,
            iccs_plot_parameters.context,
            all_seismograms=iccs_plot_parameters.all_seismograms,
            return_fig=False,
        )

cli_seismogram_plot

cli_seismogram_plot(
    event_id: Annotated[UUID, event_parameter()],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Plot input seismograms in an event sorted by epicentral distance.

Source code in src/aimbat/_cli/plot.py
@app.command(name="seismograms")
@simple_exception
def cli_seismogram_plot(
    event_id: Annotated[UUID, event_parameter()],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Plot input seismograms in an event sorted by epicentral distance."""
    from sqlmodel import Session

    from aimbat.core import resolve_event
    from aimbat.db import engine
    from aimbat.plot import plot_seismograms

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        plot_seismograms(session, event, return_fig=False)

project

Manage AIMBAT projects.

This command manages projects. By default, the project consists of a file called aimbat.db in the current working directory. All aimbat commands must be executed from the same directory. The location (and name) of the project file may also be specified by setting the AIMBAT_PROJECT environment variable to the desired filename. Alternatively, aimbat can be executed with a database url directly.

Functions:

Name Description
cli_project_create

Create a new AIMBAT project in the current directory.

cli_project_delete

Delete project (note: this does not delete seismogram files).

cli_project_info

Show information on an existing project.

cli_project_create

cli_project_create(
    *, _: DebugParameter = DebugParameter()
) -> None

Create a new AIMBAT project in the current directory.

Initialises a new project database (aimbat.db by default). Run this once before adding data with aimbat data add.

Source code in src/aimbat/_cli/project.py
@app.command(name="create")
@simple_exception
def cli_project_create(*, _: DebugParameter = DebugParameter()) -> None:
    """Create a new AIMBAT project in the current directory.

    Initialises a new project database (`aimbat.db` by default). Run this
    once before adding data with `aimbat data add`.
    """
    from aimbat.core import create_project
    from aimbat.db import engine

    create_project(engine)

cli_project_delete

cli_project_delete(
    *, _: DebugParameter = DebugParameter()
) -> None

Delete project (note: this does not delete seismogram files).

Source code in src/aimbat/_cli/project.py
@app.command(name="delete")
@simple_exception
def cli_project_delete(*, _: DebugParameter = DebugParameter()) -> None:
    """Delete project (note: this does *not* delete seismogram files)."""
    from aimbat.core import delete_project
    from aimbat.db import engine

    delete_project(engine)

cli_project_info

cli_project_info(
    event_id: Annotated[
        UUID | None, event_parameter()
    ] = None,
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Show information on an existing project.

Source code in src/aimbat/_cli/project.py
@app.command(name="info")
@simple_exception
def cli_project_info(
    event_id: Annotated[UUID | None, event_parameter()] = None,
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Show information on an existing project."""

    from rich.console import Console
    from rich.panel import Panel
    from rich.table import Table
    from sqlalchemy.exc import NoResultFound
    from sqlmodel import Session, select

    import aimbat.core._event as event
    import aimbat.core._seismogram as seismogram
    import aimbat.core._station as station
    from aimbat.core import resolve_event
    from aimbat.core._project import _project_exists
    from aimbat.db import engine
    from aimbat.models import AimbatEvent, AimbatSeismogram, AimbatStation

    if not _project_exists(engine):
        raise RuntimeError(
            'No AIMBAT project found. Try running "aimbat project create" first.'
        )

    with Session(engine) as session:
        grid = Table.grid(expand=False)
        grid.add_column()
        grid.add_column(justify="left")
        if engine.driver == "pysqlite":
            if engine.url.database == ":memory:":
                grid.add_row("AIMBAT Project: ", "in-memory database")
            else:
                grid.add_row("AIMBAT Project File: ", str(engine.url.database))

        events = len(session.exec(select(AimbatEvent)).all())
        completed_events = len(event.get_completed_events(session))
        stations = len(session.exec(select(AimbatStation)).all())
        seismograms = len(session.exec(select(AimbatSeismogram)).all())
        selected_seismograms = len(
            seismogram.get_selected_seismograms(session, all_events=True)
        )

        grid.add_row(
            "Number of Events (total/completed): ",
            f"({events}/{completed_events})",
        )

        try:
            target_event = resolve_event(session, event_id)
            target_event_id = target_event.id
            active_stations = len(
                station.get_stations_in_event(session, target_event.id)
            )
            seismograms_in_event = len(target_event.seismograms)
            selected_seismograms_in_event = len(
                seismogram.get_selected_seismograms(session, event_id=target_event_id)
            )
        except (NoResultFound, ValueError, RuntimeError):
            target_event_id = None
            active_stations = None
            seismograms_in_event = None
            selected_seismograms_in_event = None

        event_label = "Selected Event ID: "
        grid.add_row(event_label, f"{target_event_id}")
        grid.add_row(
            "Number of Stations in Project (total/selected event): ",
            f"({stations}/{active_stations})",
        )

        grid.add_row(
            "Number of Seismograms in Project (total/selected): ",
            f"({seismograms}/{selected_seismograms})",
        )
        grid.add_row(
            "Number of Seismograms in Selected Event (total/selected): ",
            f"({seismograms_in_event}/{selected_seismograms_in_event})",
        )

        console = Console()
        console.print(
            Panel(grid, title="Project Info", title_align="left", border_style="dim")
        )

seismogram

View and manage seismograms in the AIMBAT project.

Functions:

Name Description
cli_seismogram_delete

Delete existing seismogram.

cli_seismogram_dump

Dump the contents of the AIMBAT seismogram table to JSON.

cli_seismogram_list

Print information on the seismograms in an event.

cli_seismogram_parameter_dump

Dump seismogram parameter table to json.

cli_seismogram_parameter_get

Get the value of a processing parameter.

cli_seismogram_parameter_list

List processing parameter values for seismograms in an event.

cli_seismogram_parameter_reset

Reset all processing parameters to their default values.

cli_seismogram_parameter_set

Set value of a processing parameter.

cli_seismogram_delete

cli_seismogram_delete(
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram,
            help="UUID (or unique prefix) of seismogram to delete.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Delete existing seismogram.

Source code in src/aimbat/_cli/seismogram.py
@app.command(name="delete")
@simple_exception
def cli_seismogram_delete(
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram, help="UUID (or unique prefix) of seismogram to delete."
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Delete existing seismogram."""
    from sqlmodel import Session

    from aimbat.core import delete_seismogram
    from aimbat.db import engine

    with Session(engine) as session:
        delete_seismogram(session, seismogram_id)

cli_seismogram_dump

cli_seismogram_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump the contents of the AIMBAT seismogram table to JSON.

Output can be piped or redirected for use in external tools or scripts.

Source code in src/aimbat/_cli/seismogram.py
@app.command(name="dump")
@simple_exception
def cli_seismogram_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None:
    """Dump the contents of the AIMBAT seismogram table to JSON.

    Output can be piped or redirected for use in external tools or scripts.
    """
    from rich import print_json
    from sqlmodel import Session

    from aimbat.core import dump_seismogram_table
    from aimbat.db import engine

    with Session(engine) as session:
        print_json(
            data=dump_seismogram_table(session, by_alias=dump_parameters.by_alias)
        )

cli_seismogram_list

cli_seismogram_list(
    event_id: Annotated[
        UUID | Literal["all"], event_parameter_with_all()
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None

Print information on the seismograms in an event.

Source code in src/aimbat/_cli/seismogram.py
@app.command(name="list")
@simple_exception
def cli_seismogram_list(
    event_id: Annotated[UUID | Literal["all"], event_parameter_with_all()],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """Print information on the seismograms in an event."""
    from sqlmodel import Session

    from aimbat.core import dump_seismogram_table, resolve_event
    from aimbat.db import engine
    from aimbat.models import AimbatSeismogramRead
    from aimbat.utils import uuid_shortener

    from .common import json_to_table

    if raw := table_parameters.raw:
        exclude = {"short_id", "short_event_id"}
    else:
        exclude = {"id", "event_id"}

    with Session(engine) as session:
        if event_parameter_is_all(event_id):
            title = "AIMBAT seismograms for all events"
            data = dump_seismogram_table(session, from_read_model=True, exclude=exclude)
        else:
            event = resolve_event(session, event_id)
            if raw:
                title = f"AIMBAT seismograms for event {event.time} (ID={event.id})"
                exclude.add("event_id")
            else:
                title = f"AIMBAT seismograms for event {event.time.strftime('%Y-%m-%d %H:%M:%S')}"
                title += f" (ID={uuid_shortener(session, event)})"
                exclude.add("short_event_id")
            data = dump_seismogram_table(
                session,
                from_read_model=True,
                event_id=event.id,
                exclude=exclude,
            )

        json_to_table(data, model=AimbatSeismogramRead, title=title, raw=raw)

cli_seismogram_parameter_dump

cli_seismogram_parameter_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump seismogram parameter table to json.

Source code in src/aimbat/_cli/seismogram.py
@parameter.command(name="dump")
@simple_exception
def cli_seismogram_parameter_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None:
    """Dump seismogram parameter table to json."""
    from rich import print_json
    from sqlmodel import Session

    from aimbat.core import dump_seismogram_parameter_table
    from aimbat.db import engine

    with Session(engine) as session:
        print_json(
            data=dump_seismogram_parameter_table(
                session, by_alias=dump_parameters.by_alias
            )
        )

cli_seismogram_parameter_get

cli_seismogram_parameter_get(
    name: SeismogramParameter,
    *,
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram,
            help="UUID (or unique prefix) of seismogram to query.",
        ),
    ],
    _: DebugParameter = DebugParameter(),
) -> None

Get the value of a processing parameter.

Parameters:

Name Type Description Default
name SeismogramParameter

Name of the seismogram parameter.

required
Source code in src/aimbat/_cli/seismogram.py
@parameter.command(name="get")
@simple_exception
def cli_seismogram_parameter_get(
    name: SeismogramParameter,
    *,
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram, help="UUID (or unique prefix) of seismogram to query."
        ),
    ],
    _: DebugParameter = DebugParameter(),
) -> None:
    """Get the value of a processing parameter.

    Args:
        name: Name of the seismogram parameter.
    """
    from sqlalchemy.exc import NoResultFound
    from sqlmodel import Session

    from aimbat.db import engine
    from aimbat.models import AimbatSeismogram

    with Session(engine) as session:
        seismogram = session.get(AimbatSeismogram, seismogram_id)
        if seismogram is None:
            raise NoResultFound(f"Unable to find seismogram with id: {seismogram_id}.")
        value = seismogram.parameters.model_dump(mode="json").get(name)
        print(value)

cli_seismogram_parameter_list

cli_seismogram_parameter_list(
    event_id: Annotated[
        UUID | Literal["all"], event_parameter_with_all()
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None

List processing parameter values for seismograms in an event.

Displays per-seismogram parameters (e.g. select, flip, t1 pick) in a table. Use seismogram parameter set to modify individual values.

Source code in src/aimbat/_cli/seismogram.py
@parameter.command(name="list")
@simple_exception
def cli_seismogram_parameter_list(
    event_id: Annotated[UUID | Literal["all"], event_parameter_with_all()],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """List processing parameter values for seismograms in an event.

    Displays per-seismogram parameters (e.g. `select`, `flip`, `t1` pick)
    in a table. Use `seismogram parameter set` to modify individual values.
    """

    from sqlmodel import Session

    from aimbat.core import dump_seismogram_parameter_table, resolve_event
    from aimbat.db import engine
    from aimbat.models import AimbatSeismogram, AimbatSeismogramParameters, RichColSpec
    from aimbat.utils import uuid_shortener
    from aimbat.utils.formatters import fmt_flip

    from .common import json_to_table

    raw = table_parameters.raw

    with Session(engine) as session:
        if event_parameter_is_all(event_id):
            event = None
            title = "Seismogram parameters for all events"
        else:
            event = resolve_event(session, event_id)
            title = f"Seismogram parameters for event: {uuid_shortener(session, event) if not raw else str(event.id)}"

        data = dump_seismogram_parameter_table(
            session, event_id=event.id if event else None
        )

        json_to_table(
            data=data,
            model=AimbatSeismogramParameters,
            title=title,
            raw=raw,
            col_specs={
                "id": RichColSpec(
                    style="yellow",
                    no_wrap=True,
                    highlight=False,
                    formatter=lambda x: uuid_shortener(
                        session, AimbatSeismogramParameters, str_uuid=str(x)
                    ),
                ),
                "seismogram_id": RichColSpec(
                    style="magenta",
                    no_wrap=True,
                    highlight=False,
                    formatter=lambda x: uuid_shortener(
                        session, AimbatSeismogram, str_uuid=str(x)
                    ),
                ),
                "flip": RichColSpec(formatter=fmt_flip),
            },
            column_order=["id"],
        )

cli_seismogram_parameter_reset

cli_seismogram_parameter_reset(
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram,
            help="UUID (or unique prefix) of seismogram to reset parameters for.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Reset all processing parameters to their default values.

Source code in src/aimbat/_cli/seismogram.py
@parameter.command(name="reset")
@simple_exception
def cli_seismogram_parameter_reset(
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram,
            help="UUID (or unique prefix) of seismogram to reset parameters for.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Reset all processing parameters to their default values."""
    from sqlmodel import Session

    from aimbat.core import reset_seismogram_parameters
    from aimbat.db import engine

    with Session(engine) as session:
        reset_seismogram_parameters(session, seismogram_id)

cli_seismogram_parameter_set

cli_seismogram_parameter_set(
    name: SeismogramParameter,
    value: str,
    *,
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram,
            help="UUID (or unique prefix) of seismogram to modify.",
        ),
    ],
    _: DebugParameter = DebugParameter(),
) -> None

Set value of a processing parameter.

Parameters:

Name Type Description Default
name SeismogramParameter

Name of the seismogram parameter.

required
value str

Value of the seismogram parameter.

required
Source code in src/aimbat/_cli/seismogram.py
@parameter.command(name="set")
@simple_exception
def cli_seismogram_parameter_set(
    name: SeismogramParameter,
    value: str,
    *,
    seismogram_id: Annotated[
        UUID,
        id_parameter(
            AimbatSeismogram, help="UUID (or unique prefix) of seismogram to modify."
        ),
    ],
    _: DebugParameter = DebugParameter(),
) -> None:
    """Set value of a processing parameter.

    Args:
        name: Name of the seismogram parameter.
        value: Value of the seismogram parameter.
    """
    from sqlmodel import Session

    from aimbat.core import set_seismogram_parameter
    from aimbat.db import engine

    with Session(engine) as session:
        set_seismogram_parameter(session, seismogram_id, name, value)

shell

Interactive AIMBAT shell with tab-completion and command history.

All CLI commands are available. Press Tab to complete commands, Ctrl+D or type exit to leave.

Shell-only commands

event switch [ID] Switch the shell's event context.

Functions:

Name Description
cli_shell

Start an interactive AIMBAT shell.

cli_shell

cli_shell(
    event_id: Annotated[
        UUID | None,
        event_parameter(
            help="Start the shell in the context of a specific event. Full UUID or any unique prefix as shown in the table. "
        ),
    ] = None,
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Start an interactive AIMBAT shell.

Source code in src/aimbat/_cli/shell.py
@app.default
@simple_exception
def cli_shell(
    event_id: Annotated[
        uuid.UUID | None,
        event_parameter(
            help="Start the shell in the context of a specific event. "
            "Full UUID or any unique prefix as shown in the table. "
        ),
    ] = None,
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Start an interactive AIMBAT shell."""
    import os
    import shlex
    from pathlib import Path

    from cyclopts import CycloptsError
    from prompt_toolkit import PromptSession
    from prompt_toolkit.completion import NestedCompleter
    from prompt_toolkit.history import FileHistory
    from rich.console import Console

    from aimbat.app import app as aimbat_app

    console = Console()

    # Shell-local event context — None if no event specified.
    # Modified by `event switch`.
    shell_event_id: uuid.UUID | None = event_id

    # Propagate the shell event context to commands via the DEFAULT_EVENT_ID env
    # var, which all event_parameter() / event_parameter_with_all() converters
    # pick up as a fallback.  Explicit --event flags always take precedence.
    _prev_default_event = os.environ.get("DEFAULT_EVENT_ID")

    def _set_shell_event(eid: uuid.UUID | None) -> None:
        nonlocal shell_event_id
        shell_event_id = eid
        if eid is not None:
            os.environ["DEFAULT_EVENT_ID"] = str(eid)
        else:
            os.environ.pop("DEFAULT_EVENT_ID", None)

    _set_shell_event(shell_event_id)

    completion_dict = _build_completion_dict(aimbat_app)
    completion_dict.pop("shell", None)
    completion_dict.pop("tui", None)

    # Inject the shell-only `event switch` subcommand into tab completion.
    event_completions = completion_dict.get("event")
    if isinstance(event_completions, dict):
        event_completions["switch"] = None

    import sys

    pt_session: PromptSession[str] | None = None
    if sys.stdin.isatty():
        pt_session = PromptSession(
            history=FileHistory(str(Path.home() / ".aimbat_history")),
            completer=NestedCompleter.from_nested_dict(completion_dict),
            complete_while_typing=True,
        )

    console.print(
        "[bold]AIMBAT shell[/bold]  (Tab to complete, Ctrl+D or [bold]exit[/bold] to quit)"
    )

    current_bound = _check_iccs(console, None, startup=True, event_id=shell_event_id)

    def _prompt() -> str:
        if shell_event_id is not None:
            return f"aimbat [{str(shell_event_id)[:8]}]> "
        return "aimbat> "

    try:
        while True:
            try:
                if pt_session is not None:
                    text = pt_session.prompt(_prompt).strip()
                else:
                    raw = sys.stdin.readline()
                    if not raw:
                        break
                    text = raw.strip()
            except KeyboardInterrupt:
                continue
            except EOFError:
                break

            if not text:
                continue
            if text in ("exit", "quit", "q"):
                break

            try:
                tokens = shlex.split(text)
            except ValueError as exc:
                console.print(f"[red]Parse error:[/red] {exc}")
                continue

            # Strip a leading "aimbat" token typed out of habit and remind the user.
            if tokens and tokens[0] == "aimbat":
                tokens = tokens[1:]
                console.print("[dim]Tip: no need to type 'aimbat' in the shell.[/dim]")
                if not tokens:
                    continue

            # Shell-only: event switch [id]  — changes context.
            if tokens[:2] == ["event", "switch"]:
                if len(tokens) < 3:
                    # No argument: clear shell event context.
                    _set_shell_event(None)
                    current_bound = _check_iccs(
                        console, None, startup=True, event_id=None
                    )
                else:
                    try:
                        _set_shell_event(_parse_event_id(tokens[2]))
                        current_bound = _check_iccs(
                            console, None, startup=True, event_id=shell_event_id
                        )
                    except Exception as exc:
                        print_error_panel(exc)
                continue

            try:
                aimbat_app(tokens, exit_on_error=False)

                # Check ICCS for the event targeted by the command.  If the
                # user passed --event all (or no explicit flag), fall back to
                # the shell context event.
                explicit_flag = _extract_event_flag(tokens)
                check_event_id: uuid.UUID | None
                if explicit_flag and explicit_flag.lower() != "all":
                    check_event_id = _parse_event_id(explicit_flag)
                else:
                    check_event_id = shell_event_id
                current_bound = _check_iccs(
                    console, current_bound, event_id=check_event_id
                )
            except (CycloptsError, SystemExit):
                # Errors already printed by Cyclopts or subcommand
                pass
            except Exception as exc:
                print_error_panel(exc)
    finally:
        # Restore DEFAULT_EVENT_ID to whatever it was before the shell started.
        if _prev_default_event is not None:
            os.environ["DEFAULT_EVENT_ID"] = _prev_default_event
        else:
            os.environ.pop("DEFAULT_EVENT_ID", None)

snapshot

View and manage snapshots of processing parameters.

A snapshot captures the current event and seismogram processing parameters (e.g. time window, bandpass filter, picks) so they can be restored later. Use snapshot create before making experimental changes, and snapshot rollback to undo them if needed.

Functions:

Name Description
cli_snapshot_create

Create a new snapshot of current processing parameters.

cli_snapshot_delete

Delete existing snapshot.

cli_snapshot_details

Print information on the event parameters saved in a snapshot.

cli_snapshot_dump

Dump the contents of the AIMBAT snapshot tables to json.

cli_snapshot_list

Print information on the snapshots for an event.

cli_snapshot_preview

Preview the ICCS stack/matrix of a snapshot.

cli_snapshot_rollback

Rollback to snapshot.

cli_snapshot_create

cli_snapshot_create(
    event_id: Annotated[UUID, event_parameter()],
    comment: str | None = None,
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Create a new snapshot of current processing parameters.

Saves the current event and seismogram parameters for an event so they can be restored later with snapshot rollback.

Parameters:

Name Type Description Default
comment str | None

Optional description to help identify this snapshot later.

None
Source code in src/aimbat/_cli/snapshot.py
@app.command(name="create")
@simple_exception
def cli_snapshot_create(
    event_id: Annotated[UUID, event_parameter()],
    comment: str | None = None,
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Create a new snapshot of current processing parameters.

    Saves the current event and seismogram parameters for an event so
    they can be restored later with `snapshot rollback`.

    Args:
        comment: Optional description to help identify this snapshot later.
    """
    from sqlmodel import Session

    from aimbat.core import create_snapshot, resolve_event
    from aimbat.db import engine

    with Session(engine) as session:
        event = resolve_event(session, event_id)
        create_snapshot(session, event, comment)

cli_snapshot_delete

cli_snapshot_delete(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to delete.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Delete existing snapshot.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="delete")
@simple_exception
def cli_snapshot_delete(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to delete.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Delete existing snapshot."""
    from sqlmodel import Session

    from aimbat.core import delete_snapshot
    from aimbat.db import engine

    with Session(engine) as session:
        delete_snapshot(session, snapshot_id)

cli_snapshot_details

cli_snapshot_details(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to show details for.",
        ),
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None

Print information on the event parameters saved in a snapshot.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="details")
@simple_exception
def cli_snapshot_details(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to show details for.",
        ),
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """Print information on the event parameters saved in a snapshot."""
    from sqlmodel import Session

    from aimbat.db import engine
    from aimbat.models import AimbatEventParametersSnapshot
    from aimbat.utils import uuid_shortener

    from .common import json_to_table

    with Session(engine) as session:
        snapshot = session.get(AimbatSnapshot, snapshot_id)

        if snapshot is None:
            raise ValueError(
                f"Unable to print snapshot parameters: snapshot with id={snapshot_id} not found."
            )

        raw = table_parameters.raw

        if raw:
            title = f"Saved event parameters in snapshot: {snapshot.id}"
        else:
            title = f"Saved event parameters in snapshot: {uuid_shortener(session, snapshot)}"

        parameters_snapshot = snapshot.event_parameters_snapshot

        json_to_table(
            data=parameters_snapshot.model_dump(
                mode="json", exclude={"id", "snapshot_id", "parameters_id"}
            ),
            model=AimbatEventParametersSnapshot,
            title=title,
            key_header="Parameter",
        )

cli_snapshot_dump

cli_snapshot_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump the contents of the AIMBAT snapshot tables to json.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="dump")
@simple_exception
def cli_snapshot_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None:
    """Dump the contents of the AIMBAT snapshot tables to json."""
    from rich import print_json
    from sqlmodel import Session

    from aimbat.core import (
        dump_event_parameter_snapshot_table,
        dump_event_quality_snapshot_table,
        dump_seismogram_parameter_snapshot_table,
        dump_seismogram_quality_snapshot_table,
        dump_snapshot_table,
    )
    from aimbat.db import engine

    with Session(engine) as session:
        data = {
            "snapshots": dump_snapshot_table(
                session, by_alias=dump_parameters.by_alias
            ),
            "event_parameters": dump_event_parameter_snapshot_table(
                session, by_alias=dump_parameters.by_alias
            ),
            "seismogram_parameters": dump_seismogram_parameter_snapshot_table(
                session, by_alias=dump_parameters.by_alias
            ),
            "event_quality": dump_event_quality_snapshot_table(
                session, by_alias=dump_parameters.by_alias
            ),
            "seismogram_quality": dump_seismogram_quality_snapshot_table(
                session, by_alias=dump_parameters.by_alias
            ),
        }
        print_json(data=data)

cli_snapshot_list

cli_snapshot_list(
    event_id: Annotated[
        UUID | Literal["all"], event_parameter_with_all()
    ],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None

Print information on the snapshots for an event.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="list")
@simple_exception
def cli_snapshot_list(
    event_id: Annotated[UUID | Literal["all"], event_parameter_with_all()],
    *,
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """Print information on the snapshots for an event."""
    from sqlmodel import Session

    from aimbat.core import dump_snapshot_table, resolve_event
    from aimbat.db import engine
    from aimbat.logger import logger
    from aimbat.models import AimbatSnapshotRead
    from aimbat.utils import uuid_shortener

    from .common import json_to_table

    if raw := table_parameters.raw:
        exclude = {"short_id", "short_event_id"}
    else:
        exclude = {"id", "event_id"}

    with Session(engine) as session:
        logger.info("Printing AIMBAT snapshots table.")

        if event_parameter_is_all(event_id):
            event = None
            title = "AIMBAT snapshots for all events"
        else:
            event = resolve_event(session, event_id)
            if raw:
                time = event.time.isoformat()
                id = str(event.id)
                exclude.add("event_id")
            else:
                time = event.time.strftime("%Y-%m-%d %H:%M:%S")
                id = uuid_shortener(session, event)
                exclude.add("short_event_id")
            title = f"AIMBAT snapshots for event {time} (ID={id})"

        snapshot_data = dump_snapshot_table(
            session,
            from_read_model=True,
            event_id=event.id if event else None,
            exclude=exclude,
        )

        json_to_table(
            data=snapshot_data, model=AimbatSnapshotRead, title=title, raw=raw
        )

cli_snapshot_preview

cli_snapshot_preview(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to preview.",
        ),
    ],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    as_matrix: Annotated[
        bool, Parameter(name=matrix)
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None

Preview the ICCS stack/matrix of a snapshot.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="preview")
@simple_exception
def cli_snapshot_preview(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot, help="UUID (or unique prefix) of snapshot to preview."
        ),
    ],
    *,
    iccs_plot_parameters: IccsPlotParameters = IccsPlotParameters(),
    as_matrix: Annotated[bool, Parameter(name="matrix")] = False,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Preview the ICCS stack/matrix of a snapshot."""
    from sqlmodel import Session

    from aimbat.core import build_iccs_from_snapshot
    from aimbat.db import engine
    from aimbat.plot import plot_matrix_image, plot_stack

    with Session(engine) as session:
        iccs = build_iccs_from_snapshot(session, snapshot_id).iccs
        if as_matrix:
            plot_matrix_image(
                iccs,
                iccs_plot_parameters.context,
                all_seismograms=iccs_plot_parameters.all_seismograms,
                return_fig=False,
            )
        else:
            plot_stack(
                iccs,
                iccs_plot_parameters.context,
                all_seismograms=iccs_plot_parameters.all_seismograms,
                return_fig=False,
            )

cli_snapshot_rollback

cli_snapshot_rollback(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to use for rollback.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Rollback to snapshot.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="rollback")
@simple_exception
def cli_snapshot_rollback(
    snapshot_id: Annotated[
        UUID,
        id_parameter(
            AimbatSnapshot,
            help="UUID (or unique prefix) of snapshot to use for rollback.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Rollback to snapshot."""
    from sqlmodel import Session

    from aimbat.core import rollback_to_snapshot
    from aimbat.db import engine

    with Session(engine) as session:
        rollback_to_snapshot(session, snapshot_id)

station

View and manage stations.

Functions:

Name Description
cli_station_delete

Delete existing station (for all events).

cli_station_dump

Dump the contents of the AIMBAT station table to JSON.

cli_station_list

Print information on the stations used in an event.

cli_station_seismograms_plot

Plot input seismograms for events recorded at this station.

cli_station_delete

cli_station_delete(
    station_id: Annotated[
        UUID,
        id_parameter(
            AimbatStation,
            help="UUID (or unique prefix) of station to delete.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Delete existing station (for all events).

Source code in src/aimbat/_cli/station.py
@app.command(name="delete")
@simple_exception
def cli_station_delete(
    station_id: Annotated[
        UUID,
        id_parameter(
            AimbatStation,
            help="UUID (or unique prefix) of station to delete.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Delete existing station (for all events)."""
    from sqlmodel import Session

    from aimbat.core import delete_station
    from aimbat.db import engine

    with Session(engine) as session:
        delete_station(session, station_id)

cli_station_dump

cli_station_dump(
    *,
    dump_parameters: JsonDumpParameters = JsonDumpParameters(),
) -> None

Dump the contents of the AIMBAT station table to JSON.

Output can be piped or redirected for use in external tools or scripts.

Source code in src/aimbat/_cli/station.py
@app.command(name="dump")
@simple_exception
def cli_station_dump(
    *, dump_parameters: JsonDumpParameters = JsonDumpParameters()
) -> None:
    """Dump the contents of the AIMBAT station table to JSON.

    Output can be piped or redirected for use in external tools or scripts.
    """

    from rich import print_json
    from sqlmodel import Session

    from aimbat.core import dump_station_table
    from aimbat.db import engine

    with Session(engine) as session:
        print_json(data=dump_station_table(session, by_alias=dump_parameters.by_alias))

cli_station_list

cli_station_list(
    event_id: Annotated[
        UUID | Literal["all"], event_parameter_with_all()
    ],
    table_parameters: TableParameters = TableParameters(),
) -> None

Print information on the stations used in an event.

Source code in src/aimbat/_cli/station.py
@app.command(name="list")
@simple_exception
def cli_station_list(
    event_id: Annotated[UUID | Literal["all"], event_parameter_with_all()],
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """Print information on the stations used in an event."""
    from sqlmodel import Session

    from aimbat.core import dump_station_table, resolve_event
    from aimbat.db import engine
    from aimbat.logger import logger
    from aimbat.models import AimbatStationRead
    from aimbat.utils import uuid_shortener

    from .common import json_to_table

    if raw := table_parameters.raw:
        exclude = {"short_id"}
    else:
        exclude = {"id"}

    with Session(engine) as session:
        if event_parameter_is_all(event_id):
            logger.debug("Selecting all AIMBAT stations.")
            data = dump_station_table(session, from_read_model=True, exclude=exclude)
            title = "AIMBAT stations for all events"
        else:
            logger.debug("Selecting AIMBAT stations used by event.")
            event = resolve_event(session, event_id)
            data = dump_station_table(
                session,
                event_id=event.id,
                from_read_model=True,
                exclude={"seismogram_count", "event_count"} | exclude,
            )
            if raw:
                title = f"AIMBAT stations for event {event.time} (ID={event.id})"
            else:
                title = f"AIMBAT stations for event {event.time.strftime('%Y-%m-%d %H:%M:%S')} (ID={uuid_shortener(session, event)})"

        json_to_table(data, model=AimbatStationRead, title=title, raw=raw)

cli_station_seismograms_plot

cli_station_seismograms_plot(
    station_id: Annotated[
        UUID,
        id_parameter(
            AimbatStation,
            help="UUID (or unique prefix) of station to plot seismograms for.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None

Plot input seismograms for events recorded at this station.

Source code in src/aimbat/_cli/station.py
@app.command(name="plotseis")
@simple_exception
def cli_station_seismograms_plot(
    station_id: Annotated[
        UUID,
        id_parameter(
            AimbatStation,
            help="UUID (or unique prefix) of station to plot seismograms for.",
        ),
    ],
    *,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Plot input seismograms for events recorded at this station."""
    from sqlmodel import Session

    from aimbat.db import engine
    from aimbat.models import AimbatStation
    from aimbat.plot import plot_seismograms

    with Session(engine) as session:
        station = session.get(AimbatStation, station_id)
        if station is None:
            raise ValueError(f"Station with ID {station_id} not found.")
        plot_seismograms(session, station, return_fig=False)

utils

Utilities for AIMBAT.

Modules:

Name Description
app

Utilities for AIMBAT.

sampledata

Download or delete AIMBAT sample data.

app

Utilities for AIMBAT.

The utils subcommand contains useful tools that are not strictly part of an AIMBAT workflow.

sampledata

Download or delete AIMBAT sample data.

The sampledata subcommand manages an example dataset that can be used for testing or learning how to use AIMBAT.

The sample data source url can be viewed or changed via aimbat default <list/set> sampledata_src. Likewise the sample data destination folder be viewed or changed via aimbat default <list/set> sampledata_dir.

Functions:

Name Description
sampledata_cli_delete

Recursively delete sample data directory.

sampledata_cli_download

Download AIMBAT sample data.

sampledata_cli_delete

sampledata_cli_delete(
    *, _: DebugParameter = DebugParameter()
) -> None

Recursively delete sample data directory.

Source code in src/aimbat/_cli/utils/sampledata.py
@app.command(name="delete")
@simple_exception
def sampledata_cli_delete(*, _: DebugParameter = DebugParameter()) -> None:
    """Recursively delete sample data directory."""
    from aimbat.utils import delete_sampledata

    delete_sampledata()

sampledata_cli_download

sampledata_cli_download(
    *,
    force: Annotated[
        bool,
        Parameter(
            help="Delete the download directory and re-download"
        ),
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None

Download AIMBAT sample data.

Downloads an example dataset to the directory specified in the sampledata_dir AIMBAT default variable.

Source code in src/aimbat/_cli/utils/sampledata.py
@app.command(name="download")
@simple_exception
def sampledata_cli_download(
    *,
    force: Annotated[
        bool, Parameter(help="Delete the download directory and re-download")
    ] = False,
    _: DebugParameter = DebugParameter(),
) -> None:
    """Download AIMBAT sample data.

    Downloads an example dataset to the directory specified in the
    `sampledata_dir` AIMBAT default variable.
    """
    from aimbat.utils import download_sampledata

    download_sampledata(force)