From 3dc98f0970bfcea73fdbcb86cf1aa91f8355b97f Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Thu, 5 Apr 2018 16:46:23 +0200 Subject: [PATCH 1/9] Add get_length() function to the Experiment class which returns the estimated time the experiment will take. --- src/experiments/Experiment.py | 59 +++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/src/experiments/Experiment.py b/src/experiments/Experiment.py index 5ef264c..41e84aa 100644 --- a/src/experiments/Experiment.py +++ b/src/experiments/Experiment.py @@ -90,6 +90,15 @@ class Experiment: assert len(rf_gates) == len(rf_sources), "rf_sources and rf_gates must have equal number of entries" self.rf_sources = rf_sources self.rf_gates = rf_gates + + #for tracking the experiment length: + #because loops are possible we need to track the length for each loop level + self.total_time=[] + self.total_time.append(0.0) + + #and we need to know the number of iterations of the loops to multiply the state. + self.loop_iterations=[] + self.loop_iterations.append(1) # Commands ------------------------------------------------------------------------------------- @@ -118,6 +127,8 @@ class Experiment: the_value=1<' % the_value)) + + self.total_time[-1] += length ## Same as ttl_pulse, but no *channel* keyword def ttls(self, length = None, value = None): @@ -132,8 +143,10 @@ class Experiment: s_content = '' % the_value if length is not None: self.state_list.append(StateSimple(length, s_content)) + self.total_time[-1] += length else: self.state_list.append(s_content) + def rf_pulse(self, length=None, phase=0, source=0): """ @@ -157,6 +170,7 @@ class Experiment: This must be closed with state_end() """ self.state_list.append('\n' % repr(time)) + self.total_time[-1] += time ## End of *state_start* def state_end(self): @@ -184,6 +198,8 @@ class Experiment: self.state_list.append(StateSimple(time,s_content)) else: self.state_list.append(StateSimple(time)) + + self.total_time[-1] += time ## Records data with given number of samples, sampling-frequency frequency and sensitivity # @param samples Number of samples to record @@ -247,6 +263,7 @@ class Experiment: if timelength is None: timelength = samples / float(frequency)#*1.01 self.state_list.append(StateSimple(timelength, s_content)) + self.total_time[-1] += timelength ## Create a loop on the pulse programmer. Loop contents can not change inside the loop. # @params iterations Number of loop iterations @@ -264,6 +281,9 @@ class Experiment: # (These two lines could probably be guarded by a mutex) self.list_stack.append(self.state_list) self.state_list = l + + self.total_time.append(0.0) + self.loop_iterations.append(iterations) ## End loop state def loop_end(self): @@ -272,6 +292,10 @@ class Experiment: """ # (This line could probably be guarded by a mutex) self.state_list = self.list_stack.pop(-1) + + looptime=self.total_time.pop(-1) + loopiterations=self.loop_iterations.pop(-1) + self.total_time[-1] += looptime*loopiterations ## Set the frequency and phase of the frequency source. ## This state needs 2us. @@ -291,6 +315,8 @@ class Experiment: if ttls != 0: s_content += '' % ttls self.state_list.append(StateSimple(2e-6, s_content)) + + self.total_time[-1] += 2e-6 ## Creates a, possibly shaped, pulsed gradient. # @param dac_value DAC value to set @@ -331,10 +357,13 @@ class Experiment: if form == 'rec': # shape==None --> rectangular gradients s_content = '' % (trigger, dac_value) self.state_list.append(StateSimple(length, s_content)) + self.total_time[-1] += length if not is_seq: s_content = '' self.state_list.append(StateSimple(42*9e-8, s_content)) + + self.total_time[-1] += 42*9e-8 elif form == 'sin2': # sin**2 shape @@ -342,9 +371,12 @@ class Experiment: dac = int (dac_value*numpy.sin(numpy.pi/length*t)**2) s_content = '' % (trigger, dac) self.state_list.append(StateSimple(resolution, s_content)) + # set it back to zero s_content = '' % (trigger) self.state_list.append(StateSimple(resolution, s_content)) + + self.total_time[-1] += resolution*(len(t_steps)+1) elif form == 'sin': # sin shape @@ -355,6 +387,8 @@ class Experiment: # set it back to zero s_content = '' % (trigger) self.state_list.append(StateSimple(resolution, s_content)) + + self.total_time[-1] += resolution*(len(t_steps)+1) else: # don't know what to do raise SyntaxError , "form is unknown: %s"%form @@ -385,10 +419,15 @@ class Experiment: s_content = '' \ % (dac_id, dac_value, ttls) self.state_list.append(StateSimple(length, s_content)) + + self.total_time[-1] += length + if not is_seq: s_content = '' \ % (dac_id, ttls) self.state_list.append(StateSimple(42*9e-8, s_content)) + + self.total_time[-1] += 42*9e-8 ## sets the phase of the frequency source. ## This state needs 0.5us, though the phase switching time is dependent on the frequency source @@ -408,6 +447,8 @@ class Experiment: if ttls!=0: s_content += '' % ttls self.state_list.append(StateSimple(0.5e-6, s_content)) + + self.total_time[-1] += 0.5e-6 ## sets a description which is carried via the back end result ## file to the result script in the front end. In the result script @@ -434,6 +475,8 @@ class Experiment: """ self.state_list.append(StateSimple(1e-6, '')) self.state_list.append(StateSimple(1e-6, '')) + + self.total_time[-1] += 2e-6 # / Commands ----------------------------------------------------------------------------------- @@ -508,7 +551,16 @@ class Experiment: :returns: XML quit-job """ return '\n' - + + def get_length(self): + timelength = 0.0 + + #calculate the correct timelength also for unclosed loops, if there is no unclosed loop + #the timelength of this experiment is self.total_time[-1]. + for i in range(len(self.total_time)): + timelength += self.total_time[i]*self.loop_iterations[i] + + return timelength class Quit(Experiment): def write_xml_string(self): @@ -529,8 +581,7 @@ def self_test(): e.ttl_pulse(1e-6/3, None, 7) # val = 7 if True: e.loop_start(30) - e.set_pfg(dac_value=1024, is_seq = True) - e.set_pfg_wt(dac_value=2048) + e.set_pfg(dac_value=1024, length=5e-6, is_seq = True, shape=('rec', 42*9e-8)) e.loop_start(400) e.set_phase(270, ttls = 32) e.loop_end() @@ -550,6 +601,8 @@ def self_test(): raise AssertionError("An exception should happen") e.set_pts_local() print e.write_xml_string() + + print e.get_timelength() if __name__ == '__main__': self_test() From 63cb9e7d05dda386863dc54094b0e5d5ed47b2e1 Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Thu, 5 Apr 2018 17:25:35 +0200 Subject: [PATCH 2/9] Add experiment run time/expected experiment runtime (of already queued experiments) and the time of the already finished experiments to the status bar in the gui. --- src/gui/DamarisGUI.py | 28 ++++++++++++++++++++++++++++ src/gui/ExperimentHandling.py | 16 ++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index 0188ec4..41bf0d2 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -541,6 +541,33 @@ class DamarisGUI: r = self.si.data.get( "__recentresult", -1 ) + 1 b = self.si.data.get( "__resultsinadvance", -1 ) + 1 e = self.si.data.get( "__recentexperiment", -1 ) + 1 + + experimentstarttime = self.si.data.get( "__experimentstarted", 0 ) + expectedexperimentruntime = self.si.data.get( "__totalexperimentlength", 0 ) + experimentsfinishedtime = 0.0 + + for i in range(0, b): + experimentsfinishedtime += self.si.data.get("__experimentlengths", {}).get(i, 0.0) + + experimentruntime = time.time() - experimentstarttime + + experimenttimetext = "" + + if experimentstarttime > 0 and expectedexperimentruntime > 0: + runtimemin, runtimesec = divmod(math.floor(experimentruntime), 60) + runtimehours, runtimemin = divmod(runtimemin, 60) + experimenttimetext += " ({:02d}:{:02d}:{:02d} / ".format(runtimehours, runtimemin, runtimesec) + expectedmin, expectedsec = divmod(math.ceil(expectedexperimentruntime), 60) + expectedhours, expectedmin = divmod(expectedmin, 60) + experimenttimetext += "{:02d}:{:02d}:{:02d})".format(expectedhours, expectedmin, expectedsec) + + backendtimetext = "" + + if experimentsfinishedtime > 0: + finexperimmin, finexperimsec = divmod(round(experimentsfinishedtime), 60) + finexperimhours, finexperimmin = divmod(finexperimmin, 60) + backendtimetext = " ({:02d}:{:02d}:{:02d})".format(finexperimhours, finexperimmin, finexperimsec) + e_text = None r_text = None b_text = None @@ -559,6 +586,7 @@ class DamarisGUI: self.si.exp_handling = None else: e_text = "Experiment Script Running (%d)" % e + e_text += experimenttimetext if self.si.res_handling is not None: if not self.si.res_handling.isAlive( ): diff --git a/src/gui/ExperimentHandling.py b/src/gui/ExperimentHandling.py index 5f40d44..0ee5100 100644 --- a/src/gui/ExperimentHandling.py +++ b/src/gui/ExperimentHandling.py @@ -66,6 +66,7 @@ class ExperimentHandling(threading.Thread): self.traceback=traceback_file.getvalue() traceback_file=None return + while exp_iterator is not None and not self.quit_flag.isSet(): # get next experiment from script try: @@ -86,6 +87,21 @@ class ExperimentHandling(threading.Thread): if isinstance(job, Experiment): if self.data is not None: self.data["__recentexperiment"]=job.job_id+0 + + # track time when experiment is started. This is placed after executing the script + # and getting the iterator so that time for initializing devices etc. is not included + if "__experimentstarted" not in self.data: + self.data["__experimentstarted"] = time.time() + # track time of experiments in queue, the total time and for each experiment: + if "__totalexperimentlength" not in self.data: + self.data["__totalexperimentlength"] = 0.0 + if "__experimentlengths" not in self.data: + self.data["__experimentlengths"] = {} + + experimentlength = job.get_length() + self.data["__experimentlengths"][job.job_id+0] = experimentlength + self.data["__totalexperimentlength"] += experimentlength + # relax for a short time if "__resultsinadvance" in self.data and self.data["__resultsinadvance"]+100 Date: Fri, 6 Apr 2018 12:53:14 +0200 Subject: [PATCH 3/9] Fix bug in rendering of experiment runtime in GUI --- src/gui/DamarisGUI.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index 41bf0d2..d10e0e4 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -556,17 +556,17 @@ class DamarisGUI: if experimentstarttime > 0 and expectedexperimentruntime > 0: runtimemin, runtimesec = divmod(math.floor(experimentruntime), 60) runtimehours, runtimemin = divmod(runtimemin, 60) - experimenttimetext += " ({:02d}:{:02d}:{:02d} / ".format(runtimehours, runtimemin, runtimesec) + experimenttimetext += " ({:02d}:{:02d}:{:02d} / ".format(int(runtimehours), int(runtimemin), int(runtimesec)) expectedmin, expectedsec = divmod(math.ceil(expectedexperimentruntime), 60) expectedhours, expectedmin = divmod(expectedmin, 60) - experimenttimetext += "{:02d}:{:02d}:{:02d})".format(expectedhours, expectedmin, expectedsec) + experimenttimetext += "{:02d}:{:02d}:{:02d})".format(int(expectedhours), int(expectedmin), int(expectedsec)) backendtimetext = "" if experimentsfinishedtime > 0: finexperimmin, finexperimsec = divmod(round(experimentsfinishedtime), 60) finexperimhours, finexperimmin = divmod(finexperimmin, 60) - backendtimetext = " ({:02d}:{:02d}:{:02d})".format(finexperimhours, finexperimmin, finexperimsec) + backendtimetext = " ({:02d}:{:02d}:{:02d})".format(int(finexperimhours), int(finexperimmin), int(finexperimsec)) e_text = None r_text = None From 89edfcd95d89a77f259006d4d24c7ad8678b665f Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Fri, 6 Apr 2018 19:40:06 +0200 Subject: [PATCH 4/9] Small fix in Experiment class (get_length() rturns correct time when called while in loop. --- src/experiments/Experiment.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/experiments/Experiment.py b/src/experiments/Experiment.py index 41e84aa..aaa42c3 100644 --- a/src/experiments/Experiment.py +++ b/src/experiments/Experiment.py @@ -558,7 +558,8 @@ class Experiment: #calculate the correct timelength also for unclosed loops, if there is no unclosed loop #the timelength of this experiment is self.total_time[-1]. for i in range(len(self.total_time)): - timelength += self.total_time[i]*self.loop_iterations[i] + timelength += self.total_time[i] + timelength *= self.loop_iterations[i] return timelength @@ -602,7 +603,7 @@ def self_test(): e.set_pts_local() print e.write_xml_string() - print e.get_timelength() + print e.get_length() if __name__ == '__main__': self_test() From cc812f58c91a6cee4b25b59998ed8d9e7b5a016f Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Fri, 6 Apr 2018 19:51:00 +0200 Subject: [PATCH 5/9] Add timing tu backend text --- src/gui/DamarisGUI.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index d10e0e4..12af9c3 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -615,6 +615,7 @@ class DamarisGUI: b_text = "Backend Running" if b != 0: b_text += " (%d)" % b + b_text += backendtimetext if self.dump_thread is not None: if self.dump_thread.isAlive( ): From 591cf8bdea4d571248cc192d53e1619c35a02d61 Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Thu, 29 Mar 2018 15:07:18 +0200 Subject: [PATCH 6/9] Merge changes regarding Tab/ space management in editor (use 4 spaces instead of tab like before). --- src/gui/DamarisGUI.py | 91 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 7 deletions(-) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index 12af9c3..f947ed3 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -53,9 +53,11 @@ matplotlib.rcParams[ "axes.formatter.limits" ] = "-3,3" if matplotlib.rcParams[ "backend" ] == "GTK": from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas + max_points_to_display = 0 # no limit elif matplotlib.rcParams[ "backend" ] == "GTKCairo": from matplotlib.backends.backend_gtkcairo import FigureCanvasGTKCairo as FigureCanvas + max_points_to_display = 1 << 14 # cairo cannot render longer paths than 18??? else: # default @@ -181,7 +183,7 @@ class DamarisGUI: # my notebook self.main_notebook = self.xml_gui.get_widget( "main_notebook" ) - self.log = LogWindow( self.xml_gui ) + self.log = LogWindow( self.xml_gui , self) self.sw = ScriptWidgets( self.xml_gui ) @@ -277,11 +279,14 @@ class DamarisGUI: self.toolbar_run_button.emit("clicked") gtk.main( ) gtk.gdk.threads_leave( ) + self.si = None self.sw = None self.config = None self.xml_gui = None + # event handling: the real acitons in gui programming + # first global events def quit_event( self, widget, data=None ): @@ -684,7 +689,7 @@ class DamarisGUI: # keep data to display but throw away everything else self.si = None - # delete locak file so that other experiment can start + # delete lock file so that other experiment can start self.lockfile.del_experiment(self.id) return False @@ -1017,7 +1022,7 @@ class DamarisGUI: # check generic debian location self.doc_urls[ "Python DAMARIS" ] = "file:///usr/share/doc/python-damaris/html/index.html" else: - self.doc_urls[ "Python DAMARIS" ] = "http://damaris.berlios.de/wiki/index.php/Tutorial" + self.doc_urls[ "Python DAMARIS" ] = "https://element.fkp.physik.tu-darmstadt.de/damaris_cms/index.php?id=documentation" self.doc_browser = None @@ -1087,10 +1092,12 @@ class LogWindow: writes messages to the log window """ - def __init__( self, xml_gui ): + def __init__( self, xml_gui, damaris_gui ): self.xml_gui = xml_gui + self.damaris_gui = damaris_gui self.textview = self.xml_gui.get_widget( "messages_textview" ) + self.textview.connect( "key-press-event", self.textview_keypress) self.textbuffer = self.textview.get_buffer( ) self.logstream = log self.logstream.gui_log = self @@ -1113,6 +1120,14 @@ class LogWindow: self.textbuffer.insert_at_cursor( date_tag + unicode( message ) ) self.textview.scroll_to_mark( self.textbuffer.get_insert( ), 0.1 ) gtk.gdk.threads_leave( ) + + def textview_keypress( self, widget, event, data=None ): + if event.state & gtk.gdk.CONTROL_MASK != 0: + if event.keyval == gtk.gdk.keyval_from_name("f"): + self.damaris_gui.sw.search(None, None) + return True + + return False def __del__( self ): self.logstream.gui_log = None @@ -1152,13 +1167,22 @@ class ScriptWidgets: self.data_handling_textbuffer.set_language(langpython) self.data_handling_textbuffer.set_highlight_syntax(True) + fontdesc = pango.FontDescription("monospace") self.experiment_script_textview.set_buffer( self.experiment_script_textbuffer ) self.experiment_script_textview.set_show_line_numbers(True) self.experiment_script_textview.set_auto_indent(True) + self.experiment_script_textview.set_insert_spaces_instead_of_tabs(True) + self.experiment_script_textview.set_tab_width(4) + self.experiment_script_textview.set_smart_home_end(True) + self.experiment_script_textview.modify_font(fontdesc) self.data_handling_textview.set_buffer( self.data_handling_textbuffer ) self.data_handling_textview.set_show_line_numbers(True) self.data_handling_textview.set_auto_indent(True) + self.data_handling_textview.set_insert_spaces_instead_of_tabs(True) + self.data_handling_textview.set_tab_width(4) + self.data_handling_textview.set_smart_home_end(True) + self.data_handling_textview.modify_font(fontdesc) keywords = """for if else elif in print try finally except global lambda not or pass def class import from as return yield while continue break assert None True False AccumulatedValue @@ -1482,10 +1506,62 @@ get_job_id get_description set_description get_xdata get_ydata set_xdate set_yda elif event.keyval == gtk.gdk.keyval_from_name("f"): self.search(None, None) return True - return 0 + return False + + #Handle Backspace (delete more than one space on line beginning) + if event.keyval == 0xFF08: + textbuffer = widget.get_buffer( ) + + if textbuffer.get_has_selection(): + return False + + cursor_mark = textbuffer.get_insert( ) + cursor_iter = textbuffer.get_iter_at_mark( cursor_mark ) + + linestart_iter = cursor_iter.copy( ) + linestart_iter.set_line_offset( 0 ) + + linebegin = textbuffer.get_text( linestart_iter, cursor_iter ).expandtabs(4) + + if linebegin.isspace() and len(linebegin) > 0: + linebegin = u' ' * int((len( linebegin ) - 1) / 4) * 4 + textbuffer.delete( linestart_iter, cursor_iter ) + textbuffer.insert( linestart_iter, linebegin ) + return True + + elif event.keyval == 0xFF0D: + textbuffer = widget.get_buffer( ) + + if textbuffer.get_has_selection(): + return False + + cursor_mark = textbuffer.get_insert( ) + cursor_iter = textbuffer.get_iter_at_mark( cursor_mark ) + + lastchar_iter = cursor_iter.copy() + lastchar = lastchar_iter.backward_char( ) + + if not lastchar_iter.get_char( ) == u":": + return False + + linestart_iter = cursor_iter.copy( ) + linestart_iter.set_line_offset( 0 ) + spaceend_iter = linestart_iter.copy( ) + while (not spaceend_iter.ends_line( ) and not spaceend_iter.is_end( ) and spaceend_iter.get_char( ).isspace( )): + spaceend_iter.forward_char( ) + linebegin = textbuffer.get_text( linestart_iter, spaceend_iter ).expandtabs(4) + indent_length = int((int(len(linebegin)/4)+1)*4) + + intext = u"\n" + (u" " * indent_length) + + textbuffer.insert(cursor_iter, intext) + widget.scroll_to_mark( cursor_mark, 0.0, 0 ) + + return True + #self.textviews_moved(widget) - return 0 + return False def load_file_as_unicode( self, script_filename ): script_file = file( script_filename, "rU" ) @@ -3216,7 +3292,7 @@ class ScriptInterface: self.exp_writer = self.res_reader = self.back_driver = None if self.backend_executable is not None and self.backend_executable != "": self.back_driver = BackendDriver.BackendDriver( self.backend_executable, spool_dir, clear_jobs, - clear_results) + clear_results ) if self.exp_script: self.exp_writer = self.back_driver.get_exp_writer( ) if self.res_script: @@ -3236,6 +3312,7 @@ class ScriptInterface: self.data = DataPool( ) def runScripts( self ): + try: # get script engines self.exp_handling = self.res_handling = None From 3a81893a250505782a1ce4da70945ce3c1cad9bb Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Mon, 9 Apr 2018 16:43:21 +0200 Subject: [PATCH 7/9] GUI more responsive while experiment is queued and queued experiment can be stopped. --- src/gui/DamarisGUI.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index f947ed3..282b9ae 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -197,6 +197,9 @@ class DamarisGUI: # lock file to prevent other DAMARIS to start immediatly self.lockfile = LockFile() # = os.path.expanduser("~/.damaris.lock") self.id = None + + #to stop queued experiments + self.stop_experiment_flag = threading.Event() exp_script = u"" if exp_script_filename is not None and exp_script_filename != "": @@ -454,10 +457,13 @@ class DamarisGUI: self.log.textbuffer.create_mark( "lastdumped", self.log.textbuffer.get_end_iter( ), left_gravity=True ) loop_run=0 - interval = 2 + #user shorter interval because this blocks user events from the GUI + interval = 0.1 + self.stop_experiment_flag.clear() + self.id = self.lockfile.add_experiment() - while not self.lockfile.am_i_next(): - time.sleep(interval) + while not self.lockfile.am_i_next() and not self.stop_experiment_flag.isSet(): + self.stop_experiment_flag.wait(interval) while gtk.events_pending(): gtk.main_iteration(False) if loop_run > 1: @@ -937,6 +943,7 @@ class DamarisGUI: def stop_experiment( self, widget, data=None ): if self.state in [ DamarisGUI.Run_State, DamarisGUI.Pause_State ]: + self.stop_experiment_flag.set() if self.si is None: return still_running = filter( None, [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] ) From 7dc963143dc9f469ce0736df1482a2531ed581fe Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Mon, 9 Apr 2018 16:53:04 +0200 Subject: [PATCH 8/9] Fix stopping queued experiment --- src/gui/DamarisGUI.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index 282b9ae..46e2946 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -462,7 +462,7 @@ class DamarisGUI: self.stop_experiment_flag.clear() self.id = self.lockfile.add_experiment() - while not self.lockfile.am_i_next() and not self.stop_experiment_flag.isSet(): + while not self.lockfile.am_i_next(): self.stop_experiment_flag.wait(interval) while gtk.events_pending(): gtk.main_iteration(False) @@ -470,6 +470,10 @@ class DamarisGUI: self.experiment_script_statusbar_label.set_text("Waiting for other experiment to finish") loop_run = 0 loop_run += interval + + if self.stop_experiment_flag.isSet(): + self.experiment_script_statusbar_label.set_text("Experiment stopped") + return # start experiment try: From 98e96515385305819c1955ede6727bafcc6d4de4 Mon Sep 17 00:00:00 2001 From: Joachim Beerwerth Date: Tue, 10 Apr 2018 09:43:30 +0200 Subject: [PATCH 9/9] If queued experiment is stopped it is now deleted from queue so that the queue is no longer blocked. --- src/gui/DamarisGUI.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index 46e2946..8228a20 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -472,7 +472,16 @@ class DamarisGUI: loop_run += interval if self.stop_experiment_flag.isSet(): + #Experiment has been stopped, clean up and leave self.experiment_script_statusbar_label.set_text("Experiment stopped") + self.state = DamarisGUI.Edit_State + self.sw.enable_editing( ) + self.toolbar_run_button.set_sensitive( True ) + self.toolbar_stop_button.set_sensitive( False ) + self.toolbar_pause_button.set_sensitive( False ) + self.toolbar_pause_button.set_active( False ) + #delete experiment from queue so that next experiment may start + self.lockfile.del_experiment(self.id) return # start experiment @@ -519,6 +528,8 @@ class DamarisGUI: self.toolbar_stop_button.set_sensitive( False ) self.toolbar_pause_button.set_sensitive( False ) self.toolbar_pause_button.set_active( False ) + #delete Experiment from queue + self.lockfile.del_experiment(self.id) return # switch to grapics