pychemstation 0.10.5__py3-none-any.whl → 0.10.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. pychemstation/analysis/__init__.py +8 -1
  2. pychemstation/control/controllers/__init__.py +2 -2
  3. pychemstation/control/controllers/abc_tables/__init__.py +0 -0
  4. pychemstation/control/controllers/abc_tables/device.py +15 -0
  5. pychemstation/control/controllers/{tables/table.py → abc_tables/run.py} +24 -195
  6. pychemstation/control/controllers/abc_tables/table.py +221 -0
  7. pychemstation/control/controllers/comm.py +3 -99
  8. pychemstation/control/controllers/{tables → data_aq}/method.py +2 -2
  9. pychemstation/control/controllers/{tables → data_aq}/sequence.py +72 -53
  10. pychemstation/control/controllers/devices/__init__.py +3 -0
  11. pychemstation/control/controllers/devices/injector.py +57 -24
  12. pychemstation/control/hplc.py +5 -1
  13. pychemstation/utils/injector_types.py +22 -2
  14. pychemstation/utils/mocking/__init__.py +0 -0
  15. pychemstation/utils/mocking/abc_comm.py +160 -0
  16. pychemstation/utils/mocking/mock_comm.py +5 -0
  17. pychemstation/utils/mocking/mock_hplc.py +2 -0
  18. pychemstation/utils/sequence_types.py +19 -0
  19. pychemstation/utils/table_types.py +6 -0
  20. pychemstation/utils/tray_types.py +36 -1
  21. {pychemstation-0.10.5.dist-info → pychemstation-0.10.6.dist-info}/METADATA +1 -1
  22. pychemstation-0.10.6.dist-info/RECORD +42 -0
  23. pychemstation/control/controllers/devices/device.py +0 -74
  24. pychemstation-0.10.5.dist-info/RECORD +0 -36
  25. /pychemstation/control/controllers/{tables → data_aq}/__init__.py +0 -0
  26. {pychemstation-0.10.5.dist-info → pychemstation-0.10.6.dist-info}/WHEEL +0 -0
  27. {pychemstation-0.10.5.dist-info → pychemstation-0.10.6.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,11 @@
1
1
  from .process_report import CSVProcessor
2
2
  from .process_report import TXTProcessor
3
+ from .chromatogram import AgilentChannelChromatogramData
4
+ from .chromatogram import AgilentHPLCChromatogram
3
5
 
4
- __all__ = ["CSVProcessor", "TXTProcessor"]
6
+ __all__ = [
7
+ "CSVProcessor",
8
+ "TXTProcessor",
9
+ "AgilentChannelChromatogramData",
10
+ "AgilentHPLCChromatogram",
11
+ ]
@@ -3,6 +3,6 @@
3
3
  """
4
4
 
5
5
  from .comm import CommunicationController
6
- from . import tables
6
+ from . import data_aq
7
7
 
8
- __all__ = ["CommunicationController", "tables"]
8
+ __all__ = ["CommunicationController", "data_aq"]
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC
4
+
5
+ from ....control.controllers import CommunicationController
6
+ from ....utils.table_types import Table
7
+ from .table import ABCTableController
8
+
9
+
10
+ class DeviceController(ABCTableController, ABC):
11
+ def __init__(
12
+ self, controller: CommunicationController, table: Table, offline: bool
13
+ ):
14
+ super().__init__(controller=controller, table=table)
15
+ self.offline = offline
@@ -17,6 +17,7 @@ import polling
17
17
  import rainbow as rb
18
18
  from result import Err, Result, Ok
19
19
 
20
+ from .table import ABCTableController
20
21
  from ....analysis.process_report import (
21
22
  AgilentReport,
22
23
  CSVProcessor,
@@ -28,15 +29,15 @@ from pychemstation.analysis.chromatogram import (
28
29
  AgilentChannelChromatogramData,
29
30
  AgilentHPLCChromatogram,
30
31
  )
31
- from ....utils.macro import Command, HPLCRunningStatus, Response
32
+ from ....utils.macro import HPLCRunningStatus
32
33
  from ....utils.method_types import MethodDetails
33
34
  from ....utils.sequence_types import SequenceTable
34
- from ....utils.table_types import RegisterFlag, Table, TableOperation, T
35
+ from ....utils.table_types import Table, T
35
36
 
36
37
  TableType = Union[MethodDetails, SequenceTable]
37
38
 
38
39
 
39
- class TableController(abc.ABC):
40
+ class RunController(ABCTableController, abc.ABC):
40
41
  def __init__(
41
42
  self,
42
43
  controller: Optional[CommunicationController],
@@ -45,8 +46,10 @@ class TableController(abc.ABC):
45
46
  table: Table,
46
47
  offline: bool = False,
47
48
  ):
48
- self.controller = controller
49
- self.table_locator = table
49
+ super().__init__(controller=controller, table=table)
50
+ warnings.warn(
51
+ "This abstract class is not meant to be initialized. Use MethodController or SequenceController."
52
+ )
50
53
  self.table_state: Optional[TableType] = None
51
54
  self.curr_run_starting_time: Optional[float] = None
52
55
  self.timeout: Optional[float] = None
@@ -76,179 +79,27 @@ class TableController(abc.ABC):
76
79
  self.uv: Dict[int, AgilentHPLCChromatogram] = {}
77
80
  self.data_files: List = []
78
81
 
79
- def receive(self) -> Result[Response, str]:
80
- if self.controller:
81
- for _ in range(10):
82
- try:
83
- return self.controller.receive()
84
- except IndexError:
85
- continue
86
- return Err("Could not parse response")
87
- else:
88
- raise ValueError("Controller is offline!")
89
-
90
- def send(self, cmd: Union[Command, str]):
91
- if not self.controller:
92
- raise RuntimeError(
93
- "Communication controller must be initialized before sending command. It is currently in offline mode."
94
- )
95
- self.controller.send(cmd)
96
-
97
- def sleepy_send(self, cmd: Union[Command, str]):
98
- if self.controller:
99
- self.controller.sleepy_send(cmd)
100
- else:
101
- raise ValueError("Controller is offline")
102
-
103
- def sleep(self, seconds: int):
104
- """
105
- Tells the HPLC to wait for a specified number of seconds.
106
-
107
- :param seconds: number of seconds to wait
108
- """
109
- self.send(Command.SLEEP_CMD.value.format(seconds=seconds))
110
-
111
- def get_num(self, row: int, col_name: RegisterFlag) -> Union[int, float]:
112
- if self.controller:
113
- return self.controller.get_num_val(
114
- TableOperation.GET_ROW_VAL.value.format(
115
- register=self.table_locator.register,
116
- table_name=self.table_locator.name,
117
- row=row,
118
- col_name=col_name.value,
119
- )
120
- )
121
- else:
122
- raise ValueError("Controller is offline")
123
-
124
- def get_text(self, row: int, col_name: RegisterFlag) -> str:
125
- if self.controller:
126
- return self.controller.get_text_val(
127
- TableOperation.GET_ROW_TEXT.value.format(
128
- register=self.table_locator.register,
129
- table_name=self.table_locator.name,
130
- row=row,
131
- col_name=col_name.value,
132
- )
133
- )
134
- else:
135
- raise ValueError("Controller is offline")
136
-
137
- def add_new_col_num(self, col_name: RegisterFlag, val: Union[int, float]):
138
- self.sleepy_send(
139
- TableOperation.NEW_COL_VAL.value.format(
140
- register=self.table_locator.register,
141
- table_name=self.table_locator.name,
142
- col_name=col_name,
143
- val=val,
144
- )
145
- )
146
-
147
- def add_new_col_text(self, col_name: RegisterFlag, val: str):
148
- self.sleepy_send(
149
- TableOperation.NEW_COL_TEXT.value.format(
150
- register=self.table_locator.register,
151
- table_name=self.table_locator.name,
152
- col_name=col_name,
153
- val=val,
154
- )
155
- )
156
-
157
- def _edit_row_num(
158
- self, col_name: RegisterFlag, val: Union[int, float], row: Optional[int] = None
159
- ):
160
- self.sleepy_send(
161
- TableOperation.EDIT_ROW_VAL.value.format(
162
- register=self.table_locator.register,
163
- table_name=self.table_locator.name,
164
- row=row if row is not None else "Rows",
165
- col_name=col_name,
166
- val=val,
167
- )
168
- )
169
-
170
- def _edit_row_text(
171
- self, col_name: RegisterFlag, val: str, row: Optional[int] = None
172
- ):
173
- self.sleepy_send(
174
- TableOperation.EDIT_ROW_TEXT.value.format(
175
- register=self.table_locator.register,
176
- table_name=self.table_locator.name,
177
- row=row if row is not None else "Rows",
178
- col_name=col_name,
179
- val=val,
180
- )
181
- )
182
-
183
82
  @abc.abstractmethod
184
- def get_row(self, row: int):
83
+ def fuzzy_match_most_recent_folder(self, most_recent_folder: T) -> Result[T, str]:
185
84
  pass
186
85
 
187
- def delete_row(self, row: int):
188
- self.sleepy_send(
189
- TableOperation.DELETE_ROW.value.format(
190
- register=self.table_locator.register,
191
- table_name=self.table_locator.name,
192
- row=row,
193
- )
194
- )
195
-
196
- def add_row(self):
197
- """
198
- Adds a row to the provided table for currently loaded method or sequence.
199
- """
200
- self.sleepy_send(
201
- TableOperation.NEW_ROW.value.format(
202
- register=self.table_locator.register, table_name=self.table_locator.name
203
- )
204
- )
205
-
206
- def delete_table(self):
207
- """
208
- Deletes the table for the current loaded method or sequence.
209
- """
210
- self.sleepy_send(
211
- TableOperation.DELETE_TABLE.value.format(
212
- register=self.table_locator.register, table_name=self.table_locator.name
213
- )
214
- )
215
-
216
- def new_table(self):
217
- """
218
- Creates the table for the currently loaded method or sequence.
219
- """
220
- self.send(
221
- TableOperation.CREATE_TABLE.value.format(
222
- register=self.table_locator.register, table_name=self.table_locator.name
223
- )
224
- )
86
+ @abc.abstractmethod
87
+ def get_data(
88
+ self, custom_path: Optional[str] = None
89
+ ) -> Union[List[AgilentChannelChromatogramData], AgilentChannelChromatogramData]:
90
+ pass
225
91
 
226
- def get_num_rows(self) -> Result[Response, str]:
227
- self.send(
228
- TableOperation.GET_NUM_ROWS.value.format(
229
- register=self.table_locator.register,
230
- table_name=self.table_locator.name,
231
- col_name=RegisterFlag.NUM_ROWS,
232
- )
233
- )
234
- self.send(
235
- Command.GET_ROWS_CMD.value.format(
236
- register=self.table_locator.register,
237
- table_name=self.table_locator.name,
238
- col_name=RegisterFlag.NUM_ROWS,
239
- )
240
- )
241
- if self.controller:
242
- res = self.controller.receive()
243
- else:
244
- raise ValueError("Controller is offline")
92
+ @abc.abstractmethod
93
+ def get_data_uv(
94
+ self, custom_path: str | None = None
95
+ ) -> Dict[int, AgilentHPLCChromatogram]:
96
+ pass
245
97
 
246
- if res.is_ok():
247
- self.send("Sleep 0.1")
248
- self.send("Print Rows")
249
- return res
250
- else:
251
- return Err("No rows could be read.")
98
+ @abc.abstractmethod
99
+ def get_report(
100
+ self, custom_path: str, report_type: ReportType = ReportType.TXT
101
+ ) -> List[AgilentReport]:
102
+ pass
252
103
 
253
104
  def check_hplc_is_running(self) -> bool:
254
105
  if self.controller:
@@ -334,28 +185,6 @@ class TableController(abc.ABC):
334
185
  return self.data_files[-1]
335
186
  return Err("Run did not complete as expected")
336
187
 
337
- @abc.abstractmethod
338
- def fuzzy_match_most_recent_folder(self, most_recent_folder: T) -> Result[T, str]:
339
- pass
340
-
341
- @abc.abstractmethod
342
- def get_data(
343
- self, custom_path: Optional[str] = None
344
- ) -> Union[List[AgilentChannelChromatogramData], AgilentChannelChromatogramData]:
345
- pass
346
-
347
- @abc.abstractmethod
348
- def get_data_uv(
349
- self, custom_path: str | None = None
350
- ) -> Dict[int, AgilentHPLCChromatogram]:
351
- pass
352
-
353
- @abc.abstractmethod
354
- def get_report(
355
- self, custom_path: str, report_type: ReportType = ReportType.TXT
356
- ) -> List[AgilentReport]:
357
- pass
358
-
359
188
  def get_uv_spectrum(self, path: str):
360
189
  data_uv = rb.agilent.chemstation.parse_file(os.path.join(path, "DAD1.UV"))
361
190
  times = data_uv.xlabels
@@ -0,0 +1,221 @@
1
+ """
2
+ Abstract module containing shared logic for Method and Sequence tables.
3
+
4
+ Authors: Lucy Hao
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import abc
10
+ import warnings
11
+ from typing import Optional, Union
12
+
13
+ from result import Err, Result
14
+
15
+ from ....control.controllers.comm import CommunicationController
16
+ from ....utils.macro import Command, Response
17
+ from ....utils.method_types import MethodDetails
18
+ from ....utils.sequence_types import SequenceTable
19
+ from ....utils.table_types import RegisterFlag, Table, TableOperation
20
+
21
+ TableType = Union[MethodDetails, SequenceTable]
22
+
23
+
24
+ class ABCTableController(abc.ABC):
25
+ def __init__(
26
+ self,
27
+ controller: Optional[CommunicationController],
28
+ table: Table,
29
+ ):
30
+ warnings.warn(
31
+ "This abstract class is not meant to be initialized. Use MethodController or SequenceController."
32
+ )
33
+ self.controller = controller
34
+ self.table_locator = table
35
+ self.table_state: Optional[TableType] = None
36
+
37
+ def receive(self) -> Result[Response, str]:
38
+ if self.controller:
39
+ for _ in range(10):
40
+ try:
41
+ return self.controller.receive()
42
+ except IndexError:
43
+ continue
44
+ return Err("Could not parse response")
45
+ else:
46
+ raise ValueError("Controller is offline!")
47
+
48
+ def send(self, cmd: Union[Command, str]):
49
+ if not self.controller:
50
+ raise RuntimeError(
51
+ "Communication controller must be initialized before sending command. It is currently in offline mode."
52
+ )
53
+ self.controller.send(cmd)
54
+
55
+ def sleepy_send(self, cmd: Union[Command, str]):
56
+ if self.controller:
57
+ self.controller.sleepy_send(cmd)
58
+ else:
59
+ raise ValueError("Controller is offline")
60
+
61
+ def sleep(self, seconds: int):
62
+ """
63
+ Tells the HPLC to wait for a specified number of seconds.
64
+
65
+ :param seconds: number of seconds to wait
66
+ """
67
+ self.send(Command.SLEEP_CMD.value.format(seconds=seconds))
68
+
69
+ def get_num(self, row: int, col_name: RegisterFlag) -> Union[int, float]:
70
+ if self.controller:
71
+ return self.controller.get_num_val(
72
+ TableOperation.GET_ROW_VAL.value.format(
73
+ register=self.table_locator.register,
74
+ table_name=self.table_locator.name,
75
+ row=row,
76
+ col_name=col_name.value,
77
+ )
78
+ )
79
+ else:
80
+ raise ValueError("Controller is offline")
81
+
82
+ def get_text(self, row: int, col_name: RegisterFlag) -> str:
83
+ if self.controller:
84
+ return self.controller.get_text_val(
85
+ TableOperation.GET_ROW_TEXT.value.format(
86
+ register=self.table_locator.register,
87
+ table_name=self.table_locator.name,
88
+ row=row,
89
+ col_name=col_name.value,
90
+ )
91
+ )
92
+ else:
93
+ raise ValueError("Controller is offline")
94
+
95
+ def add_new_col_num(self, col_name: RegisterFlag, val: Union[int, float]):
96
+ self.sleepy_send(
97
+ TableOperation.NEW_COL_VAL.value.format(
98
+ register=self.table_locator.register,
99
+ table_name=self.table_locator.name,
100
+ col_name=col_name,
101
+ val=val,
102
+ )
103
+ )
104
+
105
+ def add_new_col_text(self, col_name: RegisterFlag, val: str):
106
+ self.sleepy_send(
107
+ TableOperation.NEW_COL_TEXT.value.format(
108
+ register=self.table_locator.register,
109
+ table_name=self.table_locator.name,
110
+ col_name=col_name,
111
+ val=val,
112
+ )
113
+ )
114
+
115
+ def _edit_row_num(
116
+ self, col_name: RegisterFlag, val: Union[int, float], row: Optional[int] = None
117
+ ):
118
+ if row:
119
+ num_rows = self.get_num_rows()
120
+ if num_rows.is_ok():
121
+ if num_rows.value.num_response < row:
122
+ raise ValueError("Not enough rows to edit!")
123
+
124
+ self.sleepy_send(
125
+ TableOperation.EDIT_ROW_VAL.value.format(
126
+ register=self.table_locator.register,
127
+ table_name=self.table_locator.name,
128
+ row=row if row is not None else "Rows",
129
+ col_name=col_name,
130
+ val=val,
131
+ )
132
+ )
133
+
134
+ def _edit_row_text(
135
+ self, col_name: RegisterFlag, val: str, row: Optional[int] = None
136
+ ):
137
+ if row:
138
+ num_rows = self.get_num_rows()
139
+ if num_rows.is_ok():
140
+ if num_rows.value.num_response < row:
141
+ raise ValueError("Not enough rows to edit!")
142
+
143
+ self.sleepy_send(
144
+ TableOperation.EDIT_ROW_TEXT.value.format(
145
+ register=self.table_locator.register,
146
+ table_name=self.table_locator.name,
147
+ row=row if row is not None else "Rows",
148
+ col_name=col_name,
149
+ val=val,
150
+ )
151
+ )
152
+
153
+ @abc.abstractmethod
154
+ def get_row(self, row: int):
155
+ pass
156
+
157
+ def delete_row(self, row: int):
158
+ self.sleepy_send(
159
+ TableOperation.DELETE_ROW.value.format(
160
+ register=self.table_locator.register,
161
+ table_name=self.table_locator.name,
162
+ row=row,
163
+ )
164
+ )
165
+
166
+ def add_row(self):
167
+ """
168
+ Adds a row to the provided table for currently loaded method or sequence.
169
+ """
170
+ self.sleepy_send(
171
+ TableOperation.NEW_ROW.value.format(
172
+ register=self.table_locator.register, table_name=self.table_locator.name
173
+ )
174
+ )
175
+
176
+ def delete_table(self):
177
+ """
178
+ Deletes the table for the current loaded method or sequence.
179
+ """
180
+ self.sleepy_send(
181
+ TableOperation.DELETE_TABLE.value.format(
182
+ register=self.table_locator.register, table_name=self.table_locator.name
183
+ )
184
+ )
185
+
186
+ def new_table(self):
187
+ """
188
+ Creates the table for the currently loaded method or sequence.
189
+ """
190
+ self.send(
191
+ TableOperation.CREATE_TABLE.value.format(
192
+ register=self.table_locator.register, table_name=self.table_locator.name
193
+ )
194
+ )
195
+
196
+ def get_num_rows(self) -> Result[Response, str]:
197
+ self.send(
198
+ TableOperation.GET_NUM_ROWS.value.format(
199
+ register=self.table_locator.register,
200
+ table_name=self.table_locator.name,
201
+ col_name=RegisterFlag.NUM_ROWS,
202
+ )
203
+ )
204
+ self.send(
205
+ Command.GET_ROWS_CMD.value.format(
206
+ register=self.table_locator.register,
207
+ table_name=self.table_locator.name,
208
+ col_name=RegisterFlag.NUM_ROWS,
209
+ )
210
+ )
211
+ if self.controller:
212
+ res = self.controller.receive()
213
+ else:
214
+ raise ValueError("Controller is offline")
215
+
216
+ if res.is_ok():
217
+ self.send("Sleep 0.1")
218
+ self.send("Print Rows")
219
+ return res
220
+ else:
221
+ return Err("No rows could be read.")
@@ -10,7 +10,6 @@ been processed.
10
10
  Authors: Alexander Hammer, Hessam Mehr, Lucy Hao
11
11
  """
12
12
 
13
- import os
14
13
  import time
15
14
  from typing import Optional, Union
16
15
 
@@ -18,22 +17,18 @@ from result import Err, Ok, Result
18
17
 
19
18
  from ...utils.macro import (
20
19
  str_to_status,
21
- HPLCAvailStatus,
22
20
  HPLCErrorStatus,
23
21
  Command,
24
22
  Status,
25
- Response,
26
23
  )
24
+ from ...utils.mocking.abc_comm import ABCCommunicationController
27
25
 
28
26
 
29
- class CommunicationController:
27
+ class CommunicationController(ABCCommunicationController):
30
28
  """
31
29
  Class that communicates with Agilent using Macros
32
30
  """
33
31
 
34
- # maximum command number
35
- MAX_CMD_NO = 255
36
-
37
32
  def __init__(
38
33
  self,
39
34
  comm_dir: str,
@@ -48,24 +43,7 @@ class CommunicationController:
48
43
  :param reply_file: Name of reply file
49
44
  :param debug: whether to save log of sent commands
50
45
  """
51
- if not offline:
52
- self.debug = debug
53
- if os.path.isdir(comm_dir):
54
- self.cmd_file = os.path.join(comm_dir, cmd_file)
55
- self.reply_file = os.path.join(comm_dir, reply_file)
56
- self.cmd_no = 0
57
- else:
58
- raise FileNotFoundError(f"comm_dir: {comm_dir} not found.")
59
-
60
- # Create files for Chemstation to communicate with Python
61
- open(self.cmd_file, "a").close()
62
- open(self.reply_file, "a").close()
63
-
64
- self.reset_cmd_counter()
65
-
66
- # Initialize row counter for table operations
67
- self._most_recent_hplc_status: Status = self.get_status()
68
- self.send("Local Rows")
46
+ super().__init__(comm_dir, cmd_file, reply_file, offline, debug)
69
47
 
70
48
  def get_num_val(self, cmd: str) -> Union[int, float]:
71
49
  tries = 10
@@ -108,21 +86,6 @@ class CommunicationController:
108
86
  except IndexError:
109
87
  return HPLCErrorStatus.MALFORMED
110
88
 
111
- def set_status(self):
112
- """Updates current status of HPLC machine"""
113
- self._most_recent_hplc_status = self.get_status()
114
-
115
- def check_if_not_running(self) -> bool:
116
- """Checks if HPLC machine is in an available state, meaning a state that data is not being written.
117
-
118
- :return: whether the HPLC machine is in a safe state to retrieve data back."""
119
- self.set_status()
120
- hplc_avail = isinstance(self._most_recent_hplc_status, HPLCAvailStatus)
121
- time.sleep(5)
122
- self.set_status()
123
- hplc_actually_avail = isinstance(self._most_recent_hplc_status, HPLCAvailStatus)
124
- return hplc_avail and hplc_actually_avail
125
-
126
89
  def _send(self, cmd: str, cmd_no: int, num_attempts=5) -> None:
127
90
  """Low-level execution primitive. Sends a command string to HPLC.
128
91
 
@@ -185,62 +148,3 @@ class CommunicationController:
185
148
  return Err(
186
149
  f"Failed to receive reply to command #{cmd_no} due to {err} caused by {err_msg}."
187
150
  )
188
-
189
- def sleepy_send(self, cmd: Union[Command, str]):
190
- self.send("Sleep 0.1")
191
- self.send(cmd)
192
- self.send("Sleep 0.1")
193
-
194
- def send(self, cmd: Union[Command, str]):
195
- """Sends a command to Chemstation.
196
-
197
- :param cmd: Command to be sent to HPLC
198
- """
199
- if self.cmd_no == self.MAX_CMD_NO:
200
- self.reset_cmd_counter()
201
-
202
- cmd_to_send: str = cmd.value if isinstance(cmd, Command) else cmd
203
- self.cmd_no += 1
204
- self._send(cmd_to_send, self.cmd_no)
205
- if self.debug:
206
- f = open("out.txt", "a")
207
- f.write(cmd_to_send + "\n")
208
- f.close()
209
-
210
- def receive(self) -> Result[Response, str]:
211
- """Returns messages received in reply file.
212
-
213
- :return: ChemStation response
214
- """
215
- num_response_prefix = "Numerical Responses:"
216
- str_response_prefix = "String Responses:"
217
- possible_response = self._receive(self.cmd_no)
218
- if possible_response.is_ok():
219
- lines = possible_response.ok_value.splitlines()
220
- for line in lines:
221
- if str_response_prefix in line and num_response_prefix in line:
222
- string_responses_dirty, _, numerical_responses = line.partition(
223
- num_response_prefix
224
- )
225
- _, _, string_responses = string_responses_dirty.partition(
226
- str_response_prefix
227
- )
228
- return Ok(
229
- Response(
230
- string_response=string_responses.strip(),
231
- num_response=float(numerical_responses.strip()),
232
- )
233
- )
234
- return Err("Could not retrieve HPLC response")
235
- else:
236
- return Err(f"Could not establish response to HPLC: {possible_response}")
237
-
238
- def reset_cmd_counter(self):
239
- """Resets the command counter."""
240
- self._send(Command.RESET_COUNTER_CMD.value, cmd_no=self.MAX_CMD_NO + 1)
241
- self._receive(cmd_no=self.MAX_CMD_NO + 1)
242
- self.cmd_no = 0
243
-
244
- def stop_macro(self):
245
- """Stops Macro execution. Connection will be lost."""
246
- self.send(Command.STOP_MACRO_CMD)
@@ -7,6 +7,7 @@ from typing import List, Optional, Union, Dict
7
7
 
8
8
  from result import Err, Ok, Result
9
9
 
10
+ from ..abc_tables.run import RunController
10
11
  from ....analysis.process_report import AgilentReport, ReportType
11
12
  from ....control.controllers import CommunicationController
12
13
  from pychemstation.analysis.chromatogram import (
@@ -24,10 +25,9 @@ from ....utils.method_types import (
24
25
  )
25
26
  from ....utils.table_types import RegisterFlag, Table, TableOperation, T
26
27
  from ..devices.injector import InjectorController
27
- from .table import TableController
28
28
 
29
29
 
30
- class MethodController(TableController):
30
+ class MethodController(RunController):
31
31
  """
32
32
  Class containing method related logic
33
33
  """