diff --git a/software/control/gui.py b/software/control/gui.py index 5daf3fc80..fede936c2 100644 --- a/software/control/gui.py +++ b/software/control/gui.py @@ -14,6 +14,7 @@ import control.core as core import control.microcontroller as microcontroller from control._def import * +import squid.logging import pyqtgraph.dockarea as dock SINGLE_WINDOW = True # set to False if use separate windows for display and control @@ -26,6 +27,8 @@ class OctopiGUI(QMainWindow): def __init__(self, is_simulation = False, *args, **kwargs): super().__init__(*args, **kwargs) + self.log = squid.logging.get_logger(self.__class__.__name__) + # load window if ENABLE_TRACKING: self.imageDisplayWindow = core.ImageDisplayWindow(draw_crosshairs=True,autoLevels=AUTOLEVEL_DEFAULT_SETTING) @@ -52,11 +55,11 @@ def __init__(self, is_simulation = False, *args, **kwargs): except: self.camera = camera.Camera_Simulation(rotate_image_angle=ROTATE_IMAGE_ANGLE,flip_image=FLIP_IMAGE) self.camera.open() - print('! camera not detected, using simulated camera !') + self.log.error("camera not detected, using simulated camera") try: self.microcontroller = microcontroller.Microcontroller(version=CONTROLLER_VERSION) except: - print('! Microcontroller not detected, using simulated microcontroller !') + self.log.error("Microcontroller not detected, using simulated microcontroller") self.microcontroller = microcontroller.Microcontroller_Simulation() # reset the MCU diff --git a/software/control/gui_hcs.py b/software/control/gui_hcs.py index 511aa0ae6..7097766a4 100644 --- a/software/control/gui_hcs.py +++ b/software/control/gui_hcs.py @@ -83,12 +83,12 @@ SINGLE_WINDOW = True # set to False if use separate windows for display and control -class OctopiGUI(QMainWindow): +class HighContentScreeningGui(QMainWindow): fps_software_trigger = 100 def __init__(self, is_simulation=False, performance_mode=False, *args, **kwargs): super().__init__(*args, **kwargs) - + self.log = squid.logging.get_logger(self.__class__.__name__) self.performance_mode = performance_mode or PERFORMANCE_MODE self.loadObjects(is_simulation) @@ -123,7 +123,7 @@ def loadObjects(self, is_simulation): try: self.loadHardwareObjects() except Exception: - log.error("---- !! ERROR CONNECTING TO HARDWARE !! ----", stack_info=True, exc_info=True) + self.log.error("---- !! ERROR CONNECTING TO HARDWARE !! ----", stack_info=True, exc_info=True) raise # Common object initialization @@ -159,7 +159,7 @@ def loadObjects(self, is_simulation): self.laserAutofocusController = core.LaserAutofocusController(self.microcontroller,self.camera_focus,self.liveController_focus_camera,self.navigationController,has_two_interfaces=HAS_TWO_INTERFACES,use_glass_top=USE_GLASS_TOP,look_for_cache=False) def loadSimulationObjects(self): - log.debug("Loading simulated hardware objects...") + self.log.debug("Loading simulated hardware objects...") # Initialize simulation objects if ENABLE_SPINNING_DISK_CONFOCAL: self.xlight = serial_peripherals.XLight_Simulation() @@ -184,7 +184,7 @@ def loadHardwareObjects(self): try: self.xlight = serial_peripherals.XLight(XLIGHT_SERIAL_NUMBER, XLIGHT_SLEEP_TIME_FOR_WHEEL) except Exception: - log.error("Error initializing Spinning Disk Confocal") + self.log.error("Error initializing Spinning Disk Confocal") raise if ENABLE_NL5: @@ -192,7 +192,7 @@ def loadHardwareObjects(self): import control.NL5 as NL5 self.nl5 = NL5.NL5() except Exception: - log.error("Error initializing NL5") + self.log.error("Error initializing NL5") raise if ENABLE_CELLX: @@ -202,7 +202,7 @@ def loadHardwareObjects(self): self.cellx.set_modulation(channel, CELLX_MODULATION) self.cellx.turn_on(channel) except Exception: - log.error("Error initializing CellX") + self.log.error("Error initializing CellX") raise if USE_LDI_SERIAL_CONTROL: @@ -212,7 +212,7 @@ def loadHardwareObjects(self): self.ldi.set_intensity_mode(LDI_INTENSITY_MODE) self.ldi.set_shutter_mode(LDI_SHUTTER_MODE) except Exception: - log.error("Error initializing LDI") + self.log.error("Error initializing LDI") raise if SUPPORT_LASER_AUTOFOCUS: @@ -222,7 +222,7 @@ def loadHardwareObjects(self): self.camera_focus.open() self.camera_focus.set_pixel_format('MONO8') except Exception: - log.error(f"Error initializing Laser Autofocus Camera") + self.log.error(f"Error initializing Laser Autofocus Camera") raise try: @@ -231,34 +231,34 @@ def loadHardwareObjects(self): self.camera.open() self.camera.set_pixel_format(DEFAULT_PIXEL_FORMAT) except Exception: - log.error("Error initializing Main Camera") + self.log.error("Error initializing Main Camera") raise if USE_ZABER_EMISSION_FILTER_WHEEL: try: self.emission_filter_wheel = serial_peripherals.FilterController(FILTER_CONTROLLER_SERIAL_NUMBER, 115200, 8, serial.PARITY_NONE, serial.STOPBITS_ONE) except Exception: - log.error("Error initializing Zaber Emission Filter Wheel") + self.log.error("Error initializing Zaber Emission Filter Wheel") raise if USE_OPTOSPIN_EMISSION_FILTER_WHEEL: try: self.emission_filter_wheel = serial_peripherals.Optospin(SN=FILTER_CONTROLLER_SERIAL_NUMBER) except Exception: - log.error("Error initializing Optospin Emission Filter Wheel") + self.log.error("Error initializing Optospin Emission Filter Wheel") raise if USE_PRIOR_STAGE: try: self.priorstage = PriorStage(PRIOR_STAGE_SN, parent=self) except Exception: - log.error("Error initializing Prior Stage") + self.log.error("Error initializing Prior Stage") raise try: self.microcontroller = microcontroller.Microcontroller(version=CONTROLLER_VERSION, sn=CONTROLLER_SN) except Exception: - log.error(f"Error initializing Microcontroller") + self.log.error(f"Error initializing Microcontroller") raise def setupHardware(self): diff --git a/software/control/gui_malaria.py b/software/control/gui_malaria.py index 4c107d1a3..01f48f23b 100644 --- a/software/control/gui_malaria.py +++ b/software/control/gui_malaria.py @@ -1,13 +1,10 @@ # set QT_API environment variable -import os -import sys +import os os.environ["QT_API"] = "pyqt5" -import qtpy # qt libraries from qtpy.QtCore import * from qtpy.QtWidgets import * -from qtpy.QtGui import * # app specific libraries import control.widgets as widgets @@ -21,7 +18,7 @@ SINGLE_WINDOW = True # set to False if use separate windows for display and control -class OctopiGUI(QMainWindow): +class MalariaGUI(QMainWindow): # variables fps_software_trigger = 100 @@ -29,6 +26,8 @@ class OctopiGUI(QMainWindow): def __init__(self, is_simulation = False, *args, **kwargs): super().__init__(*args, **kwargs) + self.log = squid.logging.get_logger(self.__class__.__name__) + # load objects if is_simulation: self.camera = camera.Camera_Simulation(rotate_image_angle=ROTATE_IMAGE_ANGLE,flip_image=FLIP_IMAGE) @@ -40,11 +39,11 @@ def __init__(self, is_simulation = False, *args, **kwargs): except: self.camera = camera.Camera_Simulation(rotate_image_angle=ROTATE_IMAGE_ANGLE,flip_image=FLIP_IMAGE) self.camera.open() - print('! camera not detected, using simulated camera !') + self.log.error("camera not detected, using simulated camera") try: self.microcontroller = microcontroller.Microcontroller(version=CONTROLLER_VERSION) except: - print('! Microcontroller not detected, using simulated microcontroller !') + self.log.error("Microcontroller not detected, using simulated microcontroller") self.microcontroller = microcontroller.Microcontroller_Simulation() # reset the MCU @@ -77,9 +76,9 @@ def __init__(self, is_simulation = False, *args, **kwargs): while self.microcontroller.is_busy(): time.sleep(0.005) if time.time() - t0 > 10: - print('z homing timeout, the program will exit') + self.log.error('z homing timeout, the program will exit') sys.exit(1) - print('objective retracted') + self.log.info('objective retracted') # set encoder arguments # set axis pid control enable @@ -104,11 +103,11 @@ def __init__(self, is_simulation = False, *args, **kwargs): self.navigationController.set_x_limit_neg_mm(-100) self.navigationController.set_y_limit_pos_mm(100) self.navigationController.set_y_limit_neg_mm(-100) - print('start homing') + self.log.info("start homing") self.slidePositionController.move_to_slide_scanning_position() while self.slidePositionController.slide_scanning_position_reached == False: time.sleep(0.005) - print('homing finished') + self.log.info("homing finished") self.navigationController.set_x_limit_pos_mm(SOFTWARE_POS_LIMIT.X_POSITIVE) self.navigationController.set_x_limit_neg_mm(SOFTWARE_POS_LIMIT.X_NEGATIVE) self.navigationController.set_y_limit_pos_mm(SOFTWARE_POS_LIMIT.Y_POSITIVE) diff --git a/software/main.py b/software/main.py index c83875651..e92ec2ace 100644 --- a/software/main.py +++ b/software/main.py @@ -3,27 +3,22 @@ import sys import argparse os.environ["QT_API"] = "pyqt5" -import qtpy # qt libraries -from qtpy.QtCore import * from qtpy.QtWidgets import * -from qtpy.QtGui import * # app specific libraries import control.gui as gui -#import control.gui_2cameras_async as gui -#import control.gui_tiscamera as gui - -parser = argparse.ArgumentParser() -parser.add_argument("--simulation", help="Run the GUI with simulated hardware.", action = 'store_true') -args = parser.parse_args() if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--simulation", help="Run the GUI with simulated hardware.", action="store_true") + parser.add_argument("--verbose", help="Turn on verbose (DEBUG) level logging.", action="store_true") + args = parser.parse_args() app = QApplication([]) app.setStyle('Fusion') - if(args.simulation): + if args.simulation: win = gui.OctopiGUI(is_simulation = True) else: win = gui.OctopiGUI() diff --git a/software/main_hcs.py b/software/main_hcs.py index c78766bd8..a8ad9867c 100644 --- a/software/main_hcs.py +++ b/software/main_hcs.py @@ -56,7 +56,7 @@ def show_acq_config(cfm): # This allows shutdown via ctrl+C even after the gui has popped up. signal.signal(signal.SIGINT, signal.SIG_DFL) - win = gui.OctopiGUI(is_simulation=args.simulation, performance_mode=args.performance) + win = gui.HighContentScreeningGui(is_simulation=args.simulation, performance_mode=args.performance) acq_config_action = QAction("Acquisition Settings", win) acq_config_action.triggered.connect(lambda : show_acq_config(win.configurationManager)) diff --git a/software/main_malaria.py b/software/main_malaria.py index dd378a932..612f24376 100644 --- a/software/main_malaria.py +++ b/software/main_malaria.py @@ -1,14 +1,13 @@ # set QT_API environment variable +import logging import os import glob import argparse os.environ["QT_API"] = "pyqt5" -import qtpy import sys # qt libraries -from qtpy.QtCore import * from qtpy.QtWidgets import * from qtpy.QtGui import * @@ -17,12 +16,8 @@ from configparser import ConfigParser from control.widgets import ConfigEditorBackwardsCompatible, ConfigEditorForAcquisitions - from control._def import CACHED_CONFIG_FILE_PATH - -parser = argparse.ArgumentParser() -parser.add_argument("--simulation", help="Run the GUI with simulated hardware.", action = 'store_true') -args = parser.parse_args() +import squid.logging def show_config(cfp, configpath, main_gui): config_widget = ConfigEditorBackwardsCompatible(cfp, configpath, main_gui) @@ -32,21 +27,32 @@ def show_acq_config(cfm): acq_config_widget = ConfigEditorForAcquisitions(cfm) acq_config_widget.exec_() + if __name__ == "__main__": + log = squid.logging.get_logger("main_malaria") + + parser = argparse.ArgumentParser() + parser.add_argument("--simulation", help="Run the GUI with simulated hardware.", action="store_true") + parser.add_argument("--verbose", help="Turn on verbose (DEBUG) logging.", action="store_true") + args = parser.parse_args() + + if args.verbose: + squid.logging.set_log_level(logging.DEBUG) + legacy_config = False cf_editor_parser = ConfigParser() config_files = glob.glob('.' + '/' + 'configuration*.ini') if config_files: cf_editor_parser.read(CACHED_CONFIG_FILE_PATH) else: - print('configuration*.ini file not found, defaulting to legacy configuration') + log.warning('configuration*.ini file not found, defaulting to legacy configuration') legacy_config = True app = QApplication([]) app.setStyle('Fusion') - if(args.simulation): - win = gui.OctopiGUI(is_simulation = True) + if args.simulation: + win = gui.MalariaGUI(is_simulation = True) else: - win = gui.OctopiGUI() + win = gui.MalariaGUI() acq_config_action = QAction("Acquisition Settings", win) acq_config_action.triggered.connect(lambda : show_acq_config(win.configurationManager)) diff --git a/software/squid/logging.py b/software/squid/logging.py index 6aa8ec490..ff87207a4 100644 --- a/software/squid/logging.py +++ b/software/squid/logging.py @@ -36,7 +36,9 @@ def format(self, record): # Make sure the squid root logger has all the handlers we want setup. We could move this into a helper so it # isn't done at the module level, but not needing to remember to call some helper to setup formatting is nice. +# Also set the default logging level to INFO py_logging.getLogger(_squid_root_logger_name).addHandler(_COLOR_STREAM_HANDLER) +py_logging.getLogger(_squid_root_logger_name).setLevel(py_logging.INFO) def get_logger(name: Optional[str] = None) -> py_logging.Logger: