added persistent ADC overflow warning

This commit is contained in:
markusro committed 2026-10-21 22:48:46 +02:00
1 parent dcf3ec0f2d
commit 12d7323851
2 files changed
+118 -6

No files matched your search

+88 -1
View File
@@ -253,6 +253,7 @@ class DamarisGUI:
"on_display_copy_data_to_clipboard_button_clicked": self.monitor.copy_display_data_to_clipboard, "on_display_copy_data_to_clipboard_button_clicked": self.monitor.copy_display_data_to_clipboard,
"on_display_copy_png_button_clicked": self.monitor.copy_canvas_as_png, "on_display_copy_png_button_clicked": self.monitor.copy_canvas_as_png,
"on_display_copy_svg_button_clicked": self.monitor.copy_canvas_as_svg, "on_display_copy_svg_button_clicked": self.monitor.copy_canvas_as_svg,
"on_statusbar_overflow_label_clicked": self.monitor.clear_overflow_indicator,
"on_experiment_script_textview_event": self.sw.textviews_modified, "on_experiment_script_textview_event": self.sw.textviews_modified,
"on_main_notebook_switch_page": self.nopevent, "on_main_notebook_switch_page": self.nopevent,
"main_window_close": self.nopevent "main_window_close": self.nopevent
@@ -524,6 +525,8 @@ class DamarisGUI:
logger.error("Experiment is still running or cleaning up!") logger.error("Experiment is still running or cleaning up!")
return return
self.monitor.clear_overflow_indicator( )
# get config values: # get config values:
config_start = time.time() config_start = time.time()
actual_config = self.config.get( ) actual_config = self.config.get( )
@@ -714,6 +717,8 @@ class DamarisGUI:
# cleanup # cleanup
self.si = None self.si = None
if self.monitor.overflow_job_ids:
logger.warning( "ADC overflow occurred in jobs: %s", ', '.join( [str( j ) for j in self.monitor.overflow_job_ids] ))
self.state = DamarisGUI.Edit_State self.state = DamarisGUI.Edit_State
self.sw.enable_editing( ) self.sw.enable_editing( )
self.toolbar_run_button.set_sensitive( True ) self.toolbar_run_button.set_sensitive( True )
@@ -917,6 +922,8 @@ class DamarisGUI:
self.lockfile.del_experiment(self.id) self.lockfile.del_experiment(self.id)
# now everything is stopped # now everything is stopped
if self.monitor.overflow_job_ids:
logger.warning( "ADC overflow occurred in jobs: %s", ', '.join( [str( j ) for j in self.monitor.overflow_job_ids] ))
self.state = DamarisGUI.Edit_State self.state = DamarisGUI.Edit_State
self.sw.enable_editing( ) self.sw.enable_editing( )
self.toolbar_run_button.set_sensitive( True ) self.toolbar_run_button.set_sensitive( True )
@@ -2959,13 +2966,28 @@ class MonitorWidgets:
self.display_autoscaling_checkbutton = self.xml_gui.get_object( "display_autoscaling_checkbutton" ) self.display_autoscaling_checkbutton = self.xml_gui.get_object( "display_autoscaling_checkbutton" )
self.display_statistics_checkbutton = self.xml_gui.get_object( "display_statistics_checkbutton" ) self.display_statistics_checkbutton = self.xml_gui.get_object( "display_statistics_checkbutton" )
self.display_descriptions_checkbutton = gtk.CheckButton(label="Show Desc.") self.display_descriptions_checkbutton = gtk.CheckButton(label="Descr.")
self.display_descriptions_checkbutton.set_active(True) self.display_descriptions_checkbutton.set_active(True)
self.display_descriptions_checkbutton.show() self.display_descriptions_checkbutton.show()
self.display_settings_frame.set_property("n-columns", 5) self.display_settings_frame.set_property("n-columns", 5)
self.display_settings_frame.attach(self.display_descriptions_checkbutton, 4, 5, 0, 1, gtk.AttachOptions.FILL, 0, 0, 0) self.display_settings_frame.attach(self.display_descriptions_checkbutton, 4, 5, 0, 1, gtk.AttachOptions.FILL, 0, 0, 0)
self.display_descriptions_checkbutton.connect("toggled", self.display_descriptions_toggled) self.display_descriptions_checkbutton.connect("toggled", self.display_descriptions_toggled)
# ADC overflow indicator: "ADC" button, green = OK, red = overflow,
# right click opens a menu to reset the state
css = gtk.CssProvider( )
css.load_from_data( b".adc_ok { background-image: none; background-color: #4caf50; }"
b".adc_error { background-image: none; background-color: #e53935; }" )
gtk.StyleContext.add_provider_for_screen( gdk.Screen.get_default( ), css, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION )
self.overflow_css = css
self.overflow_indicator_button = gtk.Button( label="ADC" )
self.overflow_indicator_button.set_tooltip_text( "ADC overflow indicator, red if an overflow occurred" )
self.overflow_job_ids = [ ]
self.overflow_indicator_button.connect( "button-press-event", self.overflow_indicator_button_press )
self.display_settings_frame.attach(self.overflow_indicator_button, 4, 5, 1, 2, gtk.AttachOptions.FILL, 0, 0, 0)
self.overflow_indicator_button.show( )
self.set_overflow_indicator( False )
# Matplot (Display_Table, 1st Row) -------------------------------------------------------- # Matplot (Display_Table, 1st Row) --------------------------------------------------------
# create new plot # create new plot
@@ -3069,6 +3091,7 @@ class MonitorWidgets:
self.fitresultlines = [ ] self.fitresultlines = [ ]
self.fit_source_keys = set( ) self.fit_source_keys = set( )
self.clipping_marker = None self.clipping_marker = None
self.statusbar_overflow_label = self.xml_gui.get_object( "statusbar_overflow_label" )
self.source_list_cache = {} self.source_list_cache = {}
def source_list_reset( self ): def source_list_reset( self ):
@@ -3709,6 +3732,61 @@ class MonitorWidgets:
except Exception as e: except Exception as e:
logger.error("Error copying figure to clipboard: %s", e) logger.error("Error copying figure to clipboard: %s", e)
def set_overflow_indicator( self, clipped ):
"""
Set the background color of the ADC indicator button: green if
clipped is False, red if clipped is True.
>>> monitor.set_overflow_indicator(True) # button turns red
"""
style = self.overflow_indicator_button.get_style_context( )
style.remove_class( "adc_ok" )
style.remove_class( "adc_error" )
style.add_class( "adc_error" if clipped else "adc_ok" )
def overflow_indicator_button_press( self, widget, event ):
"""
ADC indicator button press handler: left click shows a dialog with
the list of job ids where an ADC overflow occurred, right click
opens a menu to reset the overflow state.
>>> monitor.overflow_indicator_button_press(button, event)
"""
if event.button == 1:
if self.overflow_job_ids:
text = "\n".join( str( job_id ) for job_id in self.overflow_job_ids )
else:
text = "No ADC overflow recorded."
dialog = gtk.MessageDialog(parent=self.main_window,
type=gtk.MessageType.WARNING,
flags=gtk.DialogFlags.MODAL,
buttons=("_OK", gtk.ResponseType.OK))
dialog.set_markup("ADC OVERFLOW in jobs:")
dialog.format_secondary_text( text )
dialog.run( )
dialog.destroy( )
elif event.button == 3:
menu = gtk.Menu( )
item = gtk.MenuItem( label="Reset overflow state" )
item.connect("activate", self.clear_overflow_indicator)
menu.append( item )
menu.show_all( )
menu.popup_at_pointer( event )
return False
def clear_overflow_indicator( self, widget=None, event=None ):
"""
Reset handler for the ADC overflow warning: sets the circle back to
green and clears the status bar warning, without starting a new
experiment.
>>> monitor.clear_overflow_indicator()
"""
self.statusbar_overflow_label.set_text( "" )
self.set_overflow_indicator( False )
self.overflow_job_ids = [ ]
return False
##################### functions to feed display ##################### functions to feed display
def clear_display( self ): def clear_display( self ):
""" """
@@ -3986,6 +4064,15 @@ class MonitorWidgets:
color="red", fontsize=20, fontweight="bold", color="red", fontsize=20, fontweight="bold",
ha="center", va="top", ha="center", va="top",
bbox=dict(facecolor='white', alpha=0.7, edgecolor='red')) bbox=dict(facecolor='white', alpha=0.7, edgecolor='red'))
# the warning is only justified for results with a valid job_id;
# results without job id (e.g. backend errors) only get the plot marker
if getattr(in_result, "job_id", None) is not None:
if self.statusbar_overflow_label.get_text() == "":
self.statusbar_overflow_label.set_markup('<span foreground="red" weight="bold">ADC OVERFLOW</span>')
self.set_overflow_indicator( True )
if in_result.job_id not in self.overflow_job_ids:
self.overflow_job_ids.append( in_result.job_id )
logger.warning( "ADC overflow detected in job %s", in_result.job_id )
elif self.clipping_marker is not None: elif self.clipping_marker is not None:
try: try:
self.clipping_marker.remove() self.clipping_marker.remove()
+30 -5
View File
@@ -1191,10 +1191,11 @@ Public License instead of this License.
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="display_autoscaling_checkbutton"> <object class="GtkCheckButton" id="display_autoscaling_checkbutton">
<property name="label" translatable="yes">Auto-Scaling</property> <property name="label" translatable="yes">Autoscale</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<property name="halign">start</property>
<property name="tooltip-text" translatable="yes">Rescale graph if new ymax is larger than the old one or shrinked more than 20%</property> <property name="tooltip-text" translatable="yes">Rescale graph if new ymax is larger than the old one or shrinked more than 20%</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<property name="draw-indicator">True</property> <property name="draw-indicator">True</property>
@@ -1211,10 +1212,11 @@ Public License instead of this License.
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="display_statistics_checkbutton"> <object class="GtkCheckButton" id="display_statistics_checkbutton">
<property name="label" translatable="yes">Show Statistics</property> <property name="label" translatable="yes">Statistics</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<property name="halign">start</property>
<property name="tooltip-text" translatable="yes">Plot error-bars if result to plot uses statistic</property> <property name="tooltip-text" translatable="yes">Plot error-bars if result to plot uses statistic</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<property name="draw-indicator">True</property> <property name="draw-indicator">True</property>
@@ -2343,7 +2345,7 @@ Public License instead of this License.
<object class="GtkTable" id="statusbar_table"> <object class="GtkTable" id="statusbar_table">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="n-columns">8</property> <property name="n-columns">9</property>
<child> <child>
<object class="GtkVSeparator" id="vseparator1"> <object class="GtkVSeparator" id="vseparator1">
<property name="visible">True</property> <property name="visible">True</property>
@@ -2430,6 +2432,29 @@ Public License instead of this License.
<property name="y-options"/> <property name="y-options"/>
</packing> </packing>
</child> </child>
<child>
<object class="GtkEventBox" id="statusbar_overflow_eventbox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="above-child">True</property>
<signal name="button-press-event" handler="on_statusbar_overflow_label_clicked" swapped="no"/>
<child>
<object class="GtkLabel" id="statusbar_overflow_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes"/>
<property name="use-markup">True</property>
<property name="tooltip-text" translatable="yes">ADC overflow detected. Click to acknowledge.</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">7</property>
<property name="right-attach">8</property>
<property name="x-options"/>
<property name="y-options"/>
</packing>
</child>
<child> <child>
<object class="GtkLabel" id="label33"> <object class="GtkLabel" id="label33">
<property name="visible">True</property> <property name="visible">True</property>
@@ -2438,8 +2463,8 @@ Public License instead of this License.
<property name="xalign">0</property> <property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left-attach">7</property> <property name="left-attach">8</property>
<property name="right-attach">8</property> <property name="right-attach">9</property>
<property name="y-options"/> <property name="y-options"/>
</packing> </packing>
</child> </child>