Skip to content

Conversation

@hazlamshamin
Copy link
Contributor

@hazlamshamin hazlamshamin commented Dec 20, 2025

  • Add Tecan Infinite 200 PRO backend + tests.
  • Supports absorbance and fluorescence, including masking to read specified list of wells, up to 384-well plate.
  • Luminescence is experimental due to lack of glowing sample for testing.
  • Make USB capture decoding resilient to malformed escape sequences.

EDIT: all three modes now reflect what OEM does with 100% accuracy, and luminescence is no longer experimental ([e92c6db])

Tests: make lint, make format-check, make typecheck, make test.

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 a backend for the Tecan Infinite 200 PRO plate reader (M Plex series), adding support for absorbance and fluorescence measurements with experimental luminescence support. The implementation includes configurable well masking for reading specific wells on plates up to 384-well format.

Key changes:

  • New TecanInfinite200ProBackend class with USB communication and measurement decoding
  • Specialized decoders for absorbance, fluorescence, and luminescence measurement streams
  • Enhanced USB capture error handling to gracefully manage malformed escape sequences

Reviewed changes

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

File Description
pylabrobot/plate_reading/tecan_infinite_backend.py Implements the complete backend with transport layer, measurement decoders, and plate reading methods for all three modes
pylabrobot/plate_reading/tecan_infinite_backend_tests.py Comprehensive unit tests for decoders, scan geometry, and ASCII frame handling
pylabrobot/plate_reading/init.py Exports the new backend and configuration class for public API access
pylabrobot/io/usb.py Adds error handling to decode operations to prevent crashes from malformed USB data

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

if end == -1:
return False, None
text = buffer[1:end].decode("ascii", "ignore")
del buffer[: end + 2]
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

This deletion assumes the buffer has at least end + 2 bytes, but only checks for bytes up to end. If the buffer ends exactly at ETX (index end), accessing end + 1 would be valid, but end + 2 could exceed buffer length. Add a length check before deletion.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

i have pushed a new commit for extra guard for this after checking the hexdumps. additionally, there has already been guard for absorbance and fluorescence which checked that the consumed

i pushed a new commit (ca73508) for extra guard for this after checking the hexdumps. found cases where ETX arrives at end‑of‑packet (though this does not appear to change the measurement data). nonetheless the extra guard avoids consuming partial frames. also note in current code, we already validate measurement frames: ABS checks wavelength (words[1]), FI checks excitation/emission (words[1]/[2]). only LUM has no wavelength field to match.

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