Skip to content

Focus Lock Controller Calibration Improvements #166

@beniroquai

Description

@beniroquai

The FocusLockController contains several TODO items related to focus calibration functionality that need to be addressed to improve the calibration accuracy and integration with the PID controller.

Current Issues and TODOs

1. Calibration Scanning Logic

Location: FocusCalibThread.run() line ~1116
Issue: Current calibration always scans from fixed from_position to to_position
TODO: "We should probably scan around the current position instead of always from->to"

Description: The current implementation uses fixed absolute positions for calibration scanning, which may not be optimal. It should scan around the current Z position to better characterize the local focus response.

2. Frame Acquisition During Calibration

Location: FocusCalibThread.run() line ~1134
Issue: Calibration relies on cached focus signal value
TODO: "maybe explicitly grab a new frame here and compute the signal?"

Description: Currently the calibration uses self._controller.setPointSignal which may be stale. Fresh frame acquisition and focus computation would provide more accurate calibration data.

3. Lookup Table and Focus-to-Distance Conversion

Location: FocusCalibThread.run() line ~1149
Issue: Missing comprehensive calibration data structure
TODO: "We need to compute and store a look up table and also compute the slope for the linear part of the curve so that we can convert focus value changes to nm changes"

Description: The current implementation only fits a linear polynomial but doesn't create a proper lookup table or provide robust focus-to-distance conversion capabilities.

4. Headless Mode Signal Support

Location: FocusCalibThread.show() lines ~1179-1180
Issue: No signal support for headless operation
TODOs:

  • "We should send a signal to the frontend to update the calibration display"
  • "implement a signal for headless mode that holds all parameters and the scan/calibration curve"

Description: Headless mode lacks proper signaling for calibration results and progress updates.

5. Calibration Data Integration with PID Controller

Location: FocusCalibThread.getData() line ~1193
Issue: Calibration data is not used by the PID controller
TODO: "we need to use this calibration data in the upstream controller to convert focus value changes to nm changes"

Description: The most critical issue - calibration data is computed but never integrated into the PID controller for improved focus lock accuracy.

Proposed Solutions

1. Dynamic Calibration Range

# Instead of fixed from_position/to_position
current_z = self._controller.stage.getPosition()["Z"]
scan_range = calib_params.scan_range_um  # e.g., ±10µm
from_val = current_z - scan_range/2
to_val = current_z + scan_range/2

2. Real-time Frame Acquisition

# Force fresh frame acquisition during calibration
self._controller._master.detectorsManager[self._controller.camera].getLatestFrame()
# Recompute focus signal with fresh frame
focus_signal = self._controller.__processDataThread.update(fresh_cropped_frame, self._controller.twoFociVar)

3. Enhanced Calibration Data Structure

@dataclass
class CalibrationData:
    position_data: List[float]
    focus_data: List[float]
    polynomial_coeffs: np.ndarray
    lookup_table: Dict[float, float]  # focus_value -> z_position
    sensitivity_nm_per_unit: float
    r_squared: float
    linear_range: Tuple[float, float]  # valid focus range for linear approximation
    timestamp: float

4. PID Controller Integration

The PID controller should use calibration data to:

  • Convert focus value errors to physical distance errors (nm)
  • Apply calibration-based scaling instead of fixed scale_um_per_unit
  • Validate that focus values are within calibrated range

5. Enhanced Signal System

# New signal for calibration completion
sigCalibrationCompleted = Signal(object)  # CalibrationData

# Enhanced progress signal with curve data
sigCalibrationProgress = Signal(object)  # progress + partial curve data

Implementation Priority

  1. HIGH: Integrate calibration data with PID controller (Including DLL path in Windows build-process fails #5)
  2. HIGH: Implement real-time frame acquisition during calibration (Add firmware uploader  #2)
  3. MEDIUM: Enhanced calibration data structure and lookup table (Automatically install CP21X drivers in Bundle? #3)
  4. MEDIUM: Dynamic calibration range around current position (AttributeError: 'MCTInfo' object has no attribute 'pixelSize' #1)
  5. LOW: Headless mode signal improvements (Ensuring automated updating of Windows application  #4)

Expected Benefits

  • Improved Focus Lock Accuracy: Calibration-based scaling will provide more accurate distance control
  • Robust Calibration: Fresh frame acquisition ensures accurate calibration data
  • Better User Experience: Dynamic calibration range and enhanced progress feedback
  • API Stability: Proper headless mode support for programmatic control

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions