Fix #37: Press button to get experiment duration
Build Debian Packages / build (trixie, debian13) (push) Successful in 13m16s
Build Debian Packages / build (bookworm, debian12) (push) Successful in 13m21s

This commit is contained in:
2026-07-12 12:21:35 +02:00
parent 3c069a559d
commit baaf6b90b6
2 changed files with 127 additions and 0 deletions
+112
View File
@@ -210,6 +210,7 @@ class DamarisGUI:
#connect event handlers
eventhandlers = {"on_toolbar_run_button_clicked": self.start_experiment,
"on_toolbar_estimate_button_clicked": self.estimate_duration,
"on_toolbar_pause_button_toggled": self.pause_experiment,
"on_toolbar_stop_button_clicked": self.stop_experiment,
"on_doc_menu_activate": self.show_doc_menu,
@@ -389,6 +390,117 @@ class DamarisGUI:
# toolbar related events:
def estimate_duration( self, widget, data=None ):
"""
Estimate the total experiment duration and show a dialog.
"""
from datetime import datetime, timedelta
from damaris.experiments.DurationEstimator import estimate_duration
exp_script, _ = self.sw.get_scripts()
# validate syntax first
try:
compile(exp_script, "Experiment Script", "exec")
except SyntaxError as e:
ln = e.lineno if isinstance(e.lineno, int) else 0
lo = e.offset if isinstance(e.offset, int) else 0
msg = "Experiment Script: %s at line %d, col %d" % (e.__class__.__name__, ln, lo)
dialog = gtk.MessageDialog(
parent=self.main_window,
flags=gtk.DialogFlags.MODAL,
type=gtk.MessageType.ERROR,
buttons=gtk.ButtonsType.OK,
message_format=msg
)
dialog.run()
dialog.destroy()
return
# run estimator in a background thread to not freeze the GUI
dialog = gtk.MessageDialog(
parent=self.main_window,
flags=gtk.DialogFlags.MODAL,
type=gtk.MessageType.INFO,
buttons=gtk.ButtonsType.CLOSE,
message_format="Estimating duration..."
)
dialog.set_resizable(False)
dialog.show()
result = [None]
error = [None]
done = threading.Event()
def run_estimate():
try:
result[0] = estimate_duration(exp_script)
except Exception as e:
error[0] = str(e)
done.set()
t = threading.Thread(target=run_estimate)
t.daemon = True
t.start()
while not done.is_set():
while gtk.events_pending():
gtk.main_iteration_do(False)
if done.wait(0.1):
break
dialog.hide()
dialog.destroy()
if error[0] is not None:
dialog = gtk.MessageDialog(
parent=self.main_window,
flags=gtk.DialogFlags.MODAL,
type=gtk.MessageType.ERROR,
buttons=gtk.ButtonsType.OK,
message_format="Estimation failed: " + error[0]
)
dialog.run()
dialog.destroy()
return
r = result[0]
total = r["total_time"]
exp_time = r["experiment_time"]
sleep_t = r["sleep_time"]
jobs = r["job_count"]
# format duration as HH:MM:SS
def fmt(seconds):
h = int(seconds) // 3600
m = (int(seconds) % 3600) // 60
s = int(seconds) % 60
return "%02d:%02d:%02d" % (h, m, s)
now = datetime.now()
end = now + timedelta(seconds=total)
end_str = end.strftime("%H:%M:%S")
text = (
"Jobs: %d\n"
"Pulse program: %s (%.2f s)\n"
"Sleeps: %s (%.2f s)\n"
"---------------------------\n"
"Total: %s\n\n"
"Start now:\n"
"Estimated end: %s"
) % (jobs, fmt(exp_time), exp_time, fmt(sleep_t), sleep_t, fmt(total), end_str)
dialog = gtk.MessageDialog(
parent=self.main_window,
flags=gtk.DialogFlags.MODAL,
type=gtk.MessageType.INFO,
buttons=gtk.ButtonsType.OK,
message_format=text
)
dialog.run()
dialog.destroy()
def start_experiment( self, widget, data=None ):
# something running?
+15
View File
@@ -641,6 +641,21 @@ Public License instead of this License.
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbar_estimate_button">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Estimate experiment duration</property>
<property name="label">Estimate</property>
<property name="use-underline">True</property>
<property name="icon-name">dialog-information</property>
<signal name="clicked" handler="on_toolbar_estimate_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolItem" id="toolitem4">
<property name="visible">True</property>