Skip to content

Commit

Permalink
Time remaining for simulation progress bar. (#192)
Browse files Browse the repository at this point in the history
* Time remaining for simulation progress bar.

* Fixed calculation and output issues.

* On finish formatting and simplifying variables.
  • Loading branch information
meaghan66 authored Nov 15, 2024
1 parent d5e4c40 commit e61b128
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions epymorph/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class OnTick(NamedTuple):

tick_index: int
percent_complete: float
dim: SimDimensions


###################
Expand Down
34 changes: 27 additions & 7 deletions epymorph/log/messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

from contextlib import contextmanager
from functools import partial
from math import ceil
from time import perf_counter
from typing import Generator

import humanize
from humanize import naturalsize

from epymorph.event import AdrioProgress, EventBus, OnStart, OnTick
Expand Down Expand Up @@ -39,20 +41,38 @@ def on_start(e: OnStart) -> None:
nonlocal start_time
start_time = perf_counter()

# keeping track of the length of the last line we printed
# lets us clear any trailing characters when rendering stuff
# after the progress bar of varying width
last_progress_length = 0

def on_tick(tick: OnTick) -> None:
print(f" {progress(tick.percent_complete)}", end="\r")
nonlocal last_progress_length
ticks_complete = tick.tick_index + 1
total_process_time = perf_counter() - start_time
average_process_time = total_process_time / ticks_complete

ticks_left = tick.dim.ticks - ticks_complete

# multiply the remaining ticks by the average processing time
estimate = ticks_left * average_process_time

time_remaining = humanize.precisedelta(ceil(estimate), minimum_unit="seconds")
formatted_time = f"({time_remaining} remaining)"
line = f" {progress(tick.percent_complete)}"
# if no time remaining, omit the time progress
if estimate > 0:
line += f"{formatted_time}"
print(line.ljust(last_progress_length), end="\r")
last_progress_length = len(line)

def on_finish(_: None) -> None:
end_time = perf_counter()
print(f" {progress(1.0)}")
line = f" {progress(1.0)}"
print(line.ljust(last_progress_length), end="\n")
if start_time is not None:
print(f"Runtime: {(end_time - start_time):.3f}s")

# keeping track of the length of the last line we printed
# lets us clear any trailing characters when rendering stuff
# after the progress bar of varying width
last_progress_length = 0

def on_adrio_progress(e: AdrioProgress) -> None:
nonlocal last_progress_length
if e.ratio_complete == 0:
Expand Down
2 changes: 1 addition & 1 deletion epymorph/simulator/basic/basic_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def run(
out.compartments[tick.sim_index] = tick_compartments

t = tick.sim_index
_events.on_tick.publish(OnTick(t, (t + 1) / dim.ticks))
_events.on_tick.publish(OnTick(t, (t + 1) / dim.ticks, dim))

_events.on_finish.publish(None)

Expand Down

0 comments on commit e61b128

Please sign in to comment.