Skip to content

Conversation

@Nat-is-coding
Copy link
Contributor

Here is the working backend for the Synergy H1 readers. A work in progress as I was able to verify absorbance reading so far : )

Modified:
__init__.py
backend
biotek_tests.py

Added:
agilent_biotek_backend.py
agilent_biotek_cytation_backend.py
agilent_biotek_synergyh1_backend.py

Removed:
biotek_backend.py

(ruff reformatted the rest)
@Nat-is-coding
Copy link
Contributor Author

Nat-is-coding commented Nov 25, 2025

Here is my proposal for a BioTekPlateReaderBackend for both CytationBackend and SynergyH1Backend

Modified the following files:

  • init.py
  • backend.py
  • biotek_test.py

Added the following files:

  • agilent_biotek_backend.py
  • agilent_biotek_cytation_backend.py
  • agilent_biotek_synergyh1_backend.py

Deleted the following files:

  • biotek_backend.py (replaced by the three files above)

This proposal may not be perfect at first, as I rearranged the code and added some abstract properties in the BioTekPlateReaderBackend. Please feel free to suggest or modify some things, especially CytationBackend, as I do not have one to test it out.

I tested the SynergyH1Backend and all the functions work. Once the coding is finalized, I can work on updating the documentation for the wiki page.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces support for the Agilent BioTek Synergy H1 plate reader by refactoring the existing Cytation5Backend into a more modular architecture. The refactoring extracts common BioTek plate reader functionality into a new base class BioTekPlateReaderBackend, renames Cytation5Backend to CytationBackend (with backward-compatible deprecation wrappers), and adds the new SynergyH1Backend that inherits from the base class with H1-specific customizations.

Key changes:

  • Created BioTekPlateReaderBackend base class containing shared functionality for all BioTek plate readers (FTDI communication, plate management, absorbance/luminescence/fluorescence reading)
  • Renamed Cytation5Backend to CytationBackend with deprecation warnings for backward compatibility
  • Added SynergyH1Backend with H1-specific features (heating support, custom focal height range, improved read buffer handling with FtdiError retry logic)

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
agilent_biotek_backend.py New base class containing shared BioTek plate reader functionality (594 lines of refactored code from Cytation backend)
agilent_biotek_cytation_backend.py Refactored Cytation backend to inherit from base class, removing duplicate code and adding deprecation wrappers for old class names
agilent_biotek_synergyh1_backend.py New backend for Synergy H1 readers with custom _read_until implementation for chunk-based reading and FtdiError handling
__init__.py Updated exports to include new backends and base class, but missing backward-compatible exports
biotek_tests.py Updated test import to use new CytationBackend name
molecular_devices_backend.py, imager.py, clario_star_backend.py, chatterbox.py Minor code formatting improvements (spacing around operators)
Comments suppressed due to low confidence (4)

pylabrobot/plate_reading/agilent_biotek_cytation_backend.py:148

  • The stop() method is calling super().stop() first, but then also calls self.stop_shaking() and self.io.stop(), which are already called in the parent class's stop() method (lines 590-592 of agilent_biotek_backend.py). This results in duplicate calls to these methods. Consider removing the duplicate calls here to avoid potential issues:
async def stop(self):
    await super().stop()
    
    if self._acquiring:
        self.stop_acquisition()
    
    self._stop_camera()
    
    self._objectives = None
    self._filters = None
    # _slow_mode is already reset in parent class
    
    self._exposure = None
    # ... rest of the resets

pylabrobot/plate_reading/agilent_biotek_cytation_backend.py:139

  • The setup() method duplicates all the code from the parent class's setup() method instead of calling super().setup(). This creates maintainability issues and violates DRY (Don't Repeat Yourself). Consider refactoring to:
async def setup(self, use_cam: bool = False) -> None:
    await super().setup()
    
    if use_cam:
        try:
            await self._set_up_camera()
        except:
            await self.stop()
            raise

pylabrobot/plate_reading/agilent_biotek_cytation_backend.py:944

  • Trailing space in the deprecation warning message
    pylabrobot/plate_reading/agilent_biotek_cytation_backend.py:953
  • Trailing space in the deprecation warning message

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

rickwierenga and others added 4 commits December 1, 2025 19:12
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@rickwierenga rickwierenga merged commit 4663d6b into PyLabRobot:main Dec 2, 2025
9 checks passed
@rickwierenga
Copy link
Member

thank you so much!

@Nat-is-coding
Copy link
Contributor Author

Of course! And thank you for the review : )

When I'm back in the lab, I'll double check the SynergyH1 Backend and add in the documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants