switch all prints to logging module

This commit is contained in:
2026-07-13 22:59:54 +02:00
parent 0eb44039f0
commit 1bb92a9157
+107 -131
View File
@@ -70,36 +70,9 @@ debug = False
# version info # version info
from damaris import __version__ from damaris import __version__
# Unified logging
class logstream: import logging
gui_log = None logger = logging.getLogger("damaris.gui")
text_log = sys.__stdout__
def write( self, message ):
# default for stdout and stderr
if self.gui_log is not None:
self.gui_log( message )
if debug or self.gui_log is None:
self.text_log.write( message )
self.text_log.flush( )
def __call__( self, message ):
self.write( message )
def flush(self):
pass
def __del__( self ):
pass
global log
log = logstream( )
sys.stdout = log
sys.stderr = log
ExperimentHandling.log = log
ResultHandling.log = log
ResultReader.log = log
ExperimentWriter.log = log
BackendDriver.log = log
DataPool.log = log
class LockFile: class LockFile:
@@ -109,17 +82,17 @@ class LockFile:
self.conn = sqlite3.connect(self.file) self.conn = sqlite3.connect(self.file)
self.cursor = self.conn.cursor() self.cursor = self.conn.cursor()
self.id = None self.id = None
print("Connected to db..") logger.debug("Connected to db..")
def add_experiment(self): def add_experiment(self):
print("Add experiment..") logger.debug("Add experiment..")
self.id = str(uuid.uuid4()) self.id = str(uuid.uuid4())
self.cursor.execute("INSERT INTO damaris VALUES (?, ?)",(self.id, "started")) self.cursor.execute("INSERT INTO damaris VALUES (?, ?)",(self.id, "started"))
self.conn.commit() self.conn.commit()
return self.id return self.id
def del_experiment(self, id): def del_experiment(self, id):
print("Delete experiment..") logger.debug("Delete experiment..")
self.cursor.execute('DELETE FROM damaris WHERE uuid=?', (id,)) self.cursor.execute('DELETE FROM damaris WHERE uuid=?', (id,))
self.conn.commit() self.conn.commit()
return True return True
@@ -166,6 +139,13 @@ class DamarisGUI:
self.log = LogWindow( self.xml_gui , self) self.log = LogWindow( self.xml_gui , self)
# Initialize unified logging with GUI output
from damaris.gui import setup_logging
self._logger = setup_logging(
level=logging.DEBUG if debug else logging.INFO,
gui_callback=self.log,
)
self.sw = ScriptWidgets( self.xml_gui, self ) self.sw = ScriptWidgets( self.xml_gui, self )
self.toolbar_init( ) self.toolbar_init( )
@@ -503,23 +483,23 @@ class DamarisGUI:
def start_experiment( self, widget, data=None ): def start_experiment( self, widget, data=None ):
import time import time
overall_start = time.time() overall_start = time.time()
print(f"DEBUG: start_experiment called at {overall_start}") logger.debug("start_experiment called at %s", overall_start)
# something running? # something running?
if self.si is not None or self.state != DamarisGUI.Edit_State: if self.si is not None or self.state != DamarisGUI.Edit_State:
print("Experiment is still running or cleaning up!") logger.error("Experiment is still running or cleaning up!")
return return
# get config values: # get config values:
config_start = time.time() config_start = time.time()
actual_config = self.config.get( ) actual_config = self.config.get( )
print(f"DEBUG: Config load took {time.time() - config_start:.3f}s") logger.debug("Config load took %.3fs", time.time() - config_start)
# get scripts and start script interface # get scripts and start script interface
gui_start = time.time() gui_start = time.time()
self.sw.disable_editing( ) self.sw.disable_editing( )
exp_script, res_script = self.sw.get_scripts( ) exp_script, res_script = self.sw.get_scripts( )
print(f"DEBUG: GUI operations took {time.time() - gui_start:.3f}s") logger.debug("GUI operations took %.3fs", time.time() - gui_start)
if not actual_config[ "start_result_script" ]: if not actual_config[ "start_result_script" ]:
res_script = "" res_script = ""
if not actual_config[ "start_experiment_script" ]: if not actual_config[ "start_experiment_script" ]:
@@ -529,7 +509,7 @@ class DamarisGUI:
backend = "" backend = ""
if (backend == "" and exp_script == "" and res_script == ""): if (backend == "" and exp_script == "" and res_script == ""):
print("nothing to do...so doing nothing!") logger.info("Nothing to do...so doing nothing!")
self.sw.enable_editing( ) self.sw.enable_editing( )
return return
@@ -547,11 +527,11 @@ class DamarisGUI:
ln = 0 ln = 0
if type( lo ) is not int: if type( lo ) is not int:
lo = 0 lo = 0
print("Experiment Script: %s at line %d, col %d:" % (e.__class__.__name__, ln, lo)) logger.error("Experiment Script: %s at line %d, col %d", e.__class__.__name__, ln, lo)
if e.text != "": if e.text != "":
print(e.text.rstrip()) logger.error(e.text.rstrip())
print(" "*(e.offset-1)+"^") logger.error(" "*(e.offset-1)+"^")
print(e) logger.error("%s", e)
res_code = None res_code = None
if res_script != "": if res_script != "":
@@ -565,14 +545,14 @@ class DamarisGUI:
ln = 0 ln = 0
if type( lo ) is not int: if type( lo ) is not int:
lo = 0 lo = 0
print("Result script: %s at line %d, col %d:" % (e.__class__.__name__, ln, lo)) logger.error("Result script: %s at line %d, col %d", e.__class__.__name__, ln, lo)
if e.text != "": if e.text != "":
print("\"%s\"" % e.text) logger.error("\"%s\"", e.text)
# print " "*(e.offset+1)+"^" # nice idea, but needs monospaced fonts # logger.error(" "*(e.offset+1)+"^" # nice idea, but needs monospaced fonts
pass pass
print(e) logger.error("%s", e)
print(f"DEBUG: Script compilation took {time.time() - compile_start:.3f}s") logger.debug("Script compilation took %.3fs", time.time() - compile_start)
# detect error # detect error
if (exp_script != "" and exp_code is None) or \ if (exp_script != "" and exp_code is None) or \
@@ -605,10 +585,10 @@ class DamarisGUI:
pass pass
# Use observe_data_pool(None) which is now optimized with fast TreeStore replacement # Use observe_data_pool(None) which is now optimized with fast TreeStore replacement
print(f"DEBUG: Data pool cleanup ({listener_count} listeners, {data_items} items)") logger.debug("Data pool cleanup (%d listeners, %d items)", listener_count, data_items)
self.monitor.observe_data_pool( None ) self.monitor.observe_data_pool( None )
print(f"DEBUG: Data cleanup took {time.time() - data_cleanup_start:.3f}s") logger.debug("Data cleanup took %.3fs", time.time() - data_cleanup_start)
# set the text mark for hdf logging # set the text mark for hdf logging
if self.log.textbuffer.get_mark( "lastdumped" ) is None: if self.log.textbuffer.get_mark( "lastdumped" ) is None:
@@ -619,13 +599,11 @@ class DamarisGUI:
interval = 0.1 interval = 0.1
self.stop_experiment_flag.clear() self.stop_experiment_flag.clear()
# Add timing debug info
import time
start_time = time.time() start_time = time.time()
print(f"DEBUG: Starting experiment at {start_time}") logger.debug("Starting experiment at %s", start_time)
self.id = self.lockfile.add_experiment() self.id = self.lockfile.add_experiment()
print(f"DEBUG: Lock file operation took {time.time() - start_time:.3f}s") logger.debug("Lock file operation took %.3fs", time.time() - start_time)
# Add more timing points # Add more timing points
lock_wait_start = time.time() lock_wait_start = time.time()
@@ -639,9 +617,9 @@ class DamarisGUI:
loop_run = 0 loop_run = 0
loop_run += interval loop_run += interval
print(f"DEBUG: Lock wait took {time.time() - lock_wait_start:.3f}s") logger.debug("Lock wait took %.3fs", time.time() - lock_wait_start)
if self.stop_experiment_flag.isSet(): if self.stop_experiment_flag.is_set():
#Experiment has been stopped, clean up and leave #Experiment has been stopped, clean up and leave
self.experiment_script_statusbar_label.set_text("Experiment stopped") self.experiment_script_statusbar_label.set_text("Experiment stopped")
self.state = DamarisGUI.Edit_State self.state = DamarisGUI.Edit_State
@@ -665,7 +643,7 @@ class DamarisGUI:
self.spool_dir, self.spool_dir,
clear_jobs=actual_config[ "del_jobs_after_execution" ], clear_jobs=actual_config[ "del_jobs_after_execution" ],
clear_results=actual_config[ "del_results_after_processing" ] ) clear_results=actual_config[ "del_results_after_processing" ] )
print(f"DEBUG: ScriptInterface creation took {time.time() - script_interface_start:.3f}s") logger.debug("ScriptInterface creation took %.3fs", time.time() - script_interface_start)
self.data = self.si.data self.data = self.si.data
# run frontend and script engines # run frontend and script engines
@@ -673,18 +651,18 @@ class DamarisGUI:
# Start temperature monitoring if configured (before scripts start) # Start temperature monitoring if configured (before scripts start)
temp_start = time.time() temp_start = time.time()
self.start_temperature_monitoring(actual_config) self.start_temperature_monitoring(actual_config)
print(f"DEBUG: Temperature monitoring startup took {time.time() - temp_start:.3f}s") logger.debug("Temperature monitoring startup took %.3fs", time.time() - temp_start)
scripts_start = time.time() scripts_start = time.time()
self.si.runScripts( ) self.si.runScripts( )
print(f"DEBUG: Script execution startup took {time.time() - scripts_start:.3f}s") logger.debug("Script execution startup took %.3fs", time.time() - scripts_start)
except Exception as e: except Exception as e:
#print "ToDo evaluate exception",str(e), "at",traceback.extract_tb(sys.exc_info()[2])[-1][1:3] #logger.debug("ToDo evaluate exception %s at %s", str(e), traceback.extract_tb(sys.exc_info()[2])[-1][1:3])
#print "Full traceback:" #logger.debug("Full traceback:")
traceback_file = io.StringIO( ) traceback_file = io.StringIO( )
traceback.print_tb( sys.exc_info( )[ 2 ], None, traceback_file ) traceback.print_tb( sys.exc_info( )[ 2 ], None, traceback_file )
self.main_notebook.set_current_page( DamarisGUI.Log_Display ) self.main_notebook.set_current_page( DamarisGUI.Log_Display )
print("Error while executing scripts: %s\n" % str( e ) + traceback_file.getvalue( )) logger.error("Error while executing scripts: %s", str( e ) + traceback_file.getvalue( ))
traceback_file = None traceback_file = None
self.data = None self.data = None
@@ -692,14 +670,14 @@ class DamarisGUI:
still_running = [_f for _f in [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] if _f] still_running = [_f for _f in [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] if _f]
for r in still_running: for r in still_running:
r.quit_flag.set( ) r.quit_flag.set( )
print("waiting for threads stoping...", end=' ') logger.info("Waiting for threads to stop...")
still_running = [x for x in [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] if x is not None and x.is_alive( )] still_running = [x for x in [ self.si.exp_handling, self.si.res_handling, self.si.back_driver ] if x is not None and x.is_alive( )]
for t in still_running: for t in still_running:
while t.is_alive(): while t.is_alive():
while gtk.events_pending(): while gtk.events_pending():
gtk.main_iteration_do(False) gtk.main_iteration_do(False)
t.join( 0.05 ) t.join( 0.05 )
print("done") logger.info("Threads stopped")
# cleanup # cleanup
self.si = None self.si = None
@@ -786,17 +764,18 @@ class DamarisGUI:
if not self.si.exp_handling.is_alive( ): if not self.si.exp_handling.is_alive( ):
self.si.exp_handling.join( ) self.si.exp_handling.join( )
if self.si.exp_handling.raised_exception: if self.si.exp_handling.raised_exception:
print("experiment script failed at line %d (function %s): %s" % (self.si.exp_handling.location[ 0 ], logger.error("Experiment script failed at line %d (function %s): %s",
self.si.exp_handling.location[ 1 ], self.si.exp_handling.location[ 0 ],
self.si.exp_handling.raised_exception)) self.si.exp_handling.location[ 1 ],
print("Full traceback", self.si.exp_handling.traceback) self.si.exp_handling.raised_exception)
logger.error("Full traceback: %s", self.si.exp_handling.traceback)
e_text = "Experiment Script Failed (%d)" % e e_text = "Experiment Script Failed (%d)" % e
else: else:
e_text = "Experiment Script Finished (%d)" % e e_text = "Experiment Script Finished (%d)" % e
print("experiment script finished") logger.info("Experiment script finished")
self.si.exp_handling = None self.si.exp_handling = None
else: else:
#print self.si.back_driver.get_messages() # Backend messages are now handled by FileTailerHandler
e_text = "Experiment Script Running (%d)" % e e_text = "Experiment Script Running (%d)" % e
e_text += experimenttimetext e_text += experimenttimetext
@@ -804,10 +783,11 @@ class DamarisGUI:
if not self.si.res_handling.is_alive( ): if not self.si.res_handling.is_alive( ):
self.si.res_handling.join( ) self.si.res_handling.join( )
if self.si.res_handling.raised_exception: if self.si.res_handling.raised_exception:
print("result script failed at line %d (function %s): %s" % (self.si.res_handling.location[ 0 ], logger.error("Result script failed at line %d (function %s): %s",
self.si.res_handling.location[ 1 ], self.si.res_handling.location[ 0 ],
self.si.res_handling.raised_exception)) self.si.res_handling.location[ 1 ],
print("Full traceback", self.si.res_handling.traceback) self.si.res_handling.raised_exception)
logger.error("Full traceback: %s", self.si.res_handling.traceback)
r_text = "Result Script Failed (%d)" % r r_text = "Result Script Failed (%d)" % r
else: else:
r_text = "Result Script Finished (%d)" % r r_text = "Result Script Finished (%d)" % r
@@ -831,16 +811,16 @@ class DamarisGUI:
if self.dump_thread is not None: if self.dump_thread is not None:
if self.dump_thread.is_alive( ): if self.dump_thread.is_alive( ):
sys.stdout.write( "." ) sys.stderr.write( "." )
self.dump_dots += 1 self.dump_dots += 1
if self.dump_dots > 80: if self.dump_dots > 80:
print() sys.stderr.write("\n")
self.dump_dots = 0 self.dump_dots = 0
else: else:
self.dump_thread.join( ) self.dump_thread.join( )
self.dump_thread = None self.dump_thread = None
dump_size = os.stat( self.dump_filename ).st_size / 1e6 dump_size = os.stat( self.dump_filename ).st_size / 1e6
print("done (%.1f s, %.1f MB)" % (time.time( ) - self.dump_start_time, dump_size)) logger.info("Done (%.1f s, %.1f MB)", time.time( ) - self.dump_start_time, dump_size)
gdk.threads_enter( ) gdk.threads_enter( )
if e_text: if e_text:
@@ -856,7 +836,7 @@ class DamarisGUI:
# Stop temperature monitoring when experiment finishes # Stop temperature monitoring when experiment finishes
self.stop_temperature_monitoring() self.stop_temperature_monitoring()
if self.save_thread is None and self.dump_filename != "": if self.save_thread is None and self.dump_filename != "":
print("all subprocesses ended, saving data pool") logger.info("All subprocesses ended, saving data pool")
# Disable run button during data saving to prevent UI confusion # Disable run button during data saving to prevent UI confusion
gdk.threads_enter() gdk.threads_enter()
self.toolbar_run_button.set_sensitive(False) self.toolbar_run_button.set_sensitive(False)
@@ -875,21 +855,21 @@ class DamarisGUI:
self.toolbar_stop_button.set_sensitive( False ) self.toolbar_stop_button.set_sensitive( False )
gdk.threads_leave( ) gdk.threads_leave( )
if len( still_running ) != 0: if len( still_running ) != 0:
print("subprocess(es) still running: " + ', '.join( [s.getName( ) for s in still_running] )) logger.warning("Subprocess(es) still running: %s", ', '.join( [s.getName( ) for s in still_running] ))
return True return True
else: else:
if self.save_thread is not None: if self.save_thread is not None:
if self.save_thread.is_alive( ): if self.save_thread.is_alive( ):
sys.stdout.write( "." ) sys.stderr.write( "." )
self.dump_dots += 1 self.dump_dots += 1
if self.dump_dots > 80: if self.dump_dots > 80:
print() sys.stderr.write("\n")
self.dump_dots = 0 self.dump_dots = 0
return True return True
self.save_thread.join( ) self.save_thread.join( )
self.save_thread = None self.save_thread = None
dump_size = os.stat( self.dump_filename ).st_size / 1e6 dump_size = os.stat( self.dump_filename ).st_size / 1e6
print("done (%.1f s, %.1f MB)" % (time.time( ) - self.dump_start_time, dump_size)) logger.info("Done (%.1f s, %.1f MB)", time.time( ) - self.dump_start_time, dump_size)
# keep data to display but throw away everything else # keep data to display but throw away everything else
self.si = None self.si = None
@@ -910,7 +890,7 @@ class DamarisGUI:
dump_interval = self.dump_timeinterval if self.dump_timeinterval > 0 else 2.0 dump_interval = self.dump_timeinterval if self.dump_timeinterval > 0 else 2.0
if self.dump_thread is None and self.dump_filename != "" and \ if self.dump_thread is None and self.dump_filename != "" and \
self.last_dumped + dump_interval < time.time( ): self.last_dumped + dump_interval < time.time( ):
print("dumping data pool") logger.info("Dumping data pool")
self.dump_start_time = time.time( ) self.dump_start_time = time.time( )
self.dump_dots = 0 self.dump_dots = 0
# thread to save data... # thread to save data...
@@ -945,13 +925,13 @@ class DamarisGUI:
try: try:
self.dump_filename = actual_config.get( "data_pool_name" ) % extensions_dict self.dump_filename = actual_config.get( "data_pool_name" ) % extensions_dict
except ValueError: except ValueError:
print("invalid formating character in '" + actual_config.get( "data_pool_name" ) + "'") logger.error("Invalid formatting character in '%s'", actual_config.get( "data_pool_name" ))
self.dump_filename = "DAMARIS_data_pool.h5" self.dump_filename = "DAMARIS_data_pool.h5"
print("reseting dumpfile to " + self.dump_filename) logger.info("Resetting dumpfile to %s", self.dump_filename)
del extensions_dict del extensions_dict
if os.path.split( self.dump_filename )[ 1 ] == "" or os.path.isdir( self.dump_filename ): if os.path.split( self.dump_filename )[ 1 ] == "" or os.path.isdir( self.dump_filename ):
print("The dump filename is a directory, using filename 'DAMARIS_data_pool.h5'") logger.warning("Dump filename is a directory, using filename 'DAMARIS_data_pool.h5'")
self.dump_filename += os.sep + "DAMARIS_data_pool.h5" self.dump_filename += os.sep + "DAMARIS_data_pool.h5"
# compression # compression
@@ -968,7 +948,7 @@ class DamarisGUI:
try: try:
self.dump_timeinterval = int( 60 * float( actual_config[ "data_pool_write_interval" ] ) ) self.dump_timeinterval = int( 60 * float( actual_config[ "data_pool_write_interval" ] ) )
except ValueError as e: except ValueError as e:
print("configuration provides non-number for dump interval: " + str( e )) logger.warning("Configuration provides non-number for dump interval: %s", str( e ))
# if existent, move away old files # if existent, move away old files
if os.path.isfile( self.dump_filename ): if os.path.isfile( self.dump_filename ):
@@ -990,15 +970,15 @@ class DamarisGUI:
last_backup -= 1 last_backup -= 1
os.rename( self.dump_filename, dump_filename_pattern % 0 ) os.rename( self.dump_filename, dump_filename_pattern % 0 )
if cummulated_size > (1 << 30): if cummulated_size > (1 << 30):
print("Warning: the cumulated backups size of '%s' is %d MByte" % (self.dump_filename, logger.warning("The cumulated backups size of '%s' is %d MByte", self.dump_filename,
cummulated_size / (1 << 20))) cummulated_size / (1 << 20))
# init is finnished now # init is finnished now
# now it's time to create the hdf file # now it's time to create the hdf file
dump_file = None dump_file = None
if not os.path.isfile( self.dump_filename ): if not os.path.isfile( self.dump_filename ):
if not init: if not init:
print("dump file \"%s\" vanished unexpectedly, creating new one" % self.dump_filename) logger.warning("Dump file \"%s\" vanished unexpectedly, creating new one", self.dump_filename)
# have a look to the path and create necessary directories # have a look to the path and create necessary directories
dir_stack = [ ] dir_stack = [ ]
dir_trunk = os.path.dirname( os.path.abspath( self.dump_filename ) ) dir_trunk = os.path.dirname( os.path.abspath( self.dump_filename ) )
@@ -1012,8 +992,7 @@ class DamarisGUI:
continue continue
os.mkdir( dir_trunk ) os.mkdir( dir_trunk )
except OSError as e: except OSError as e:
print(e) logger.error("Could not create dump directory '%s', so hdf5 dumps disabled: %s", dir_trunk, e)
print("could not create dump directory '%s', so hdf5 dumps disabled" % dir_trunk)
self.dump_filename = "" self.dump_filename = ""
self.dump_timeinterval = 0 self.dump_timeinterval = 0
return True return True
@@ -1056,7 +1035,7 @@ class DamarisGUI:
if dump_file is None: if dump_file is None:
# exit! # exit!
print("could not create dump directory '%s', so hdf5 dumps disabled" % dir_trunk) logger.error("Could not create dump directory '%s', so hdf5 dumps disabled", dir_trunk)
self.dump_filename = "" self.dump_filename = ""
self.dump_timeinterval = 0 self.dump_timeinterval = 0
return True return True
@@ -1200,22 +1179,22 @@ class DamarisGUI:
temp_baudrate = config.get("temperature_baudrate", 19200) temp_baudrate = config.get("temperature_baudrate", 19200)
if not temp_device: if not temp_device:
print("Temperature monitoring: No device configured for Eurotherm") logger.warning("Temperature monitoring: No device configured for Eurotherm")
return return
self.temp_controller = create_controller( self.temp_controller = create_controller(
"eurotherm", temp_device, baudrate=temp_baudrate "eurotherm", temp_device, baudrate=temp_baudrate
) )
print(f"Temperature monitoring started with Eurotherm on {temp_device} (interval: {temp_interval}s)") logger.info("Temperature monitoring started with Eurotherm on %s (interval: %ss)", temp_device, temp_interval)
elif controller_type == "simulated": elif controller_type == "simulated":
# Simulated controller doesn't need device configuration # Simulated controller doesn't need device configuration
# Use default parameters: 290K base, 10K amplitude, 60s period, 5% noise, 10% missing # Use default parameters: 290K base, 10K amplitude, 60s period, 5% noise, 10% missing
self.temp_controller = create_controller("simulated") self.temp_controller = create_controller("simulated")
print(f"Temperature monitoring started with simulated controller (interval: {temp_interval}s)") logger.info("Temperature monitoring started with simulated controller (interval: %ss)", temp_interval)
else: else:
print(f"Temperature monitoring: Unknown controller type: {controller_type}") logger.warning("Temperature monitoring: Unknown controller type: %s", controller_type)
return return
# Create and start monitor thread # Create and start monitor thread
@@ -1228,7 +1207,7 @@ class DamarisGUI:
self.temp_monitor.start() self.temp_monitor.start()
except Exception as e: except Exception as e:
print(f"Failed to start temperature monitoring: {e}") logger.error("Failed to start temperature monitoring: %s", e)
import traceback import traceback
traceback.print_exc() traceback.print_exc()
self.temp_controller = None self.temp_controller = None
@@ -1241,9 +1220,9 @@ class DamarisGUI:
if self.temp_monitor is not None: if self.temp_monitor is not None:
try: try:
self.temp_monitor.stop() self.temp_monitor.stop()
print("Temperature monitoring stopped") logger.info("Temperature monitoring stopped")
except Exception as e: except Exception as e:
print(f"Error stopping temperature monitoring: {e}") logger.error("Error stopping temperature monitoring: %s", e)
finally: finally:
self.temp_monitor = None self.temp_monitor = None
@@ -1251,7 +1230,7 @@ class DamarisGUI:
try: try:
self.temp_controller.close() self.temp_controller.close()
except Exception as e: except Exception as e:
print(f"Error closing temperature controller: {e}") logger.error("Error closing temperature controller: %s", e)
finally: finally:
self.temp_controller = None self.temp_controller = None
@@ -1282,7 +1261,7 @@ class DamarisGUI:
if not self.doc_browser.is_alive( ): if not self.doc_browser.is_alive( ):
self.doc_browser.join( ) self.doc_browser.join( )
if self.doc_browser.my_webbrowser is not None: if self.doc_browser.my_webbrowser is not None:
print("new browser tab") logger.debug("New browser tab")
self.doc_browser.my_webbrowser.open_new_tab( self.doc_urls[ requested_doc ] ) self.doc_browser.my_webbrowser.open_new_tab( self.doc_urls[ requested_doc ] )
else: else:
del self.doc_browser del self.doc_browser
@@ -1292,7 +1271,7 @@ class DamarisGUI:
self.doc_browser = start_browser( self.doc_urls[ requested_doc ] ) self.doc_browser = start_browser( self.doc_urls[ requested_doc ] )
self.doc_browser.start( ) self.doc_browser.start( )
else: else:
print("missing docs for '%s'" % (requested_doc)) logger.warning("Missing docs for '%s'", requested_doc)
show_manual = show_doc_menu show_manual = show_doc_menu
@@ -1316,11 +1295,11 @@ class start_browser( threading.Thread ):
# this is what it should be everywhere! # this is what it should be everywhere!
self.my_webbrowser = webbrowser.get( ) self.my_webbrowser = webbrowser.get( )
if self.my_webbrowser is not None: if self.my_webbrowser is not None:
print("starting web browser (module webbrowser)") logger.info("Starting web browser (module webbrowser)")
self.my_webbrowser.open( self.start_url ) self.my_webbrowser.open( self.start_url )
return True return True
# last resort # last resort
print("starting web browser (webbrowser.py)") logger.info("Starting web browser (webbrowser.py)")
self.my_webbrowser_process = os.spawnl( os.P_NOWAIT, self.my_webbrowser_process = os.spawnl( os.P_NOWAIT,
sys.executable, sys.executable,
os.path.basename( sys.executable ), os.path.basename( sys.executable ),
@@ -1343,8 +1322,6 @@ class LogWindow:
font_desc = pango.FontDescription("Monospace 10") font_desc = pango.FontDescription("Monospace 10")
self.textview.modify_font(font_desc) self.textview.modify_font(font_desc)
self.textbuffer = self.textview.get_buffer( ) self.textbuffer = self.textview.get_buffer( )
self.logstream = log
self.logstream.gui_log = self
self.last_timetag = None self.last_timetag = None
self( "Started in directory %s\n" % os.getcwd( ) ) self( "Started in directory %s\n" % os.getcwd( ) )
@@ -1374,8 +1351,7 @@ class LogWindow:
return False return False
def __del__( self ): def __del__( self ):
self.logstream.gui_log = None pass
self.logstream = None
class ScriptWidgets: class ScriptWidgets:
@@ -1642,8 +1618,8 @@ get_ylabel set_ylabel"""
ln = 0 ln = 0
if type( lo ) is not int: if type( lo ) is not int:
lo = 0 lo = 0
print("Syntax Error:\n%s in %s at line %d, offset %d" % ( logger.error("Syntax Error:\n%s in %s at line %d, offset %d",
str( se ), se.filename, ln, lo) + "\n(ToDo: Dialog)") str( se ), se.filename, ln, lo)
if ln > 0 and ln <= tb.get_line_count( ): if ln > 0 and ln <= tb.get_line_count( ):
new_place = tb.get_iter_at_line_offset( ln - 1, 0 ) new_place = tb.get_iter_at_line_offset( ln - 1, 0 )
if lo > 0 and lo <= new_place.get_chars_in_line( ): if lo > 0 and lo <= new_place.get_chars_in_line( ):
@@ -1651,7 +1627,7 @@ get_ylabel set_ylabel"""
tb.place_cursor( new_place ) tb.place_cursor( new_place )
tv.scroll_to_iter( new_place, 0.2, False, 0, 0 ) tv.scroll_to_iter( new_place, 0.2, False, 0, 0 )
except Exception as e: except Exception as e:
print("Compilation Error:\n" + str( e ) + "\n(ToDo: Dialog)") logger.error("Compilation Error:\n%s", str( e ))
def notebook_page_switched( self, notebook, page, pagenumber ): def notebook_page_switched( self, notebook, page, pagenumber ):
self.set_toolbuttons_status( ) self.set_toolbuttons_status( )
@@ -1669,7 +1645,7 @@ get_ylabel set_ylabel"""
newline = self.data_handling_line_indicator.get_value_as_int( ) - 1 newline = self.data_handling_line_indicator.get_value_as_int( ) - 1
newcol = column_indicator.get_value_as_int( ) - 1 newcol = column_indicator.get_value_as_int( ) - 1
else: else:
print("unknown line/column selector") logger.error("Unknown line/column selector")
return False return False
textbuffer = textview.get_buffer( ) textbuffer = textview.get_buffer( )
@@ -2475,13 +2451,13 @@ pygobject version %(pygobject)s
elif isinstance( model, gtk.TreeStore ): elif isinstance( model, gtk.TreeStore ):
model.append( None, [ libname ] ) model.append( None, [ libname ] )
else: else:
print("cannot append compression lib name to %s" % model.__class__.__name__) logger.warning("Cannot append compression lib name to %s", model.__class__.__name__)
# debug message # debug message
if debug: if debug:
print("DAMARIS", __version__) logger.debug("DAMARIS %s", __version__)
print(components_text % components_versions) logger.debug(components_text % components_versions)
# set no compression as default... # set no compression as default...
self.config_data_pool_complib.set_active( 0 ) self.config_data_pool_complib.set_active( 0 )
@@ -2497,7 +2473,7 @@ pygobject version %(pygobject)s
if os.access( self.system_default_filename, os.R_OK ): if os.access( self.system_default_filename, os.R_OK ):
self.load_config( self.system_default_filename ) self.load_config( self.system_default_filename )
else: else:
print("can not read system defaults from %s, ask your instrument responsible if required" % self.system_default_filename) logger.warning("Can not read system defaults from %s, ask your instrument responsible if required", self.system_default_filename)
self.config_from_system = self.get( ) self.config_from_system = self.get( )
self.load_config( ) self.load_config( )
@@ -2620,7 +2596,7 @@ pygobject version %(pygobject)s
iter = model.iter_next( iter ) iter = model.iter_next( iter )
# if this compression method is not supported, warn and do nothing # if this compression method is not supported, warn and do nothing
if iter is None: if iter is None:
print("compression method %s is not supported" % config[ "data_pool_complib" ]) logger.warning("Compression method %s is not supported", config[ "data_pool_complib" ])
def on_adc_bit_depth_changed(self, widget): def on_adc_bit_depth_changed(self, widget):
ADC_Result.default_bit_depth = widget.get_value_as_int() ADC_Result.default_bit_depth = widget.get_value_as_int()
@@ -2784,7 +2760,7 @@ pygobject version %(pygobject)s
readfile = open( filename, "rb" ) readfile = open( filename, "rb" )
except Exception as e: except Exception as e:
if debug: if debug:
print("Could not open %s: %s" % (filename, str( e ))) logger.debug("Could not open %s: %s", filename, str( e ))
return return
# parser functions # parser functions
@@ -2836,7 +2812,7 @@ pygobject version %(pygobject)s
if not os.path.isdir( dirs ): if not os.path.isdir( dirs ):
os.makedirs( dirs ) os.makedirs( dirs )
print("save config to: "+filename) logger.info("Save config to: %s", filename)
configfile = open( filename, "w" ) configfile = open( filename, "w" )
configfile.write( "<?xml version='1.0'?>\n" ) configfile.write( "<?xml version='1.0'?>\n" )
@@ -2845,10 +2821,10 @@ pygobject version %(pygobject)s
if k in self.config_from_system \ if k in self.config_from_system \
and self.config_from_system[ k ] == v: and self.config_from_system[ k ] == v:
if debug: if debug:
print("Ignoring for write, because system value for %r is %r equal to %r" % \ logger.debug("Ignoring for write, because system value for %r is %r equal to %r",
(k, self.config_from_system[ k ], v)) k, self.config_from_system[ k ], v)
continue continue
print(k,v, type(v)) logger.debug("Config key: %s = %r (%s)", k, v, type(v).__name__)
val = "" val = ""
typename = "" typename = ""
if type( v ) is bool: if type( v ) is bool:
@@ -3097,11 +3073,11 @@ class MonitorWidgets:
pwd = namelist[ : ] pwd = namelist[ : ]
iter = self.source_list_find( namelist ) iter = self.source_list_find( namelist )
if iter is None or len( namelist ) > 0: if iter is None or len( namelist ) > 0:
print("source_list_remove: WARNING: Not found") logger.warning("source_list_remove: Not found")
return return
model = self.display_source_treestore model = self.display_source_treestore
if model.iter_has_child( iter ): if model.iter_has_child( iter ):
print("source_list_remove: WARNING: Request to delete a tree") logger.warning("source_list_remove: Request to delete a tree")
return return
while True: while True:
parent = model.iter_parent( iter ) parent = model.iter_parent( iter )
@@ -3186,7 +3162,7 @@ class MonitorWidgets:
if event.subject.startswith( "__" ): if event.subject.startswith( "__" ):
return return
if debug and self.update_counter < 0: if debug and self.update_counter < 0:
print("negative event count!", self.update_counter) logger.debug("Negative event count: %d", self.update_counter)
# Throttling removed as it blocks data production thread. # Throttling removed as it blocks data production thread.
# GUI updates are already decoupled via idle_add. # GUI updates are already decoupled via idle_add.
@@ -3232,10 +3208,10 @@ class MonitorWidgets:
do fast work selecting important events do fast work selecting important events
""" """
if debug and self.update_counter < 0: if debug and self.update_counter < 0:
print("negative event count!", self.update_counter) logger.debug("Negative event count: %d", self.update_counter)
if self.update_counter > 5: if self.update_counter > 5:
if debug: if debug:
print("sleeping to find time for graphics updates") logger.debug("Sleeping to find time for graphics updates")
threading.Event( ).wait( 0.05 ) threading.Event( ).wait( 0.05 )
while self.update_counter > 15: while self.update_counter > 15:
threading.Event( ).wait( 0.05 ) threading.Event( ).wait( 0.05 )
@@ -3264,7 +3240,7 @@ class MonitorWidgets:
if self.displayed_data[ 1 ] is new_data_struct: if self.displayed_data[ 1 ] is new_data_struct:
# update display only # update display only
if self.update_counter > 10: if self.update_counter > 10:
print("update queue too long (%d>10): skipping one update" % self.update_counter) logger.warning("Update queue too long (%d>10): skipping one update", self.update_counter)
else: else:
gdk.threads_enter( ) gdk.threads_enter( )
try: try:
@@ -3282,7 +3258,7 @@ class MonitorWidgets:
new_data_struct.register_listener( self.datastructures_listener ) new_data_struct.register_listener( self.datastructures_listener )
self.displayed_data[ 1 ] = new_data_struct self.displayed_data[ 1 ] = new_data_struct
if self.update_counter > 10: if self.update_counter > 10:
print("update queue too long (%d>10): skipping one update" % self.update_counter) logger.warning("Update queue too long (%d>10): skipping one update", self.update_counter)
else: else:
gdk.threads_enter( ) gdk.threads_enter( )
try: try:
@@ -3323,7 +3299,7 @@ class MonitorWidgets:
self.update_counter_lock.release( ) self.update_counter_lock.release( )
# print "update display", self.update_counter # print "update display", self.update_counter
if self.update_counter > 10: if self.update_counter > 10:
print("update queue too long (%d>10): skipping one update" % self.update_counter) logger.warning("Update queue too long (%d>10): skipping one update", self.update_counter)
return return
if self.displayed_data[ 0 ] is None or subject != self.displayed_data[ 0 ]: if self.displayed_data[ 0 ] is None or subject != self.displayed_data[ 0 ]:
return return
@@ -3751,7 +3727,7 @@ class MonitorWidgets:
moving_average = data_slice = None moving_average = data_slice = None
if max_points_to_display > 0 and len( xdata ) > max_points_to_display: if max_points_to_display > 0 and len( xdata ) > max_points_to_display:
print("decimating data to %d points by moving average (prevent crash of matplotlib)" % max_points_to_display) logger.warning("Decimating data to %d points by moving average (prevent crash of matplotlib)", max_points_to_display)
n = numpy.ceil( len( xdata ) / max_points_to_display ) n = numpy.ceil( len( xdata ) / max_points_to_display )
moving_average = numpy.ones( n, dtype="float" ) / n moving_average = numpy.ones( n, dtype="float" ) / n
data_slice = numpy.array( numpy.floor( numpy.arange( max_points_to_display, dtype="float" ) \ data_slice = numpy.array( numpy.floor( numpy.arange( max_points_to_display, dtype="float" ) \