Skip to content

Commit 3dad907

Browse files
xbtu2rickwierenga
andauthored
added atc support for proflex backend (#702)
Co-authored-by: Rick Wierenga <rick_wierenga@icloud.com>
1 parent 972bb86 commit 3dad907

File tree

6 files changed

+47
-31
lines changed

6 files changed

+47
-31
lines changed
Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
1-
"""This module contains the thermocycling related classes and functions."""
2-
31
from .backend import ThermocyclerBackend
42
from .chatterbox import ThermocyclerChatterboxBackend
53
from .opentrons import OpentronsThermocyclerModuleV1, OpentronsThermocyclerModuleV2
64
from .opentrons_backend import OpentronsThermocyclerBackend
7-
from .proflex import ProflexBackend
85
from .standard import Step
6+
from .thermo_fisher import *
97
from .thermocycler import Thermocycler
10-
11-
__all__ = [
12-
"ThermocyclerBackend",
13-
"ThermocyclerChatterboxBackend",
14-
"Thermocycler",
15-
"ProflexBackend",
16-
"Step",
17-
"OpentronsThermocyclerBackend",
18-
"OpentronsThermocyclerModuleV1",
19-
"OpentronsThermocyclerModuleV2",
20-
]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .atc import ATCBackend
2+
from .proflex import ProflexBackend
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from pylabrobot.thermocycling.thermo_fisher.thermo_fisher_thermocycler import (
2+
ThermoFisherThermocyclerBackend,
3+
)
4+
5+
6+
class ATCBackend(ThermoFisherThermocyclerBackend):
7+
async def close_lid(self):
8+
if self.bid != "31":
9+
raise NotImplementedError("Lid control is only available for BID 31 (ATC)")
10+
res = await self.send_command({"cmd": "lidclose"}, response_timeout=20, read_once=False)
11+
if self._parse_scpi_response(res)["status"] != "OK":
12+
raise ValueError("Failed to close lid")
13+
14+
async def open_lid(self):
15+
if self.bid != "31":
16+
raise NotImplementedError("Lid control is only available for BID 31 (ATC)")
17+
res = await self.send_command({"cmd": "lidopen"}, response_timeout=20, read_once=False)
18+
if self._parse_scpi_response(res)["status"] != "OK":
19+
raise ValueError("Failed to open lid")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from pylabrobot.thermocycling.thermo_fisher.thermo_fisher_thermocycler import (
2+
ThermoFisherThermocyclerBackend,
3+
)
4+
5+
6+
class ProflexBackend(ThermoFisherThermocyclerBackend):
7+
async def open_lid(self):
8+
raise NotImplementedError("Open lid command is not implemented for Proflex thermocycler")
9+
10+
async def close_lid(self):
11+
raise NotImplementedError("Close lid command is not implemented for Proflex thermocycler")

pylabrobot/thermocycling/proflex_tests.py renamed to pylabrobot/thermocycling/thermo_fisher/proflex_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import unittest
33
import unittest.mock
44

5-
from pylabrobot.thermocycling.proflex import ProflexBackend
65
from pylabrobot.thermocycling.standard import Protocol, Stage, Step
6+
from pylabrobot.thermocycling.thermo_fisher.proflex import ProflexBackend
77

88

99
class TestProflexBackend(unittest.IsolatedAsyncioTestCase):
@@ -168,7 +168,7 @@ async def test_run_protocol(self):
168168
-cover= 105
169169
-mode= Fast
170170
-coverEnabled= On
171-
-notes=
171+
-notes=\x20
172172
</multiline.write>
173173
"""
174174
).strip()

pylabrobot/thermocycling/proflex.py renamed to pylabrobot/thermocycling/thermo_fisher/thermo_fisher_thermocycler.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
import logging
55
import re
66
import xml.etree.ElementTree as ET
7+
from abc import ABCMeta
78
from base64 import b64decode
89
from dataclasses import dataclass
910
from typing import Any, Dict, List, Optional, cast
1011
from xml.dom import minidom
1112

1213
from pylabrobot.io import Socket
14+
from pylabrobot.thermocycling.backend import ThermocyclerBackend
1315
from pylabrobot.thermocycling.standard import LidStatus, Protocol, Stage, Step
1416

15-
from .backend import ThermocyclerBackend
16-
1717

1818
def _generate_run_info_files(
1919
protocol: Protocol,
@@ -203,7 +203,7 @@ def stage_to_scpi(stage: Stage, stage_index: int, stage_name_prefix: str) -> dic
203203
return data
204204

205205

206-
class ProflexBackend(ThermocyclerBackend):
206+
class ThermoFisherThermocyclerBackend(ThermocyclerBackend, metaclass=ABCMeta):
207207
"""Backend for Proflex thermocycler."""
208208

209209
def __init__(self, ip: str, port: int = 7000, shared_secret: bytes = b"f4ct0rymt55"):
@@ -401,8 +401,11 @@ async def _load_num_blocks_and_type(self):
401401
elif self.bid == "13":
402402
self._num_blocks = 3
403403
self.num_temp_zones = 2
404+
elif self.bid == "31":
405+
self._num_blocks = 1
406+
self.num_temp_zones = 1
404407
else:
405-
raise NotImplementedError("Only BID 12 and 13 are supported")
408+
raise NotImplementedError("Only BID 31, 12 and 13 are supported")
406409

407410
async def is_block_running(self, block_id: int) -> bool:
408411
run_name = await self.get_run_name(block_id=block_id)
@@ -778,7 +781,7 @@ async def get_run_info(self, protocol: Protocol, block_id: int) -> "RunProgress"
778781
run_name = await self.get_run_name(block_id=block_id)
779782
if not progress:
780783
self.logger.info("Protocol completed")
781-
return ProflexBackend.RunProgress(
784+
return ThermoFisherThermocyclerBackend.RunProgress(
782785
running=False,
783786
stage="completed",
784787
elapsed_time=await self.get_elapsed_run_time_from_log(run_name=run_name),
@@ -788,7 +791,7 @@ async def get_run_info(self, protocol: Protocol, block_id: int) -> "RunProgress"
788791
if progress["RunTitle"] == "-":
789792
await self._read_response(timeout=5)
790793
self.logger.info("Protocol completed")
791-
return ProflexBackend.RunProgress(
794+
return ThermoFisherThermocyclerBackend.RunProgress(
792795
running=False,
793796
stage="completed",
794797
elapsed_time=await self.get_elapsed_run_time_from_log(run_name=run_name),
@@ -797,7 +800,7 @@ async def get_run_info(self, protocol: Protocol, block_id: int) -> "RunProgress"
797800

798801
if progress["Stage"] == "POSTRun":
799802
self.logger.info("Protocol in POSTRun")
800-
return ProflexBackend.RunProgress(
803+
return ThermoFisherThermocyclerBackend.RunProgress(
801804
running=True,
802805
stage="POSTRun",
803806
elapsed_time=await self.get_elapsed_run_time_from_log(run_name=run_name),
@@ -820,7 +823,7 @@ async def get_run_info(self, protocol: Protocol, block_id: int) -> "RunProgress"
820823
break
821824
await asyncio.sleep(5)
822825
self.logger.info("Infinite hold")
823-
return ProflexBackend.RunProgress(
826+
return ThermoFisherThermocyclerBackend.RunProgress(
824827
running=False,
825828
stage="infinite_hold",
826829
elapsed_time=time_elapsed,
@@ -829,7 +832,7 @@ async def get_run_info(self, protocol: Protocol, block_id: int) -> "RunProgress"
829832

830833
self.logger.info(f"Elapsed time: {time_elapsed}")
831834
self.logger.info(f"Remaining time: {remaining_time}")
832-
return ProflexBackend.RunProgress(
835+
return ThermoFisherThermocyclerBackend.RunProgress(
833836
running=True,
834837
stage=progress["Stage"],
835838
elapsed_time=time_elapsed,
@@ -852,12 +855,6 @@ async def setup(
852855
await self.set_block_idle_temp(temp=block_idle_temp, block_id=block_index)
853856
await self.set_cover_idle_temp(temp=cover_idle_temp, block_id=block_index)
854857

855-
async def open_lid(self):
856-
raise NotImplementedError("Open lid command is not implemented for Proflex thermocycler")
857-
858-
async def close_lid(self):
859-
raise NotImplementedError("Close lid command is not implemented for Proflex thermocycler")
860-
861858
async def deactivate_lid(self, block_id: Optional[int] = None):
862859
assert block_id is not None, "block_id must be specified"
863860
return await self.set_cover_idle_temp(temp=105, control_enabled=False, block_id=block_id)

0 commit comments

Comments
 (0)