Events, observers, and progress

Quantas events decouple workflow communication from presentation. Calculators emit structured events; observers decide whether to display, collect, forward, or ignore them.

Event contracts

An operational quantas.core.events.Event contains:

  • message;

  • EventLevel;

  • optional progress in the interval [0, 1];

  • lightweight structured data;

  • timestamp.

Supported levels are:

DEBUG

Detailed diagnostic information.

INFO

Normal workflow information.

WARNING

A non-fatal condition requiring attention.

ERROR

Failure information emitted before an exception is propagated.

PROGRESS

Operational progress for live observers.

RESULT

Availability or completion of a structured result.

Observers

An observer is any callable satisfying:

def observer(event: Event) -> None:
    ...

Shared implementations include:

NullObserver

Ignore events. This is the default for silent library use.

ListObserver

Collect operational events for tests or custom processing.

CallbackObserver

Forward events to an application callback.

Frontends may implement additional observers without changing calculators.

Calculator emission

quantas.models.BasicCalculator provides emit and add_warning. A calculator should emit meaningful stage boundaries and structured results, not every internal scalar operation.

self.emit("Fitting static equation of state")
self.emit(
    "Static EOS fit completed",
    level=EventLevel.RESULT,
    data={"model": model_name, "r_squared": r_squared},
)

Event data should remain lightweight. Large arrays are summarized before persistence, because the authoritative numerical arrays already belong in the result payload.

Numerical progress

Core numerical functions do not emit Quantas events. They accept a callback such as callback(current, total). The calculator converts that callback to:

self.emit(
    "Evaluating states",
    level=EventLevel.PROGRESS,
    progress=current / total,
)

This keeps core routines independent from observers and lets the same algorithm run inside tests, notebooks, the CLI, or a GUI.

Persistent and operational events

PROGRESS events are observer-only and are intentionally excluded from ResultData.events and native HDF5. Persisting thousands of loop updates would inflate files without adding scientific provenance.

Meaningful messages, warnings, errors, and result events are converted to serializable quantas.core.events.EventRecord objects. Array payloads are represented by type/shape/dtype summaries.

Warnings

Use add_warning when a calculation completes but interpretation is limited, for example:

  • extrapolation;

  • a poorly conditioned fit;

  • an unresolved polarization branch;

  • incomplete optional metadata;

  • a fallback explicitly allowed by the method.

The warning is both emitted and stored. Do not emit a warning for a state that must instead raise an exception.

CLI observer behaviour

The CLI translates events into Rich presentation:

  • warnings in yellow;

  • errors in red;

  • transient progress bars by default;

  • no live progress with --no-progress;

  • ordinary text using the terminal theme.

Rich writes directly to standard output/error. Redirected or unsupported terminals must receive plain text without ANSI sequences.

Testing events

Test:

  • event ordering for meaningful stages;

  • progress normalization and final completion;

  • warning persistence;

  • exclusion of progress from persistent histories;

  • serializable summarization of event data;

  • observer independence of numerical results;

  • CLI rendering separately from calculator behaviour.

Do not freeze incidental debug wording more tightly than necessary. Freeze levels, structured data, and scientifically meaningful messages.