Skip to content

aimbat._cli

Modules:

Name Description
align

Align seismograms using ICCS or MCCC.

common

Common parameters and functions for the AIMBAT CLI.

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.

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 the default event.

cli_mccc_run

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

cli_iccs_run

cli_iccs_run(
    *,
    autoflip: bool = False,
    autoselect: bool = False,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Run the ICCS algorithm to align seismograms for the default 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.

Parameters:

Name Type Description Default
autoflip bool

Whether to automatically flip seismograms (multiply data by -1) when the cross-correlation is negative.

False
autoselect bool

Whether to automatically de-select seismograms whose cross-correlation with the stack falls below min_ccnorm.

False
Source code in src/aimbat/_cli/align.py
@app.command(name="iccs")
@simple_exception
def cli_iccs_run(
    *,
    autoflip: bool = False,
    autoselect: bool = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Run the ICCS algorithm to align seismograms for the default 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.

    Args:
        autoflip: Whether to automatically flip seismograms (multiply data by -1)
            when the cross-correlation is negative.
        autoselect: Whether to automatically de-select seismograms whose
            cross-correlation with the stack falls below `min_ccnorm`.
    """
    from aimbat.db import engine
    from aimbat.core import create_iccs_instance, run_iccs, resolve_event
    from sqlmodel import Session

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

cli_mccc_run

cli_mccc_run(
    *,
    all_seismograms: Annotated[
        bool, Parameter(name=all)
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

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

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

Parameters:

Name Type Description Default
all_seismograms Annotated[bool, Parameter(name=all)]

Include all seismograms in MCCC processing, not just the currently selected ones.

False
Source code in src/aimbat/_cli/align.py
@app.command(name="mccc")
@simple_exception
def cli_mccc_run(
    *,
    all_seismograms: Annotated[bool, Parameter(name="all")] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Run the MCCC algorithm to refine arrival time picks for the default event.

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

    Args:
        all_seismograms: Include all seismograms in MCCC processing, not just
            the currently selected ones.
    """
    from aimbat.db import engine
    from aimbat.core import create_iccs_instance, run_mccc, resolve_event
    from sqlmodel import Session

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

common

Common parameters and functions for the AIMBAT CLI.

Classes:

Name Description
CliHints

Hints for error messages.

DebugTrait

DebugTrait(debug: bool = False)

EventContextTrait

EventContextTrait(event_id: Annotated[uuid.UUID | None, Parameter(name=('event', 'event-id'), converter=, help='Process a specific event instead of the default one. Full UUID or any unique prefix as shown in the table.')] = None)

GlobalParameters

GlobalParameters(event_id: Annotated[uuid.UUID | None, Parameter(name=('event', 'event-id'), converter=, help='Process a specific event instead of the default one. Full UUID or any unique prefix as shown in the table.')] = None, debug: bool = False)

IccsPlotParameters

IccsPlotParameters(context: bool = True, all: bool = False)

TableParameters

TableParameters(short: bool = True)

Functions:

Name Description
id_parameter

Create a Parameter for a record ID with automatic UUID prefix resolution.

simple_exception

Decorator to handle exceptions and print them to the console.

use_event_parameter

Create a Parameter for --use-event with automatic UUID prefix resolution.

use_station_parameter

Create a Parameter for --use-station with automatic UUID prefix resolution.

CliHints dataclass

Hints for error messages.

Source code in src/aimbat/_cli/common.py
@dataclass(frozen=True)
class CliHints:
    """Hints for error messages."""

    SET_DEFAULT_EVENT = (
        "Hint: set a default event with `aimbat event default <EVENT_ID>`."
    )
    LIST_EVENTS = "Hint: view available events with `aimbat event list`."

DebugTrait dataclass

DebugTrait(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.py
@Parameter(name="*")
@dataclass
class DebugTrait:
    debug: bool = False
    """Enable verbose logging for troubleshooting."""

    # NOTE: only one __post_init__ is allowed per dataclass
    def __post_init__(self) -> None:
        if self.debug:
            settings.log_level = "DEBUG"
            from aimbat.logger import configure_logging

            configure_logging()

debug class-attribute instance-attribute

debug: bool = False

Enable verbose logging for troubleshooting.

EventContextTrait dataclass

EventContextTrait(event_id: Annotated[uuid.UUID | None, Parameter(name=('event', 'event-id'), converter=, help='Process a specific event instead of the default one. Full UUID or any unique prefix as shown in the table.')] = None)

Parameters:

Name Type Description Default
event_id UUID | None
None
Source code in src/aimbat/_cli/common.py
@Parameter(name="*")
@dataclass
class EventContextTrait:
    event_id: Annotated[
        uuid.UUID | None,
        Parameter(
            name=["event", "event-id"],
            help="Process a specific event instead of the default one. "
            "Full UUID or any unique prefix as shown in the table.",
            converter=_event_id_converter,
        ),
    ] = None

GlobalParameters dataclass

Bases: DebugTrait, EventContextTrait

GlobalParameters(event_id: Annotated[uuid.UUID | None, Parameter(name=('event', 'event-id'), converter=, help='Process a specific event instead of the default one. Full UUID or any unique prefix as shown in the table.')] = None, debug: bool = False)

Parameters:

Name Type Description Default
event_id UUID | None
None
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.py
@dataclass
class GlobalParameters(DebugTrait, EventContextTrait):
    pass

debug class-attribute instance-attribute

debug: bool = False

Enable verbose logging for troubleshooting.

IccsPlotParameters dataclass

IccsPlotParameters(context: bool = True, all: bool = False)

Parameters:

Name Type Description Default
context bool

Plot seismograms with extra context instead of the short tapered ones used for cross-correlation.

True
all bool

Include all seismograms in the plot, even if not used in stack.

False

Attributes:

Name Type Description
all bool

Include all seismograms in the plot, even if not used in stack.

context bool

Plot seismograms with extra context instead of the short tapered ones used for cross-correlation.

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

all class-attribute instance-attribute

all: bool = False

Include all seismograms in the plot, even if not used in stack.

context class-attribute instance-attribute

context: bool = True

Plot seismograms with extra context instead of the short tapered ones used for cross-correlation.

TableParameters dataclass

TableParameters(short: bool = True)

Parameters:

Name Type Description Default
short bool

Shorten UUIDs and format data.

True

Attributes:

Name Type Description
short bool

Shorten UUIDs and format data.

Source code in src/aimbat/_cli/common.py
@Parameter(name="*")
@dataclass
class TableParameters:
    short: bool = True
    "Shorten UUIDs and format data."

short class-attribute instance-attribute

short: bool = True

Shorten UUIDs and format data.

id_parameter

id_parameter(model_class: type) -> Parameter

Create a Parameter for a record ID with automatic UUID prefix resolution.

Source code in src/aimbat/_cli/common.py
def id_parameter(model_class: type) -> Parameter:
    """Create a Parameter for a record ID with automatic UUID prefix resolution."""
    return Parameter(
        name="id",
        help="Full UUID or any unique prefix as shown in the table.",
        converter=_make_uuid_converter(model_class),
    )

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.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.
    """
    from functools import wraps
    from rich.console import Console
    from rich.panel import Panel
    import sys

    @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:
            console = Console()
            panel = Panel(
                f"{e}",
                title="Error",
                title_align="left",
                border_style="red",
                expand=True,
            )
            console.print(panel)
            sys.exit(1)

    return wrapper  # type: ignore

use_event_parameter

use_event_parameter(model_class: type) -> Parameter

Create a Parameter for --use-event with automatic UUID prefix resolution.

Source code in src/aimbat/_cli/common.py
def use_event_parameter(model_class: type) -> Parameter:
    """Create a Parameter for --use-event with automatic UUID prefix resolution."""
    return Parameter(
        name="use-event",
        help="UUID (or unique prefix) of an existing event to link to instead of"
        " extracting one from each data source.",
        converter=_make_uuid_converter(model_class),
    )

use_station_parameter

use_station_parameter(model_class: type) -> Parameter

Create a Parameter for --use-station with automatic UUID prefix resolution.

Source code in src/aimbat/_cli/common.py
def use_station_parameter(model_class: type) -> Parameter:
    """Create a Parameter for --use-station with automatic UUID prefix resolution."""
    return Parameter(
        name="use-station",
        help="UUID (or unique prefix) of an existing station to link to instead of"
        " extracting one from each data source.",
        converter=_make_uuid_converter(model_class),
    )

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          # find the event ID
aimbat event default <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 the contents of the AIMBAT data source table to JSON.

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,
            consume_multiple=True,
            validator=Path(exists=True),
        ),
    ],
    *,
    data_type: Annotated[
        DataType, Parameter(name=type)
    ] = SAC,
    station_id: Annotated[
        UUID | None, use_station_parameter(AimbatStation)
    ] = None,
    event_id: Annotated[
        UUID | None, use_event_parameter(AimbatEvent)
    ] = None,
    dry_run: Annotated[
        bool, Parameter(name=dry - run)
    ] = False,
    show_progress_bar: Annotated[
        bool, Parameter(name=progress)
    ] = True,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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.

Parameters:

Name Type Description Default
data_sources Annotated[list[Path], Parameter(name=sources, consume_multiple=True, validator=Path(exists=True))]

One or more data source paths to add.

required
data_type Annotated[DataType, Parameter(name=type)]

Format of the data sources. Determines which metadata (station, event, seismogram) can be extracted automatically.

SAC
dry_run Annotated[bool, Parameter(name=dry - run)]

Preview which records would be added without modifying the database.

False
show_progress_bar Annotated[bool, Parameter(name=progress)]

Display a progress bar while ingesting sources.

True
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",
            consume_multiple=True,
            validator=validators.Path(exists=True),
        ),
    ],
    *,
    data_type: Annotated[DataType, Parameter(name="type")] = DataType.SAC,
    station_id: Annotated[
        uuid.UUID | None, use_station_parameter(AimbatStation)
    ] = None,
    event_id: Annotated[uuid.UUID | None, use_event_parameter(AimbatEvent)] = None,
    dry_run: Annotated[bool, Parameter(name="dry-run")] = False,
    show_progress_bar: Annotated[bool, Parameter(name="progress")] = True,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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.

    Args:
        data_sources: One or more data source paths to add.
        data_type: Format of the data sources. Determines which metadata
            (station, event, seismogram) can be extracted automatically.
        dry_run: Preview which records would be added without modifying the
            database.
        show_progress_bar: Display a progress bar while ingesting sources.
    """
    from aimbat.db import engine
    from aimbat.core import add_data_to_project

    disable_progress_bar = not show_progress_bar

    with Session(engine) as session:
        add_data_to_project(
            session,
            data_sources,
            data_type,
            station_id=station_id,
            event_id=event_id,
            dry_run=dry_run,
            disable_progress_bar=disable_progress_bar,
        )

cli_data_dump

cli_data_dump(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Dump the contents of the AIMBAT data source table to JSON.

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(
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Dump the contents of the AIMBAT data source table to JSON.

    Output can be piped or redirected for use in external tools or scripts.
    """
    from aimbat.db import engine
    from aimbat.core import dump_data_table_to_json
    from rich import print_json

    with Session(engine) as session:
        print_json(dump_data_table_to_json(session))

cli_data_list

cli_data_list(
    *,
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *,
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Print a table of data sources registered in the AIMBAT project."""
    from aimbat.db import engine
    from aimbat.core import resolve_event, get_data_for_event
    from aimbat.utils import uuid_shortener, make_table, TABLE_STYLING
    from aimbat.logger import logger
    from rich.console import Console

    short = table_parameters.short

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

        if all_events:
            aimbat_data_sources = session.exec(select(AimbatDataSource)).all()
            title = "Data sources for all events"
        else:
            event = resolve_event(session, global_parameters.event_id)
            aimbat_data_sources = get_data_for_event(session, event)
            time = event.time.strftime("%Y-%m-%d %H:%M:%S") if short else event.time
            id = uuid_shortener(session, event) if short else event.id
            title = f"Data sources for event {time} (ID={id})"

        logger.debug(f"Found {len(aimbat_data_sources)} data sources in total.")

        rows = [
            [
                uuid_shortener(session, a) if short else str(a.id),
                str(a.datatype),
                str(a.sourcename),
                (
                    uuid_shortener(session, a.seismogram)
                    if short
                    else str(a.seismogram.id)
                ),
            ]
            for a in aimbat_data_sources
        ]

        table = make_table(title=title)

        table.add_column(
            "ID (shortened)" if short else "ID",
            justify="center",
            style=TABLE_STYLING.id,
            no_wrap=True,
        )
        table.add_column("Datatype", justify="center", style=TABLE_STYLING.mine)
        table.add_column(
            "Source", justify="left", style=TABLE_STYLING.mine, no_wrap=True
        )
        table.add_column(
            "Seismogram ID", justify="center", style=TABLE_STYLING.linked, no_wrap=True
        )

        for row in rows:
            table.add_row(*row)

        console = Console()
        console.print(table)

event

View and manage events in the AIMBAT project.

Functions:

Name Description
cli_event_default

Select the event to be default for processing.

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 values for the default event.

cli_event_parameter_set

Set parameter value for an event.

cli_event_default

cli_event_default(
    new_default_event_id: Annotated[
        UUID, id_parameter(AimbatEvent)
    ],
    *,
    global_parameters: DebugTrait = DebugTrait()
) -> None

Select the event to be default for processing.

Source code in src/aimbat/_cli/event.py
@app.command(name="default")
@simple_exception
def cli_event_default(
    new_default_event_id: Annotated[uuid.UUID, id_parameter(AimbatEvent)],
    *,
    global_parameters: DebugTrait = DebugTrait(),
) -> None:
    """Select the event to be default for processing."""
    from aimbat.core import set_default_event_by_id
    from aimbat.db import engine

    with Session(engine) as session:
        set_default_event_by_id(session, new_default_event_id)

cli_event_delete

cli_event_delete(
    event_id: Annotated[UUID, id_parameter(AimbatEvent)],
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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, id_parameter(AimbatEvent)],
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Delete existing event."""
    from aimbat.db import engine
    from aimbat.core import delete_event_by_id

    with Session(engine) as session:
        delete_event_by_id(session, event_id)

cli_event_dump

cli_event_dump(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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 aimbat.db import engine
    from aimbat.core import dump_event_table_to_json
    from rich import print_json

    with Session(engine) as session:
        print_json(dump_event_table_to_json(session))

cli_event_list

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

Print a table of events stored in the AIMBAT project.

The default event is highlighted. Use event default to change which event is processed by subsequent commands.

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

    The default event is highlighted. Use `event default` to change which event
    is processed by subsequent commands.
    """
    from aimbat.db import engine
    from aimbat.core import dump_event_table_to_json
    from aimbat.utils import uuid_shortener, json_to_table, TABLE_STYLING
    from aimbat.logger import logger
    from pandas import Timestamp

    short = table_parameters.short

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

        json_to_table(
            data=dump_event_table_to_json(session, as_string=False),
            title="AIMBAT Events",
            column_order=[
                "id",
                "is_default",
                "time",
                "latitude",
                "longitude",
                "depth",
                "completed",
                "seismogram_count",
                "station_count",
            ],
            formatters={
                "id": lambda x: (
                    uuid_shortener(session, AimbatEvent, str_uuid=x) if short else x
                ),
                "is_default": TABLE_STYLING.bool_formatter,
                "time": lambda x: TABLE_STYLING.timestamp_formatter(
                    Timestamp(x), short
                ),
                "latitude": lambda x: f"{x:.3f}" if short else str(x),
                "longitude": lambda x: f"{x:.3f}" if short else str(x),
                "depth": lambda x: f"{x:.0f}" if short and x is not None else str(x),
                "completed": TABLE_STYLING.bool_formatter,
                "last_modified": lambda x: TABLE_STYLING.timestamp_formatter(
                    Timestamp(x), short
                ),
            },
            common_column_kwargs={"justify": "center"},
            column_kwargs={
                "id": {
                    "header": "ID (shortened)" if short else "ID",
                    "style": TABLE_STYLING.id,
                    "no_wrap": True,
                },
                "is_default": {
                    "header": "Default",
                    "style": TABLE_STYLING.mine,
                    "no_wrap": True,
                },
                "time": {
                    "header": "Date & Time",
                    "style": TABLE_STYLING.mine,
                    "no_wrap": True,
                },
                "last_modified": {
                    "header": "Last Modified",
                    "style": TABLE_STYLING.mine,
                    "no_wrap": True,
                },
                "latitude": {"style": TABLE_STYLING.mine},
                "longitude": {"style": TABLE_STYLING.mine},
                "depth": {"style": TABLE_STYLING.mine},
                "completed": {"style": TABLE_STYLING.parameters},
                "seismogram_count": {
                    "header": "# Seismograms",
                    "style": TABLE_STYLING.linked,
                },
                "station_count": {
                    "header": "# Stations",
                    "style": TABLE_STYLING.linked,
                },
            },
        )

cli_event_parameter_dump

cli_event_parameter_dump(
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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(
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Dump event parameter table to json."""
    from aimbat.db import engine
    from aimbat.core import dump_event_parameter_table_to_json, resolve_event
    from sqlmodel import Session
    from rich import print_json

    with Session(engine) as session:
        event = (
            resolve_event(session, global_parameters.event_id)
            if not all_events
            else None
        )
        print_json(
            dump_event_parameter_table_to_json(
                session, all_events, as_string=True, event=event
            )
        )

cli_event_parameter_get

cli_event_parameter_get(
    name: EventParameter,
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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,
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Get parameter value for an event.

    Args:
        name: Event parameter name.
    """

    from aimbat.db import engine
    from aimbat.core import get_event_parameter, resolve_event
    from sqlmodel import Session

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        value = get_event_parameter(session, event, name)
        if isinstance(value, Timedelta):
            print(f"{value.total_seconds()}s")
        else:
            print(value)

cli_event_parameter_list

cli_event_parameter_list(
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
    table_parameters: TableParameters = TableParameters(),
) -> None

List processing parameter values for the default event.

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

Source code in src/aimbat/_cli/event.py
@parameter.command(name="list")
@simple_exception
def cli_event_parameter_list(
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
    table_parameters: TableParameters = TableParameters(),
) -> None:
    """List processing parameter values for the default event.

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

    from aimbat.db import engine
    from aimbat.core import dump_event_parameter_table_to_json, resolve_event
    from aimbat.utils import uuid_shortener, json_to_table, TABLE_STYLING
    from aimbat.logger import logger

    short = table_parameters.short

    with Session(engine) as session:
        if all_events:
            logger.info("Printing AIMBAT event parameters table for all events.")
            json_to_table(
                data=dump_event_parameter_table_to_json(
                    session, all_events=True, as_string=False
                ),
                title="Event parameters for all events",
                skip_keys=["id"],
                column_order=[
                    "event_id",
                    "completed",
                    "window_pre",
                    "window_post",
                    "min_ccnorm",
                ],
                formatters={
                    "event_id": lambda x: (
                        uuid_shortener(session, AimbatEvent, str_uuid=x) if short else x
                    ),
                },
                common_column_kwargs={"highlight": True},
                column_kwargs={
                    "event_id": {
                        "header": "Event ID (shortened)" if short else "Event ID",
                        "justify": "center",
                        "style": TABLE_STYLING.mine,
                    },
                },
            )
        else:
            logger.info("Printing AIMBAT event parameters table for default event.")

            event = resolve_event(session, global_parameters.event_id)
            json_to_table(
                data=event.parameters.model_dump(mode="json"),
                title=f"Event parameters for event: {uuid_shortener(session, event) if short else str(event.id)}",
                skip_keys=["id", "event_id"],
                common_column_kwargs={"highlight": True},
                column_kwargs={
                    "Key": {
                        "header": "Parameter",
                        "justify": "left",
                        "style": TABLE_STYLING.id,
                    },
                },
            )

cli_event_parameter_set

cli_event_parameter_set(
    name: EventParameter,
    value: str,
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Set parameter value for an event.

Parameters:

Name Type Description Default
name EventParameter

Event parameter name.

required
value str

Event parameter value. For timedelta parameters, bare numbers are interpreted as seconds.

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

    Args:
        name: Event parameter name.
        value: Event parameter value. For timedelta parameters, bare numbers
            are interpreted as seconds.
    """
    from aimbat.db import engine
    from aimbat.core import set_event_parameter, resolve_event
    from sqlmodel import Session

    _TIMEDELTA_PARAMS = (EventParameter.WINDOW_PRE, EventParameter.WINDOW_POST)
    parsed_value: Timedelta | str = value
    if name in _TIMEDELTA_PARAMS:
        try:
            parsed_value = Timedelta(seconds=float(value))
        except ValueError:
            parsed_value = Timedelta(value)

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        set_event_parameter(session, event, name, parsed_value)

pick

Interactively pick phase arrival times and processing parameters.

These commands open an interactive matplotlib plot for the default event. Click on the plot to set the chosen value, then close the window to save it. Use aimbat event default to switch the default event before picking.

Functions:

Name Description
cli_pick_min_ccnorm

Interactively pick a new minimum cross-correlation norm 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 the default event.

cli_pick_min_ccnorm

cli_pick_min_ccnorm(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

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

Opens an interactive plot; click to set the ccnorm 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="ccnorm")
@simple_exception
def cli_pick_min_ccnorm(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Interactively pick a new minimum cross-correlation norm for auto-selection.

    Opens an interactive plot; click to set the ccnorm threshold. Seismograms
    whose cross-correlation with the stack falls below this value will be
    automatically de-selected when running ICCS with `--autoselect`.
    """
    from aimbat.db import engine
    from aimbat.core import create_iccs_instance, update_min_ccnorm, resolve_event
    from sqlmodel import Session

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        iccs = create_iccs_instance(session, event).iccs
        update_min_ccnorm(
            session,
            event,
            iccs,
            iccs_parameters.context,
            iccs_parameters.all,
            return_fig=False,
        )

cli_pick_timewindow

cli_pick_timewindow(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_seismogram_image: Annotated[
        bool, Parameter(name=img)
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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 the seismogram is used during ICCS alignment.

Parameters:

Name Type Description Default
use_seismogram_image Annotated[bool, Parameter(name=img)]

Use the seismogram image to pick the time window.

False
Source code in src/aimbat/_cli/pick.py
@app.command(name="window")
@simple_exception
def cli_pick_timewindow(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_seismogram_image: Annotated[bool, Parameter(name="img")] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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 the
    seismogram is used during ICCS alignment.

    Args:
        use_seismogram_image: Use the seismogram image to pick the time window.
    """
    from aimbat.db import engine
    from aimbat.core import create_iccs_instance, update_timewindow, resolve_event
    from sqlmodel import Session

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        iccs = create_iccs_instance(session, event).iccs
        update_timewindow(
            session,
            event,
            iccs,
            iccs_parameters.context,
            iccs_parameters.all,
            use_seismogram_image,
            return_fig=False,
        )

cli_update_phase_pick

cli_update_phase_pick(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_seismogram_image: Annotated[
        bool, Parameter(name=img)
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

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

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

Parameters:

Name Type Description Default
use_seismogram_image Annotated[bool, Parameter(name=img)]

Use the seismogram image to update pick.

False
Source code in src/aimbat/_cli/pick.py
@app.command(name="phase")
@simple_exception
def cli_update_phase_pick(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    use_seismogram_image: Annotated[bool, Parameter(name="img")] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Interactively pick a new phase arrival time (t1) for the default event.

    Opens an interactive plot; click on the waveform to place the new pick,
    then close the window to save. The pick is stored as `t1` for each
    selected seismogram.

    Args:
        use_seismogram_image: Use the seismogram image to update pick.
    """
    from aimbat.db import engine
    from aimbat.core import create_iccs_instance, update_pick, resolve_event
    from sqlmodel import Session

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        iccs = create_iccs_instance(session, event).iccs
        update_pick(
            session,
            iccs,
            iccs_parameters.context,
            iccs_parameters.all,
            use_seismogram_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 the default event
  • image: seismograms displayed as a 2-D image (wiggle plot)

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

Functions:

Name Description
cli_iccs_plot_image

Plot the ICCS seismograms of an event as an image.

cli_iccs_plot_stack

Plot the ICCS stack of an event.

cli_seismogram_plot

Plot raw seismograms for the default event sorted by epicentral distance.

cli_iccs_plot_image

cli_iccs_plot_image(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Plot the ICCS seismograms of an event as an image.

Source code in src/aimbat/_cli/plot.py
@app.command(name="image")
@simple_exception
def cli_iccs_plot_image(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Plot the ICCS seismograms of an event as an image."""
    from aimbat.db import engine
    from aimbat.core import (
        create_iccs_instance,
        plot_iccs_seismograms,
        resolve_event,
    )
    from sqlmodel import Session

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        iccs = create_iccs_instance(session, event).iccs
        plot_iccs_seismograms(
            iccs, iccs_parameters.context, iccs_parameters.all, return_fig=False
        )

cli_iccs_plot_stack

cli_iccs_plot_stack(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Plot the ICCS stack of an event.

Source code in src/aimbat/_cli/plot.py
@app.command(name="stack")
@simple_exception
def cli_iccs_plot_stack(
    *,
    iccs_parameters: IccsPlotParameters = IccsPlotParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Plot the ICCS stack of an event."""
    from aimbat.db import engine
    from aimbat.core import create_iccs_instance, plot_stack, resolve_event
    from sqlmodel import Session

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

cli_seismogram_plot

cli_seismogram_plot(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Plot raw seismograms for the default event sorted by epicentral distance.

Source code in src/aimbat/_cli/plot.py
@app.command(name="data")
@simple_exception
def cli_seismogram_plot(
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Plot raw seismograms for the default event sorted by epicentral distance."""
    from aimbat.db import engine
    from aimbat.core import plot_all_seismograms, resolve_event
    from sqlmodel import Session

    with Session(engine) as session:
        event = resolve_event(session, global_parameters.event_id)
        plot_all_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(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *, global_parameters: GlobalParameters = GlobalParameters()
) -> 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.db import engine
    from aimbat.core import create_project

    create_project(engine)

cli_project_delete

cli_project_delete(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *, global_parameters: GlobalParameters = GlobalParameters()
) -> None:
    """Delete project (note: this does *not* delete seismogram files)."""
    from aimbat.db import engine
    from aimbat.core import delete_project

    delete_project(engine)

cli_project_info

cli_project_info(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *, global_parameters: GlobalParameters = GlobalParameters()
) -> None:
    """Show information on an existing project."""

    from aimbat.db import engine
    from aimbat.core._project import _project_exists
    from aimbat.core import resolve_event
    from aimbat.models import AimbatEvent, AimbatSeismogram, AimbatStation
    from aimbat.logger import logger
    from sqlmodel import Session, select
    from rich.console import Console
    from rich.table import Table
    from rich.panel import Panel
    from sqlalchemy.exc import NoResultFound
    import aimbat.core._event as event
    import aimbat.core._seismogram as seismogram
    import aimbat.core._station as station

    logger.info("Printing project info.")

    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, global_parameters.event_id)
            target_event_id = target_event.id
            active_stations = len(station.get_stations_in_event(session, target_event))
            seismograms_in_event = len(target_event.seismograms)
            selected_seismograms_in_event = len(
                seismogram.get_selected_seismograms(session, event=target_event)
            )
        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: "
            if global_parameters.event_id
            else "Default 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)
    ],
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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.UUID, id_parameter(AimbatSeismogram)],
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Delete existing seismogram."""
    from aimbat.db import engine
    from aimbat.core import delete_seismogram_by_id
    from sqlmodel import Session

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

cli_seismogram_dump

cli_seismogram_dump(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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 aimbat.db import engine
    from aimbat.core import dump_seismogram_table_to_json
    from sqlmodel import Session
    from rich import print_json

    with Session(engine) as session:
        print_json(dump_seismogram_table_to_json(session))

cli_seismogram_list

cli_seismogram_list(
    *,
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *,
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Print information on the seismograms in an event."""
    from aimbat.db import engine
    from aimbat.core import resolve_event
    from aimbat.utils import uuid_shortener, make_table, TABLE_STYLING
    from aimbat.logger import logger
    from rich.console import Console
    from sqlmodel import Session, select

    short = table_parameters.short

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

        title = "AIMBAT seismograms for all events"

        if all_events:
            logger.debug("Selecting seismograms for all events.")
            seismograms = session.exec(select(AimbatSeismogram)).all()
        else:
            logger.debug("Selecting seismograms for event.")
            event = resolve_event(session, global_parameters.event_id)
            seismograms = event.seismograms
            if short:
                title = f"AIMBAT seismograms for event {event.time.strftime('%Y-%m-%d %H:%M:%S')} (ID={uuid_shortener(session, event)})"
            else:
                title = f"AIMBAT seismograms for event {event.time} (ID={event.id})"

        logger.debug(f"Found {len(seismograms)} seismograms for the table.")

        table = make_table(title=title)
        table.add_column(
            "ID (shortened)" if short else "ID",
            justify="center",
            style=TABLE_STYLING.id,
            no_wrap=True,
        )
        table.add_column(
            "Selected", justify="center", style=TABLE_STYLING.mine, no_wrap=True
        )
        table.add_column(
            "NPTS", justify="center", style=TABLE_STYLING.mine, no_wrap=True
        )
        table.add_column(
            "Delta", justify="center", style=TABLE_STYLING.mine, no_wrap=True
        )
        table.add_column(
            "Data ID", justify="center", style=TABLE_STYLING.linked, no_wrap=True
        )
        table.add_column("Station ID", justify="center", style=TABLE_STYLING.linked)
        table.add_column("Station Name", justify="center", style=TABLE_STYLING.linked)
        if all_events:
            table.add_column("Event ID", justify="center", style=TABLE_STYLING.linked)

        for seismogram in seismograms:
            logger.debug(f"Adding seismogram with ID {seismogram.id} to the table.")
            row = [
                (uuid_shortener(session, seismogram) if short else str(seismogram.id)),
                TABLE_STYLING.bool_formatter(seismogram.parameters.select),
                str(len(seismogram.data)),
                str(seismogram.delta.total_seconds()),
                (
                    uuid_shortener(session, seismogram.datasource)
                    if short
                    else str(seismogram.datasource.id)
                ),
                (
                    uuid_shortener(session, seismogram.station)
                    if short
                    else str(seismogram.station.id)
                ),
                f"{seismogram.station.name} - {seismogram.station.network}",
            ]

            if all_events:
                row.append(
                    uuid_shortener(session, seismogram.event)
                    if short
                    else str(seismogram.event.id)
                )
            table.add_row(*row)

        console = Console()
        console.print(table)

cli_seismogram_parameter_dump

cli_seismogram_parameter_dump(
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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(
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Dump seismogram parameter table to json."""
    from aimbat.db import engine
    from aimbat.core import dump_seismogram_parameter_table_to_json, resolve_event
    from sqlmodel import Session
    from rich import print_json

    with Session(engine) as session:
        event = (
            resolve_event(session, global_parameters.event_id)
            if not all_events
            else None
        )
        print_json(
            dump_seismogram_parameter_table_to_json(
                session, all_events, as_string=True, event=event
            )
        )

cli_seismogram_parameter_get

cli_seismogram_parameter_get(
    seismogram_id: Annotated[
        UUID, id_parameter(AimbatSeismogram)
    ],
    name: SeismogramParameter,
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    seismogram_id: Annotated[uuid.UUID, id_parameter(AimbatSeismogram)],
    name: SeismogramParameter,
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Get the value of a processing parameter.

    Args:
        name: Name of the seismogram parameter.
    """
    from aimbat.db import engine
    from aimbat.core import get_seismogram_parameter_by_id
    from sqlmodel import Session

    with Session(engine) as session:
        print(get_seismogram_parameter_by_id(session, seismogram_id, name))

cli_seismogram_parameter_list

cli_seismogram_parameter_list(
    global_parameters: GlobalParameters = GlobalParameters(),
    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(
    global_parameters: GlobalParameters = GlobalParameters(),
    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 aimbat.db import engine
    from aimbat.core import resolve_event, dump_seismogram_parameter_table_to_json
    from aimbat.utils import uuid_shortener, json_to_table, TABLE_STYLING
    from aimbat.logger import logger
    from sqlmodel import Session

    short = table_parameters.short

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

        event = resolve_event(session, global_parameters.event_id)
        title = f"Seismogram parameters for event: {uuid_shortener(session, event) if short else str(event.id)}"

        json_to_table(
            data=dump_seismogram_parameter_table_to_json(
                session, all_events=False, as_string=False, event=event
            ),
            title=title,
            skip_keys=["id"],
            column_order=["seismogram_id", "select"],
            common_column_kwargs={"highlight": True},
            formatters={
                "seismogram_id": lambda x: (
                    uuid_shortener(session, AimbatSeismogram, str_uuid=x)
                    if short
                    else x
                ),
            },
            column_kwargs={
                "seismogram_id": {
                    "header": "Seismogram ID (shortened)" if short else "Seismogram ID",
                    "justify": "center",
                    "style": TABLE_STYLING.mine,
                },
            },
        )

cli_seismogram_parameter_reset

cli_seismogram_parameter_reset(
    seismogram_id: Annotated[
        UUID, id_parameter(AimbatSeismogram)
    ],
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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.UUID, id_parameter(AimbatSeismogram)],
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Reset all processing parameters to their default values."""
    from aimbat.db import engine
    from aimbat.core import reset_seismogram_parameters_by_id
    from sqlmodel import Session

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

cli_seismogram_parameter_set

cli_seismogram_parameter_set(
    seismogram_id: Annotated[
        UUID, id_parameter(AimbatSeismogram)
    ],
    name: SeismogramParameter,
    value: str,
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    seismogram_id: Annotated[uuid.UUID, id_parameter(AimbatSeismogram)],
    name: SeismogramParameter,
    value: str,
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Set value of a processing parameter.

    Args:
        name: Name of the seismogram parameter.
        value: Value of the seismogram parameter.
    """
    from aimbat.db import engine
    from aimbat.core import set_seismogram_parameter_by_id
    from sqlmodel import Session

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

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_snapshop_delete

Delete existing snapshot.

cli_snapshot_create

Create a new snapshot of current processing parameters.

cli_snapshot_details

Print information on the event parameters saved in a snapshot.

cli_snapshot_dump

Dump the contents of the AIMBAT snapshot table to json.

cli_snapshot_list

Print information on the snapshots for an event.

cli_snapshot_rollback

Rollback to snapshot.

cli_snapshop_delete

cli_snapshop_delete(
    snapshot_id: Annotated[
        UUID, id_parameter(AimbatSnapshot)
    ],
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Delete existing snapshot.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="delete")
@simple_exception
def cli_snapshop_delete(
    snapshot_id: Annotated[uuid.UUID, id_parameter(AimbatSnapshot)],
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Delete existing snapshot."""
    from aimbat.db import engine
    from aimbat.core import delete_snapshot_by_id
    from sqlmodel import Session

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

cli_snapshot_create

cli_snapshot_create(
    comment: str | None = None,
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    comment: str | None = None,
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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 aimbat.db import engine
    from aimbat.core import create_snapshot, resolve_event
    from sqlmodel import Session

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

cli_snapshot_details

cli_snapshot_details(
    snapshot_id: Annotated[
        UUID, id_parameter(AimbatSnapshot)
    ],
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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.UUID, id_parameter(AimbatSnapshot)],
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Print information on the event parameters saved in a snapshot."""
    from aimbat.db import engine
    from aimbat.utils import uuid_shortener, json_to_table, TABLE_STYLING
    from sqlmodel import Session

    short = table_parameters.short

    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."
            )

        parameters_snapshot = snapshot.event_parameters_snapshot
        json_to_table(
            data=parameters_snapshot.model_dump(mode="json"),
            title=f"Saved event parameters in snapshot: {uuid_shortener(session, parameters_snapshot.snapshot) if short else str(parameters_snapshot.snapshot.id)}",
            skip_keys=["id", "snapshot_id", "parameters_id"],
            common_column_kwargs={"highlight": True},
            column_kwargs={
                "Key": {
                    "header": "Parameter",
                    "justify": "left",
                    "style": TABLE_STYLING.id,
                },
            },
        )

cli_snapshot_dump

cli_snapshot_dump(
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None

Dump the contents of the AIMBAT snapshot table to json.

Source code in src/aimbat/_cli/snapshot.py
@app.command(name="dump")
@simple_exception
def cli_snapshot_dump(
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Dump the contents of the AIMBAT snapshot table to json."""
    from aimbat.db import engine
    from aimbat.core import dump_snapshot_tables_to_json, resolve_event
    from sqlmodel import Session
    from rich import print_json

    with Session(engine) as session:
        event = (
            resolve_event(session, global_parameters.event_id)
            if not all_events
            else None
        )
        print_json(
            dump_snapshot_tables_to_json(
                session, all_events, as_string=True, event=event
            )
        )

cli_snapshot_list

cli_snapshot_list(
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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(
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Print information on the snapshots for an event."""
    from aimbat.db import engine
    from aimbat.core import resolve_event, dump_snapshot_tables_to_json
    from aimbat.utils import uuid_shortener, json_to_table, TABLE_STYLING
    from aimbat.logger import logger
    from aimbat.models import AimbatEvent
    from pandas import Timestamp
    from sqlmodel import Session

    short = table_parameters.short

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

        title = "AIMBAT snapshots for all events"

        event = None
        if not all_events:
            event = resolve_event(session, global_parameters.event_id)
            if short:
                title = f"AIMBAT snapshots for event {event.time.strftime('%Y-%m-%d %H:%M:%S')} (ID={uuid_shortener(session, event)})"
            else:
                title = f"AIMBAT snapshots for event {event.time} (ID={event.id})"

        data = dump_snapshot_tables_to_json(
            session, all_events, as_string=False, event=event
        )
        snapshot_data = data["snapshots"]

        column_order = ["id", "date", "comment", "seismogram_count"]
        if all_events:
            column_order.append("event_id")

        skip_keys = [] if all_events else ["event_id"]

        json_to_table(
            data=snapshot_data,
            title=title,
            column_order=column_order,
            skip_keys=skip_keys,
            formatters={
                "id": lambda x: (
                    uuid_shortener(session, AimbatSnapshot, str_uuid=x) if short else x
                ),
                "date": lambda x: TABLE_STYLING.timestamp_formatter(
                    Timestamp(x), short
                ),
                "event_id": lambda x: (
                    uuid_shortener(session, AimbatEvent, str_uuid=x) if short else x
                ),
            },
            common_column_kwargs={"justify": "center"},
            column_kwargs={
                "id": {
                    "header": "ID (shortened)" if short else "ID",
                    "style": TABLE_STYLING.id,
                    "no_wrap": True,
                },
                "date": {
                    "header": "Date & Time",
                    "style": TABLE_STYLING.mine,
                    "no_wrap": True,
                },
                "comment": {"style": TABLE_STYLING.mine},
                "seismogram_count": {
                    "header": "# Seismograms",
                    "style": TABLE_STYLING.linked,
                },
                "selected_seismogram_count": {
                    "header": "# Selected",
                    "style": TABLE_STYLING.linked,
                },
                "flipped_seismogram_count": {
                    "header": "# Flipped",
                    "style": TABLE_STYLING.linked,
                },
                "event_id": {
                    "header": "Event ID (shortened)" if short else "Event ID",
                    "style": TABLE_STYLING.linked,
                },
            },
        )

cli_snapshot_rollback

cli_snapshot_rollback(
    snapshot_id: Annotated[
        UUID, id_parameter(AimbatSnapshot)
    ],
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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.UUID, id_parameter(AimbatSnapshot)],
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Rollback to snapshot."""
    from aimbat.db import engine
    from aimbat.core import rollback_to_snapshot_by_id
    from sqlmodel import Session

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

station

View and manage stations.

Functions:

Name Description
cli_station_delete

Delete existing station.

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_delete

cli_station_delete(
    station_id: Annotated[
        UUID, id_parameter(AimbatStation)
    ],
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Delete existing station.

Source code in src/aimbat/_cli/station.py
@app.command(name="delete")
@simple_exception
def cli_station_delete(
    station_id: Annotated[uuid.UUID, id_parameter(AimbatStation)],
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Delete existing station."""
    from aimbat.db import engine
    from aimbat.core import delete_station_by_id
    from sqlmodel import Session

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

cli_station_dump

cli_station_dump(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *,
    global_parameters: GlobalParameters = GlobalParameters(),
) -> 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 aimbat.db import engine
    from aimbat.core import dump_station_table_to_json
    from sqlmodel import Session
    from rich import print_json

    with Session(engine) as session:
        print_json(dump_station_table_to_json(session))

cli_station_list

cli_station_list(
    *,
    all_events: Annotated[
        bool, ALL_EVENTS_PARAMETER
    ] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *,
    all_events: Annotated[bool, ALL_EVENTS_PARAMETER] = False,
    table_parameters: TableParameters = TableParameters(),
    global_parameters: GlobalParameters = GlobalParameters(),
) -> None:
    """Print information on the stations used in an event."""
    from aimbat.db import engine
    from aimbat.core import (
        resolve_event,
        get_stations_in_event,
    )
    from aimbat.utils import uuid_shortener, json_to_table, TABLE_STYLING
    from aimbat.logger import logger
    from typing import Any
    from sqlmodel import Session

    short = table_parameters.short

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

        title = "AIMBAT stations for all events"

        if all_events:
            logger.debug("Selecting all AIMBAT stations.")
            from aimbat.core import dump_station_table_with_counts

            data = dump_station_table_with_counts(session)
        else:
            logger.debug("Selecting AIMBAT stations used by event.")
            event = resolve_event(session, global_parameters.event_id)
            data = get_stations_in_event(session, event, as_json=True)

            if short:
                title = f"AIMBAT stations for event {event.time.strftime('%Y-%m-%d %H:%M:%S')} (ID={uuid_shortener(session, event)})"
            else:
                title = f"AIMBAT stations for event {event.time} (ID={event.id})"

        column_order = [
            "id",
            "name",
            "network",
            "channel",
            "location",
            "latitude",
            "longitude",
            "elevation",
        ]
        if all_events:
            column_order.extend(["seismogram_count", "event_count"])

        column_kwargs: dict[str, dict[str, Any]] = {
            "id": {
                "header": "ID (shortened)" if short else "ID",
                "style": TABLE_STYLING.id,
                "justify": "center",
                "no_wrap": True,
            },
            "name": {
                "header": "Name",
                "style": TABLE_STYLING.mine,
                "justify": "center",
                "no_wrap": True,
            },
            "network": {
                "header": "Network",
                "style": TABLE_STYLING.mine,
                "justify": "center",
                "no_wrap": True,
            },
            "channel": {
                "header": "Channel",
                "style": TABLE_STYLING.mine,
                "justify": "center",
            },
            "location": {
                "header": "Location",
                "style": TABLE_STYLING.mine,
                "justify": "center",
            },
            "latitude": {
                "header": "Latitude",
                "style": TABLE_STYLING.mine,
                "justify": "center",
            },
            "longitude": {
                "header": "Longitude",
                "style": TABLE_STYLING.mine,
                "justify": "center",
            },
            "elevation": {
                "header": "Elevation",
                "style": TABLE_STYLING.mine,
                "justify": "center",
            },
            "seismogram_count": {
                "header": "# Seismograms",
                "style": TABLE_STYLING.linked,
                "justify": "center",
            },
            "event_count": {
                "header": "# Events",
                "style": TABLE_STYLING.linked,
                "justify": "center",
            },
        }

        formatters = {
            "id": lambda x: (
                uuid_shortener(session, AimbatStation, str_uuid=x) if short else str(x)
            ),
            "latitude": lambda x: f"{x:.3f}" if short else str(x),
            "longitude": lambda x: f"{x:.3f}" if short else str(x),
            "elevation": lambda x: f"{x:.0f}" if short else str(x),
        }

        json_to_table(
            data,
            title=title,
            column_order=column_order,
            column_kwargs=column_kwargs,
            formatters=formatters,
        )

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(
    *,
    global_parameters: GlobalParameters = GlobalParameters()
) -> 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(
    *, global_parameters: GlobalParameters = GlobalParameters()
) -> None:
    """Recursively delete sample data directory."""
    from aimbat.utils import delete_sampledata

    delete_sampledata()

sampledata_cli_download

sampledata_cli_download(
    *,
    force: bool = False,
    global_parameters: GlobalParameters = GlobalParameters()
) -> None

Download AIMBAT sample data.

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

Parameters:

Name Type Description Default
force bool

Delete the download directory and re-download."

False
Source code in src/aimbat/_cli/utils/sampledata.py
@app.command(name="download")
@simple_exception
def sampledata_cli_download(
    *, force: bool = False, global_parameters: GlobalParameters = GlobalParameters()
) -> None:
    """Download AIMBAT sample data.

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

    Args:
        force: Delete the download directory and re-download."
    """
    from aimbat.utils import download_sampledata

    download_sampledata(force)