Skip to content

sylva.util.progress

sylva.util.progress

Progress reporting for the work that takes a while.

Segmenting a plot, tracing a few million pulses or fitting a QSM can run for minutes with nothing on the screen. The core counts what it has done in atomics; nothing is printed and no callback is called on that path, so the counting costs nothing when no one is watching. Ask to watch and a thread here reads those counts a few times a second and draws them::

from sylva import trees
from sylva.util import progress

with progress.bar():
    labels = trees.segment_trees(cloud, stems)

A script that wants the numbers rather than a bar passes a callback, which is called with the running stages as (label, done, total), outermost first::

with progress.bar(lambda stages: log(stages[-1])):
    ...

Python loops report too, so a stage that runs over trees or scans shows up the same way::

with progress.task("fitting QSMs", len(trees)) as t:
    for tree in trees:
        ...
        t.update()

Nothing is drawn unless the stream is a terminal, so redirected output and notebooks stay clean; pass force=True to draw anyway.

state

state() -> list[tuple[str, int, int]]

The stages running now, outermost first.

Returns:

Type Description
list of (str, int, int)

Label, steps done and steps expected (0 when not known). Safe to call from another thread while the work runs.

task

task(label: str, total: int = 0)

Report a stage of a Python loop.

Parameters:

Name Type Description Default
label str

What the stage is doing, in a few words ("fitting QSMs").

required
total int

Steps expected; 0 if not known, which draws a sapling in the wind rather than a bar.

0

Yields:

Type Description
_Handle

Call update(n=1) per step, or set(done).

bar

bar(callback=None, stream=None, interval: float = 0.15, force: bool = False)

Watch the work while it runs.

Parameters:

Name Type Description Default
callback

Called with the running stages as (label, done, total), outermost first, every interval seconds. Draws a bar when None.

None
stream

Where to draw; stderr by default, so piped output stays clean.

None
interval float

Seconds between reads.

0.15
force bool

Draw even when the stream is not a terminal.

False
Notes

The bar is drawn from a thread of its own while the core works with the GIL released, so it costs the work nothing. Nested calls are harmless: only the outermost draws.