From f9970a66cb78dadc645accf95f5adbeae11e81cf Mon Sep 17 00:00:00 2001 From: appleb_m Date: Thu, 29 Jan 2026 16:46:54 +0100 Subject: [PATCH] DAQ: removed samcam script as it duplicated area_detector --- src/aare/devices/sam_cam.py | 163 ------------------------------------ 1 file changed, 163 deletions(-) delete mode 100644 src/aare/devices/sam_cam.py diff --git a/src/aare/devices/sam_cam.py b/src/aare/devices/sam_cam.py deleted file mode 100644 index 89eeb964..00000000 --- a/src/aare/devices/sam_cam.py +++ /dev/null @@ -1,163 +0,0 @@ -from epics import PV - -from aare.common.beamline import MXBeamline - - -class SamCam: - def __init__(self, bl: MXBeamline): - BEAMLINE = bl.value.upper() - sam_cam_pv_name = f"{BEAMLINE}-SAMCAM" - self.cam_exp = PV(f"{sam_cam_pv_name}:cam1:AcquireTime") - self.cam_gain = PV(f"{sam_cam_pv_name}:cam1:Gain") - self.cam_mean = PV(f"{sam_cam_pv_name}:Stats1:MeanValue_RBV") - - def auto_exposure(self, - target_mean=128, - tolerance=5, - max_iterations=50, - timeout=30.0): - """ - Auto-expose a camera by adaptively adjusting exposure and gain. - - Args: - cam_exp_pv: PV for exposure time (0 to 0.2s) - cam_gain_pv: PV for gain (36 to 512) - cam_mean_pv: PV for image mean value - target_mean: Target mean pixel value (default 128) - tolerance: Acceptable range ±tolerance (default ±5) - max_iterations: Maximum iterations before giving up - timeout: Total timeout in seconds - - Returns: - dict with status, final_mean, iterations, exposure, gain - - Raises: - TimeoutError if target not reached within timeout - ValueError if PVs are invalid - """ - import time - - start_time = time.time() - - # Validate PVs and get initial values - try: - exp = self.cam_exp.get() - gain = self.cam_gain.get() - mean = self.cam_mean.get() - except Exception as e: - raise ValueError(f"Failed to read camera PVs: {e}") - - # Hardware limits - EXP_MIN, EXP_MAX = 0.0, 0.2 - GAIN_MIN, GAIN_MAX = 36, 512 - - # Check if we're already in target range - if abs(mean - target_mean) <= tolerance: - return { - "status": "success", - "final_mean": mean, - "iterations": 0, - "exposure": exp, - "gain": gain, - "converged": True - } - - iteration = 0 - - while iteration < max_iterations: - # Check timeout - if time.time() - start_time > timeout: - raise TimeoutError( - f"Auto-exposure failed to converge after {timeout}s. " - f"Last mean: {mean:.1f}" - ) - - iteration += 1 - error = mean - target_mean # Positive = too bright, negative = too dark - - # Calculate adaptive step size based on error magnitude - # Larger errors → larger steps for faster convergence - error_magnitude = abs(error) - - if error_magnitude > 30: # Large error: aggressive steps - exp_step = 0.01 - gain_step = 40 - elif error_magnitude > 15: # Medium error: moderate steps - exp_step = 0.005 - gain_step = 20 - else: # Small error: fine adjustments - exp_step = 0.001 - gain_step = 5 - - # Strategy: Prefer adjusting gain first (faster response), then exposure - # This prioritizes the parameter that responds more quickly to changes - - if error > tolerance: # Too bright: reduce signal - # Try to reduce gain first (has faster effect on some cameras) - if gain > GAIN_MIN: - gain = max(GAIN_MIN, gain - gain_step) - self.cam_gain.put(gain) - elif exp > EXP_MIN: - exp = max(EXP_MIN, exp - exp_step) - self.cam_exp.put(exp) - else: - # Already at minimum - can't go darker - return { - "status": "warning_min_limits", - "final_mean": mean, - "iterations": iteration, - "exposure": exp, - "gain": gain, - "converged": False, - "message": "Reached minimum exposure/gain, cannot reduce further" - } - - elif error < -tolerance: # Too dark: increase signal - # Try to increase exposure first (more precise control) - if exp < EXP_MAX: - exp = min(EXP_MAX, exp + exp_step) - self.cam_exp.put(exp) - elif gain < GAIN_MAX: - gain = min(GAIN_MAX, gain + gain_step) - self.cam_gain.put(gain) - else: - # Already at maximum - can't go brighter - return { - "status": "warning_max_limits", - "final_mean": mean, - "iterations": iteration, - "exposure": exp, - "gain": gain, - "converged": False, - "message": "Reached maximum exposure/gain, cannot increase further" - } - - # Small settling time for camera to stabilize - time.sleep(0.1) - mean = self.cam_mean.get() - - # Check convergence - if abs(mean - target_mean) <= tolerance: - return { - "status": "success", - "final_mean": mean, - "iterations": iteration, - "exposure": exp, - "gain": gain, - "converged": True - } - - # Max iterations exceeded - return { - "status": "warning_max_iterations", - "final_mean": mean, - "iterations": iteration, - "exposure": exp, - "gain": gain, - "converged": False, - "message": f"Did not converge after {max_iterations} iterations. Final mean: {mean:.1f}" - } - -if __name__ == "__main__": - from aare.common.beamline import mx_beamline - beamline = mx_beamline()