From d44aed5c4b7cf2167193b6c236b4baf705dafbae Mon Sep 17 00:00:00 2001 From: i-jey Date: Thu, 30 Jan 2025 21:34:40 -0800 Subject: [PATCH 1/2] Add monitoring and dialog box exception if a pressure leak is detected during a run. --- ulc_mm_package/QtGUI/oracle.py | 13 ++++++- ulc_mm_package/QtGUI/scope_op.py | 11 ++++++ ulc_mm_package/hardware/hardware_constants.py | 1 + ulc_mm_package/hardware/scope_routines.py | 36 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/ulc_mm_package/QtGUI/oracle.py b/ulc_mm_package/QtGUI/oracle.py index d016734f4..005b7cf0d 100644 --- a/ulc_mm_package/QtGUI/oracle.py +++ b/ulc_mm_package/QtGUI/oracle.py @@ -294,6 +294,7 @@ def _init_sigslots(self): self.scopeop.reload_pause.connect(self.reload_pause_handler) self.scopeop.lid_open_pause.connect(self.lid_open_pause_handler) + self.scopeop.pressure_leak_pause.connect(self.pressure_leak_pause_handler) self.scopeop.create_timers.connect(self.acquisition.create_timers) self.scopeop.start_timers.connect(self.acquisition.start_timers) @@ -392,6 +393,17 @@ def lid_open_pause_handler(self): self.scopeop.to_pause() self.unpause() + def pressure_leak_pause_handler(self): + if self.scopeop.state not in NO_PAUSE_STATES: + self.scopeop.to_pause() + self.display_message( + QMessageBox.Icon.Information, + "Pressure leak detected - pausing...", + 'Please open the lid and reseat the CAP module, a pressure leak has been detected. Press "OK" to resume.', + buttons=Buttons.OK, + ) + self.unpause() + def general_pause_handler( self, icon=QMessageBox.Icon.Information, @@ -428,7 +440,6 @@ def general_pause_handler( buttons=Buttons.OK, image=IMAGE_RELOAD_PATH, ) - self.close_lid_display_message() self.unpause() def unpause(self): diff --git a/ulc_mm_package/QtGUI/scope_op.py b/ulc_mm_package/QtGUI/scope_op.py index a38bf3a06..308e42826 100644 --- a/ulc_mm_package/QtGUI/scope_op.py +++ b/ulc_mm_package/QtGUI/scope_op.py @@ -92,6 +92,7 @@ class ScopeOp(QObject, NamedMachine): reload_pause = pyqtSignal(str, str) lid_open_pause = pyqtSignal() + pressure_leak_pause = pyqtSignal() create_timers = pyqtSignal() start_timers = pyqtSignal() @@ -412,6 +413,9 @@ def _check_pressure_seal(self, *args): self.logger.info( f"Pressure check ✅. Ambient absolute pressure: {self.ambient_pressure:.2f} mBar. Gauge pressure = {pdiff:.2f} mBar." ) + self.pressure_monitoring_routine = ( + self.routines.pressure_monitoring_routine(self.ambient_pressure) + ) if self.state == "pressure_check": self.next_state() except PressureSensorBusy as e: @@ -971,6 +975,7 @@ def run_experiment(self, img, timestamp) -> None: self.img_metadata["motor_pos"] = self.mscope.motor.getCurrentPosition() try: pressure, status = self.mscope.pneumatic_module.getPressure() + self.pressure_monitoring_routine.send(pressure) ( self.img_metadata["pressure_hpa"], self.img_metadata["pressure_status_flag"], @@ -978,6 +983,12 @@ def run_experiment(self, img, timestamp) -> None: except PressureSensorStaleValue as e: ## TODO??? self.logger.info(f"Stale pressure sensor value - {e}") + except PressureLeak as e: + self.logger.warning( + f"Pressure leak detected. Current pressure: {pressure:.2f}mBar (gauge: {pressure - self.ambient_pressure:.2f}mBar)." + ) + self.pressure_leak_pause.emit() + return self.img_metadata["led_pwm_val"] = self.mscope.led.pwm_duty_cycle self.img_metadata[ diff --git a/ulc_mm_package/hardware/hardware_constants.py b/ulc_mm_package/hardware/hardware_constants.py index 277bd7b26..7cf44a736 100644 --- a/ulc_mm_package/hardware/hardware_constants.py +++ b/ulc_mm_package/hardware/hardware_constants.py @@ -78,6 +78,7 @@ MPRLS_PWR = 22 MIN_PRESSURE_DIFF = 330 # In units of hPa +PRESSURE_EWMA_ALPHA = 0.1 # ================ Fan constants ================ # FAN_GPIO = 5 CAM_FAN_1 = 23 diff --git a/ulc_mm_package/hardware/scope_routines.py b/ulc_mm_package/hardware/scope_routines.py index b4c6b64a8..bee2a20e1 100644 --- a/ulc_mm_package/hardware/scope_routines.py +++ b/ulc_mm_package/hardware/scope_routines.py @@ -31,6 +31,7 @@ from ulc_mm_package.hardware.motorcontroller import Direction, MotorControllerError from ulc_mm_package.hardware.hardware_constants import ( MIN_PRESSURE_DIFF, + PRESSURE_EWMA_ALPHA, FOCUS_EWMA_ALPHA, ) from ulc_mm_package.image_processing.classic_focus import OOF, ClassicImageFocus @@ -433,6 +434,41 @@ def checkPressureDifference( ) return pressure_diff + @init_generator + def pressure_monitoring_routine( + self, ambient_pressure: float + ) -> Generator[None, float, None]: + """ + Monitor the pressure and raise an exception if it drops below the minimum required pressure difference. + + Parameters + ---------- + mscope: MalariaScope + + Exceptions + ---------- + PressureLeak: + Raised if the pressure difference is less than the minimum required (as set in `hardware_constants.py` via MIN_PRESSURE_DIFF). + """ + + pressure_ewma_filter = EWMAFiltering(PRESSURE_EWMA_ALPHA) + pressure_ewma_filter.set_init_val(ambient_pressure) + period_num = pressure_ewma_filter.get_adjustment_period_ewma() + counter = 0 + + while True: + counter += 1 + curr_pressure = yield + filtered_pressure = pressure_ewma_filter.update_and_get_val(curr_pressure) + gauge_pressure = ambient_pressure - filtered_pressure + + if counter > period_num: + if gauge_pressure < MIN_PRESSURE_DIFF: + raise PressureLeak( + f"Pressure leak detected. Could only generate {gauge_pressure:.3f}mBar of pressure difference (ambient is at: {ambient_pressure:.2f}mBar)." + ) + counter = 0 + @init_generator def find_cells_routine( self, From 60da54804418886fb0150d4b13503edaedfd41f3 Mon Sep 17 00:00:00 2001 From: i-jey Date: Thu, 30 Jan 2025 21:36:23 -0800 Subject: [PATCH 2/2] remove extraneous e --- ulc_mm_package/QtGUI/scope_op.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ulc_mm_package/QtGUI/scope_op.py b/ulc_mm_package/QtGUI/scope_op.py index 308e42826..5717c9af5 100644 --- a/ulc_mm_package/QtGUI/scope_op.py +++ b/ulc_mm_package/QtGUI/scope_op.py @@ -983,7 +983,7 @@ def run_experiment(self, img, timestamp) -> None: except PressureSensorStaleValue as e: ## TODO??? self.logger.info(f"Stale pressure sensor value - {e}") - except PressureLeak as e: + except PressureLeak: self.logger.warning( f"Pressure leak detected. Current pressure: {pressure:.2f}mBar (gauge: {pressure - self.ambient_pressure:.2f}mBar)." )