Public Access
Fix #37: Press button to get experiment duration
This commit is contained in:
@@ -210,6 +210,7 @@ class DamarisGUI:
|
|||||||
|
|
||||||
#connect event handlers
|
#connect event handlers
|
||||||
eventhandlers = {"on_toolbar_run_button_clicked": self.start_experiment,
|
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_pause_button_toggled": self.pause_experiment,
|
||||||
"on_toolbar_stop_button_clicked": self.stop_experiment,
|
"on_toolbar_stop_button_clicked": self.stop_experiment,
|
||||||
"on_doc_menu_activate": self.show_doc_menu,
|
"on_doc_menu_activate": self.show_doc_menu,
|
||||||
@@ -389,6 +390,117 @@ class DamarisGUI:
|
|||||||
|
|
||||||
# toolbar related events:
|
# 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 ):
|
def start_experiment( self, widget, data=None ):
|
||||||
|
|
||||||
# something running?
|
# something running?
|
||||||
|
|||||||
@@ -641,6 +641,21 @@ Public License instead of this License.
|
|||||||
<property name="homogeneous">True</property>
|
<property name="homogeneous">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<object class="GtkToolItem" id="toolitem4">
|
<object class="GtkToolItem" id="toolitem4">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|||||||
Reference in New Issue
Block a user