pychemstation 0.10.11__py3-none-any.whl → 0.10.12__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.
- pychemstation/control/controllers/comm.py +1 -1
- pychemstation/control/controllers/data_aq/method.py +112 -136
- pychemstation/control/controllers/data_aq/sequence.py +49 -24
- pychemstation/control/controllers/devices/column.py +61 -0
- pychemstation/control/controllers/devices/dad.py +85 -0
- pychemstation/control/controllers/devices/injector.py +18 -0
- pychemstation/control/controllers/devices/pump.py +131 -0
- pychemstation/control/controllers/devices/sample_info.py +27 -0
- pychemstation/control/hplc.py +36 -12
- pychemstation/utils/abc_tables/device.py +17 -3
- pychemstation/utils/abc_tables/table.py +146 -63
- pychemstation/utils/device_types.py +66 -0
- pychemstation/utils/macro.py +2 -0
- pychemstation/utils/table_types.py +65 -8
- {pychemstation-0.10.11.dist-info → pychemstation-0.10.12.dist-info}/METADATA +2 -2
- {pychemstation-0.10.11.dist-info → pychemstation-0.10.12.dist-info}/RECORD +18 -14
- {pychemstation-0.10.11.dist-info → pychemstation-0.10.12.dist-info}/WHEEL +0 -0
- {pychemstation-0.10.11.dist-info → pychemstation-0.10.12.dist-info}/licenses/LICENSE +0 -0
@@ -54,7 +54,7 @@ class CommunicationController(ABCCommunicationController):
|
|
54
54
|
raise RuntimeError("Failed to get number.")
|
55
55
|
|
56
56
|
def get_text_val(self, cmd: str) -> str:
|
57
|
-
tries =
|
57
|
+
tries = 5
|
58
58
|
for _ in range(tries):
|
59
59
|
self.send(Command.GET_TEXT_VAL_CMD.value.format(cmd=cmd))
|
60
60
|
res = self.receive()
|
@@ -5,12 +5,16 @@ import time
|
|
5
5
|
import warnings
|
6
6
|
from typing import Dict, List, Optional, Union, Tuple
|
7
7
|
|
8
|
-
from result import Err,
|
8
|
+
from result import Err, Result, Ok
|
9
9
|
|
10
|
-
from
|
10
|
+
from ..devices.column import ColumnController
|
11
|
+
from ..devices.dad import DADController
|
12
|
+
from ..devices.pump import PumpController
|
13
|
+
from ..devices.sample_info import SampleInfo
|
14
|
+
from ....analysis.chromatogram import (
|
11
15
|
TIME_FORMAT,
|
12
|
-
AgilentChannelChromatogramData,
|
13
16
|
AgilentHPLCChromatogram,
|
17
|
+
AgilentChannelChromatogramData,
|
14
18
|
)
|
15
19
|
|
16
20
|
from ....analysis.process_report import AgilentReport, ReportType
|
@@ -20,12 +24,13 @@ from ....utils.macro import Command
|
|
20
24
|
from ....utils.method_types import (
|
21
25
|
HPLCMethodParams,
|
22
26
|
MethodDetails,
|
27
|
+
TimeTableEntry,
|
23
28
|
Param,
|
24
29
|
PType,
|
25
|
-
TimeTableEntry,
|
26
30
|
)
|
27
|
-
from ....utils.table_types import RegisterFlag, T, Table
|
31
|
+
from ....utils.table_types import RegisterFlag, T, Table
|
28
32
|
from ..devices.injector import InjectorController
|
33
|
+
from ....utils.tray_types import Tray
|
29
34
|
|
30
35
|
|
31
36
|
class MethodController(RunController):
|
@@ -38,9 +43,17 @@ class MethodController(RunController):
|
|
38
43
|
data_dirs: Optional[List[str]],
|
39
44
|
table: Table,
|
40
45
|
offline: bool,
|
41
|
-
|
46
|
+
injector: InjectorController,
|
47
|
+
pump: PumpController,
|
48
|
+
dad: DADController,
|
49
|
+
column: ColumnController,
|
50
|
+
sample_info: SampleInfo,
|
42
51
|
):
|
43
|
-
self.
|
52
|
+
self.injector = injector
|
53
|
+
self.pump = pump
|
54
|
+
self.dad = dad
|
55
|
+
self.column = column
|
56
|
+
self.sample_info = sample_info
|
44
57
|
self.data_files: List[str] = []
|
45
58
|
super().__init__(
|
46
59
|
controller=controller,
|
@@ -50,6 +63,9 @@ class MethodController(RunController):
|
|
50
63
|
offline=offline,
|
51
64
|
)
|
52
65
|
|
66
|
+
def get_sample_location(self) -> Tray:
|
67
|
+
return self.sample_info.get_location()
|
68
|
+
|
53
69
|
def get_current_method_name(self) -> str:
|
54
70
|
self.sleepy_send(Command.GET_METHOD_CMD)
|
55
71
|
res = self.receive()
|
@@ -60,18 +76,8 @@ class MethodController(RunController):
|
|
60
76
|
def get_method_params(self) -> HPLCMethodParams:
|
61
77
|
if self.controller:
|
62
78
|
return HPLCMethodParams(
|
63
|
-
organic_modifier=self.
|
64
|
-
|
65
|
-
register=self.table_locator.register,
|
66
|
-
register_flag=RegisterFlag.SOLVENT_B_COMPOSITION,
|
67
|
-
)
|
68
|
-
),
|
69
|
-
flow=self.controller.get_num_val(
|
70
|
-
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
71
|
-
register=self.table_locator.register,
|
72
|
-
register_flag=RegisterFlag.FLOW,
|
73
|
-
)
|
74
|
-
),
|
79
|
+
organic_modifier=self.get_om(),
|
80
|
+
flow=self.get_flow(),
|
75
81
|
)
|
76
82
|
raise ValueError("Communication controller is offline!")
|
77
83
|
|
@@ -135,26 +141,6 @@ class MethodController(RunController):
|
|
135
141
|
method_name = res.ok_value.string_response
|
136
142
|
return method_name
|
137
143
|
|
138
|
-
def get_post_time(self) -> Union[int, float]:
|
139
|
-
if self.controller:
|
140
|
-
return self.controller.get_num_val(
|
141
|
-
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
142
|
-
register=self.table_locator.register,
|
143
|
-
register_flag=RegisterFlag.POST_TIME,
|
144
|
-
)
|
145
|
-
)
|
146
|
-
raise ValueError("Communication controller is not online!")
|
147
|
-
|
148
|
-
def get_stop_time(self) -> Union[int, float]:
|
149
|
-
if self.controller:
|
150
|
-
return self.controller.get_num_val(
|
151
|
-
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
152
|
-
register=self.table_locator.register,
|
153
|
-
register_flag=RegisterFlag.MAX_TIME,
|
154
|
-
)
|
155
|
-
)
|
156
|
-
raise ValueError("Communication controller is not online!")
|
157
|
-
|
158
144
|
def get_total_runtime(self) -> Union[int, float]:
|
159
145
|
"""Returns total method runtime in minutes."""
|
160
146
|
return self.get_post_time() + self.get_stop_time()
|
@@ -214,20 +200,14 @@ class MethodController(RunController):
|
|
214
200
|
self.edit_method_timetable(updated_method.timetable)
|
215
201
|
|
216
202
|
if save:
|
217
|
-
self.
|
218
|
-
Command.SAVE_METHOD_CMD.value.format(
|
219
|
-
commit_msg=f"saved method at {str(time.time())}"
|
220
|
-
)
|
221
|
-
)
|
203
|
+
self.save_method()
|
222
204
|
|
223
|
-
def
|
224
|
-
self.
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
ptype=PType.NUM,
|
205
|
+
def save_method(self):
|
206
|
+
self.send(
|
207
|
+
Command.SAVE_METHOD_CMD.value.format(
|
208
|
+
commit_msg=f"saved method at {str(time.time())}"
|
209
|
+
)
|
229
210
|
)
|
230
|
-
self._update_param(initial_organic_modifier)
|
231
211
|
|
232
212
|
def _validate_organic_modifier(self, new_om):
|
233
213
|
if not (isinstance(new_om, int) or isinstance(new_om, float)):
|
@@ -237,13 +217,6 @@ class MethodController(RunController):
|
|
237
217
|
if new_om > 100:
|
238
218
|
raise ValueError("Organic modifer must be less than 100.")
|
239
219
|
|
240
|
-
def edit_flow(self, new_flow: Union[int, float]):
|
241
|
-
self._validate_flow(new_flow)
|
242
|
-
flow: Param = Param(
|
243
|
-
val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
|
244
|
-
)
|
245
|
-
self._update_param(flow)
|
246
|
-
|
247
220
|
def _validate_flow(self, new_flow):
|
248
221
|
if not (isinstance(new_flow, int) or isinstance(new_flow, float)):
|
249
222
|
raise ValueError("Flow must be int or float")
|
@@ -252,38 +225,12 @@ class MethodController(RunController):
|
|
252
225
|
if new_flow >= 5.0:
|
253
226
|
raise ValueError("Flow must be less than 5.0")
|
254
227
|
|
255
|
-
def edit_stop_time(self, new_stop_time: Union[int, float]):
|
256
|
-
self.validate_stop_time(new_stop_time)
|
257
|
-
stop_time: Param = Param(
|
258
|
-
val=new_stop_time,
|
259
|
-
chemstation_key=RegisterFlag.MAX_TIME,
|
260
|
-
ptype=PType.NUM,
|
261
|
-
)
|
262
|
-
self._update_param(
|
263
|
-
Param(
|
264
|
-
val="Set", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR
|
265
|
-
)
|
266
|
-
)
|
267
|
-
self._update_param(stop_time)
|
268
|
-
|
269
228
|
def validate_stop_time(self, new_stop_time):
|
270
229
|
if not (isinstance(new_stop_time, int) or isinstance(new_stop_time, float)):
|
271
230
|
raise ValueError("Stop time must be int or float")
|
272
231
|
if new_stop_time < 0:
|
273
232
|
raise ValueError("Stop time must be positive")
|
274
233
|
|
275
|
-
def edit_post_time(self, new_post_time: Union[int, float]):
|
276
|
-
self.validate_post_time(new_post_time)
|
277
|
-
post_time: Param = Param(
|
278
|
-
val=new_post_time,
|
279
|
-
chemstation_key=RegisterFlag.POST_TIME,
|
280
|
-
ptype=PType.NUM,
|
281
|
-
)
|
282
|
-
self._update_param(
|
283
|
-
Param(val="Set", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR)
|
284
|
-
)
|
285
|
-
self._update_param(post_time)
|
286
|
-
|
287
234
|
def validate_post_time(self, new_post_time):
|
288
235
|
if not (isinstance(new_post_time, int) or isinstance(new_post_time, float)):
|
289
236
|
raise ValueError("Post time must be int or float")
|
@@ -298,59 +245,14 @@ class MethodController(RunController):
|
|
298
245
|
new_post_time: Union[int, float] | None,
|
299
246
|
):
|
300
247
|
self.delete_table()
|
301
|
-
self.
|
248
|
+
self._validate_flow(new_flow)
|
249
|
+
self.validate_post_time(new_post_time)
|
250
|
+
self._validate_organic_modifier(new_initial_om)
|
251
|
+
self.validate_stop_time(new_stop_time)
|
302
252
|
self.edit_flow(new_flow)
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
self._update_param(
|
307
|
-
Param(
|
308
|
-
val="Off",
|
309
|
-
chemstation_key=RegisterFlag.STOPTIME_MODE,
|
310
|
-
ptype=PType.STR,
|
311
|
-
)
|
312
|
-
)
|
313
|
-
if new_post_time:
|
314
|
-
self.edit_post_time(new_post_time)
|
315
|
-
else:
|
316
|
-
self._update_param(
|
317
|
-
Param(
|
318
|
-
val="Off",
|
319
|
-
chemstation_key=RegisterFlag.POSTIME_MODE,
|
320
|
-
ptype=PType.STR,
|
321
|
-
)
|
322
|
-
)
|
323
|
-
|
324
|
-
def _update_param(self, method_param: Param):
|
325
|
-
"""Change a method parameter, changes what is visibly seen in Chemstation GUI.
|
326
|
-
(changes the first row in the timetable)
|
327
|
-
|
328
|
-
:param method_param: a parameter to update for currently loaded method.
|
329
|
-
"""
|
330
|
-
register = self.table_locator.register
|
331
|
-
setting_command = (
|
332
|
-
TableOperation.UPDATE_OBJ_HDR_VAL
|
333
|
-
if method_param.ptype == PType.NUM
|
334
|
-
else TableOperation.UPDATE_OBJ_HDR_TEXT
|
335
|
-
)
|
336
|
-
if isinstance(method_param.chemstation_key, list):
|
337
|
-
for register_flag in method_param.chemstation_key:
|
338
|
-
self.sleepy_send(
|
339
|
-
setting_command.value.format(
|
340
|
-
register=register,
|
341
|
-
register_flag=register_flag,
|
342
|
-
val=method_param.val,
|
343
|
-
)
|
344
|
-
)
|
345
|
-
else:
|
346
|
-
self.sleepy_send(
|
347
|
-
setting_command.value.format(
|
348
|
-
register=register,
|
349
|
-
register_flag=method_param.chemstation_key,
|
350
|
-
val=method_param.val,
|
351
|
-
)
|
352
|
-
)
|
353
|
-
self.download()
|
253
|
+
self.edit_initial_om(new_initial_om)
|
254
|
+
self.edit_stop_time(new_stop_time)
|
255
|
+
self.edit_post_time(new_post_time)
|
354
256
|
|
355
257
|
def download(self):
|
356
258
|
self.sleepy_send("DownloadRCMethod PMP1")
|
@@ -585,3 +487,77 @@ class MethodController(RunController):
|
|
585
487
|
Row {i + 1} ({timetable[i].start_time}) has a smaller or equal starttime than row {i} ({start_time})"""
|
586
488
|
)
|
587
489
|
self._validate_row(row)
|
490
|
+
|
491
|
+
def get_om(self):
|
492
|
+
return self._read_num_param(RegisterFlag.SOLVENT_B_COMPOSITION)
|
493
|
+
|
494
|
+
def get_flow(self):
|
495
|
+
return self._read_num_param(RegisterFlag.FLOW)
|
496
|
+
|
497
|
+
def get_post_time(self) -> Union[int, float]:
|
498
|
+
return self._read_num_param(RegisterFlag.POST_TIME)
|
499
|
+
|
500
|
+
def get_stop_time(self) -> Union[int, float]:
|
501
|
+
return self._read_num_param(RegisterFlag.MAX_TIME)
|
502
|
+
|
503
|
+
def edit_post_time(self, new_post_time: Optional[int | float]):
|
504
|
+
if new_post_time:
|
505
|
+
post_time: Param = Param(
|
506
|
+
val=new_post_time,
|
507
|
+
chemstation_key=RegisterFlag.POST_TIME,
|
508
|
+
ptype=PType.NUM,
|
509
|
+
)
|
510
|
+
self._update_param(
|
511
|
+
Param(
|
512
|
+
val="Set",
|
513
|
+
chemstation_key=RegisterFlag.POSTIME_MODE,
|
514
|
+
ptype=PType.STR,
|
515
|
+
)
|
516
|
+
)
|
517
|
+
self._update_param(post_time)
|
518
|
+
else:
|
519
|
+
self._update_param(
|
520
|
+
Param(
|
521
|
+
val="Off",
|
522
|
+
chemstation_key=RegisterFlag.POSTIME_MODE,
|
523
|
+
ptype=PType.STR,
|
524
|
+
)
|
525
|
+
)
|
526
|
+
|
527
|
+
def edit_stop_time(self, new_stop_time: Optional[int | float]):
|
528
|
+
if new_stop_time:
|
529
|
+
stop_time: Param = Param(
|
530
|
+
val=new_stop_time,
|
531
|
+
chemstation_key=RegisterFlag.MAX_TIME,
|
532
|
+
ptype=PType.NUM,
|
533
|
+
)
|
534
|
+
self._update_param(
|
535
|
+
Param(
|
536
|
+
val="Set",
|
537
|
+
chemstation_key=RegisterFlag.STOPTIME_MODE,
|
538
|
+
ptype=PType.STR,
|
539
|
+
)
|
540
|
+
)
|
541
|
+
self._update_param(stop_time)
|
542
|
+
else:
|
543
|
+
self._update_param(
|
544
|
+
Param(
|
545
|
+
val="Off",
|
546
|
+
chemstation_key=RegisterFlag.STOPTIME_MODE,
|
547
|
+
ptype=PType.STR,
|
548
|
+
)
|
549
|
+
)
|
550
|
+
|
551
|
+
def edit_flow(self, new_flow: Union[int, float]):
|
552
|
+
flow: Param = Param(
|
553
|
+
val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
|
554
|
+
)
|
555
|
+
self._update_param(flow)
|
556
|
+
|
557
|
+
def edit_initial_om(self, new_om: Union[int, float]):
|
558
|
+
initial_organic_modifier: Param = Param(
|
559
|
+
val=new_om,
|
560
|
+
chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
|
561
|
+
ptype=PType.NUM,
|
562
|
+
)
|
563
|
+
self._update_param(initial_organic_modifier)
|
@@ -89,18 +89,17 @@ class SequenceController(RunController):
|
|
89
89
|
raise ValueError("Expected vial location, is empty.")
|
90
90
|
|
91
91
|
def get_row(self, row: int) -> SequenceEntry:
|
92
|
-
sample_name = self.
|
93
|
-
vial_location = self.
|
94
|
-
data_file = self.
|
95
|
-
method = self.
|
96
|
-
num_inj = self.
|
97
|
-
inj_vol = self.
|
98
|
-
inj_source =
|
99
|
-
sample_type =
|
100
|
-
vial_enum = self.try_vial_location(vial_location)
|
92
|
+
sample_name = self.get_sample_name(row)
|
93
|
+
vial_location = self.get_vial_location(row)
|
94
|
+
data_file = self.get_data_file(row)
|
95
|
+
method = self.get_method(row)
|
96
|
+
num_inj = self.get_num_inj(row)
|
97
|
+
inj_vol = self.get_inj_vol(row)
|
98
|
+
inj_source = self.get_inj_source(row)
|
99
|
+
sample_type = self.get_sample_type(row)
|
101
100
|
return SequenceEntry(
|
102
101
|
sample_name=sample_name,
|
103
|
-
vial_location=
|
102
|
+
vial_location=vial_location,
|
104
103
|
method=None if len(method) == 0 else method,
|
105
104
|
num_inj=num_inj,
|
106
105
|
inj_vol=inj_vol,
|
@@ -109,6 +108,32 @@ class SequenceController(RunController):
|
|
109
108
|
data_file=data_file,
|
110
109
|
)
|
111
110
|
|
111
|
+
def get_sample_type(self, row):
|
112
|
+
return SampleType(self.get_num(row, RegisterFlag.SAMPLE_TYPE))
|
113
|
+
|
114
|
+
def get_inj_source(self, row):
|
115
|
+
return InjectionSource(self.get_text(row, RegisterFlag.INJ_SOR))
|
116
|
+
|
117
|
+
def get_inj_vol(self, row):
|
118
|
+
return self.try_float(self.get_text(row, RegisterFlag.INJ_VOL))
|
119
|
+
|
120
|
+
def get_num_inj(self, row):
|
121
|
+
return self.try_int(self.get_num(row, RegisterFlag.NUM_INJ))
|
122
|
+
|
123
|
+
def get_method(self, row):
|
124
|
+
return self.get_text(row, RegisterFlag.METHOD)
|
125
|
+
|
126
|
+
def get_data_file(self, row):
|
127
|
+
return self.get_text(row, RegisterFlag.DATA_FILE)
|
128
|
+
|
129
|
+
def get_vial_location(self, row) -> Tray:
|
130
|
+
return self.try_vial_location(
|
131
|
+
self.try_int(self.get_num(row, RegisterFlag.VIAL_LOCATION))
|
132
|
+
)
|
133
|
+
|
134
|
+
def get_sample_name(self, row):
|
135
|
+
return self.get_text(row, RegisterFlag.NAME)
|
136
|
+
|
112
137
|
def switch(self, seq_name: str):
|
113
138
|
"""
|
114
139
|
Switch to the specified sequence. The sequence name does not need the '.S' extension.
|
@@ -145,12 +170,12 @@ class SequenceController(RunController):
|
|
145
170
|
self.send(Command.SAVE_SEQUENCE_CMD)
|
146
171
|
for i in range(int(wanted_row_num)):
|
147
172
|
self.add_row()
|
148
|
-
self.
|
173
|
+
self.download()
|
149
174
|
self.send(Command.SWITCH_SEQUENCE_CMD)
|
150
175
|
for i, row in enumerate(sequence_table.rows):
|
151
176
|
self._edit_row(row=row, row_num=i + 1)
|
152
177
|
self.sleep(1)
|
153
|
-
self.
|
178
|
+
self.download()
|
154
179
|
self.send(Command.SWITCH_SEQUENCE_CMD)
|
155
180
|
|
156
181
|
def _edit_row(self, row: SequenceEntry, row_num: int):
|
@@ -163,7 +188,7 @@ class SequenceController(RunController):
|
|
163
188
|
num_rows = self.get_row_count_safely()
|
164
189
|
while num_rows < row_num:
|
165
190
|
self.add_row()
|
166
|
-
self.
|
191
|
+
self.download()
|
167
192
|
num_rows = self.get_row_count_safely()
|
168
193
|
if row.vial_location:
|
169
194
|
self.edit_vial_location(row.vial_location, row_num, save=False)
|
@@ -181,7 +206,7 @@ class SequenceController(RunController):
|
|
181
206
|
self.edit_data_file(row.data_file, row_num, save=False)
|
182
207
|
if row.sample_type:
|
183
208
|
self.edit_sample_type(row.sample_type, row_num, save=False)
|
184
|
-
self.
|
209
|
+
self.download()
|
185
210
|
|
186
211
|
def edit_sample_type(
|
187
212
|
self, sample_type: SampleType, row_num: int, save: bool = True
|
@@ -194,17 +219,17 @@ class SequenceController(RunController):
|
|
194
219
|
val=sample_type.value,
|
195
220
|
)
|
196
221
|
if save:
|
197
|
-
self.
|
222
|
+
self.download()
|
198
223
|
|
199
224
|
def edit_data_file(self, data_file: str, row_num: int, save: bool = True):
|
200
225
|
self._edit_row_text(row=row_num, col_name=RegisterFlag.DATA_FILE, val=data_file)
|
201
226
|
if save:
|
202
|
-
self.
|
227
|
+
self.download()
|
203
228
|
|
204
229
|
def edit_sample_name(self, sample_name: str, row_num: int, save: bool = True):
|
205
230
|
self._edit_row_text(row=row_num, col_name=RegisterFlag.NAME, val=sample_name)
|
206
231
|
if save:
|
207
|
-
self.
|
232
|
+
self.download()
|
208
233
|
|
209
234
|
def edit_injection_source(
|
210
235
|
self, inj_source: InjectionSource, row_num: int, save: bool = True
|
@@ -215,7 +240,7 @@ class SequenceController(RunController):
|
|
215
240
|
row=row_num, col_name=RegisterFlag.INJ_SOR, val=inj_source.value
|
216
241
|
)
|
217
242
|
if save:
|
218
|
-
self.
|
243
|
+
self.download()
|
219
244
|
|
220
245
|
def edit_injection_volume(
|
221
246
|
self, inj_vol: Union[int, float], row_num: int, save: bool = True
|
@@ -224,12 +249,12 @@ class SequenceController(RunController):
|
|
224
249
|
row=row_num, col_name=RegisterFlag.INJ_VOL, val=str(inj_vol)
|
225
250
|
)
|
226
251
|
if save:
|
227
|
-
self.
|
252
|
+
self.download()
|
228
253
|
|
229
254
|
def edit_num_injections(self, num_inj: int, row_num: int, save: bool = True):
|
230
255
|
self._edit_row_num(row=row_num, col_name=RegisterFlag.NUM_INJ, val=num_inj)
|
231
256
|
if save:
|
232
|
-
self.
|
257
|
+
self.download()
|
233
258
|
|
234
259
|
def edit_method_name(
|
235
260
|
self, method: str, row_num: int, save: bool = True, override_check: bool = False
|
@@ -244,7 +269,7 @@ class SequenceController(RunController):
|
|
244
269
|
)
|
245
270
|
self._edit_row_text(row=row_num, col_name=RegisterFlag.METHOD, val=method)
|
246
271
|
if save:
|
247
|
-
self.
|
272
|
+
self.download()
|
248
273
|
|
249
274
|
def edit_vial_location(self, loc: Tray, row_num: int, save: bool = True):
|
250
275
|
loc_num = -1
|
@@ -270,7 +295,7 @@ class SequenceController(RunController):
|
|
270
295
|
self._edit_row(previous_contents, num_rows)
|
271
296
|
self.move_row(int(num_rows), row_num)
|
272
297
|
self.delete_row(row_num + 1)
|
273
|
-
self.
|
298
|
+
self.download()
|
274
299
|
else:
|
275
300
|
raise ValueError(
|
276
301
|
"`loc` should be of type `VialBar`, `FiftyFourVialPlate`"
|
@@ -288,9 +313,9 @@ class SequenceController(RunController):
|
|
288
313
|
row=row_num, col_name=RegisterFlag.VIAL_LOCATION, val=loc_num
|
289
314
|
)
|
290
315
|
if save:
|
291
|
-
self.
|
316
|
+
self.download()
|
292
317
|
|
293
|
-
def
|
318
|
+
def download(self):
|
294
319
|
self.send(Command.SAVE_SEQUENCE_CMD)
|
295
320
|
|
296
321
|
def run(self, stall_while_running: bool = True):
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from typing import List, Dict
|
2
|
+
|
3
|
+
from ....control.controllers import CommunicationController
|
4
|
+
from ....utils.abc_tables.device import DeviceController
|
5
|
+
from ....utils.macro import Command
|
6
|
+
from ....utils.method_types import Param, PType
|
7
|
+
from ....utils.table_types import Device, Table, RegisterFlag
|
8
|
+
|
9
|
+
|
10
|
+
class ColumnController(DeviceController):
|
11
|
+
def __init__(
|
12
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
13
|
+
):
|
14
|
+
super().__init__(controller, table, offline)
|
15
|
+
if not self.offline:
|
16
|
+
self.display_to_internal: Dict[str, str] = {
|
17
|
+
display_name: real_name
|
18
|
+
for display_name, real_name in zip(
|
19
|
+
self.check_available_column_positions(),
|
20
|
+
self._internal_column_positions(),
|
21
|
+
)
|
22
|
+
}
|
23
|
+
self.internal_to_display: Dict[str, str] = dict(
|
24
|
+
map(reversed, self.display_to_internal.items()) # type: ignore
|
25
|
+
)
|
26
|
+
|
27
|
+
def check_column_position(self):
|
28
|
+
return self.internal_to_display[
|
29
|
+
self._read_str_param(register_flag=RegisterFlag.COLUMN_POSITION)
|
30
|
+
]
|
31
|
+
|
32
|
+
def _internal_column_positions(self) -> List[str]:
|
33
|
+
return self._read_str_param(
|
34
|
+
register_flag=RegisterFlag.AVAIL_COLUMN_POSITIONS
|
35
|
+
).split("|")
|
36
|
+
|
37
|
+
def check_available_column_positions(self) -> List[str]:
|
38
|
+
return self._read_str_param(
|
39
|
+
register_flag=RegisterFlag.AVAIL_COLUMN_DISPLAY_VALUES
|
40
|
+
).split("|")
|
41
|
+
|
42
|
+
def change_column_position(self, column: str):
|
43
|
+
if column not in self.display_to_internal.keys():
|
44
|
+
raise ValueError(f"Please use one of: {self.display_to_internal.keys()}")
|
45
|
+
self._update_param(
|
46
|
+
Param(
|
47
|
+
ptype=PType.STR,
|
48
|
+
chemstation_key=RegisterFlag.COLUMN_POSITION,
|
49
|
+
val=self.display_to_internal[column],
|
50
|
+
),
|
51
|
+
)
|
52
|
+
|
53
|
+
def turn_off(self):
|
54
|
+
self.sleepy_send(Command.COLUMN_OFF_CMD)
|
55
|
+
pass
|
56
|
+
|
57
|
+
def turn_on(self):
|
58
|
+
self.sleepy_send(Command.COLUMN_ON_CMD)
|
59
|
+
|
60
|
+
def download(self):
|
61
|
+
self.sleepy_send("DownloadRCMethod THM1")
|
@@ -0,0 +1,85 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import warnings
|
4
|
+
|
5
|
+
from ...controllers import CommunicationController
|
6
|
+
from ....utils.abc_tables.device import DeviceController
|
7
|
+
from ....utils.device_types import DADChannels, DADChannel
|
8
|
+
from ....utils.macro import Command
|
9
|
+
from ....utils.method_types import Param, PType
|
10
|
+
from ....utils.table_types import RegisterFlag, Table, Device
|
11
|
+
|
12
|
+
|
13
|
+
class DADController(DeviceController):
|
14
|
+
def __init__(
|
15
|
+
self, controller: CommunicationController, table: Table | Device, offline: bool
|
16
|
+
):
|
17
|
+
super().__init__(controller, table, offline)
|
18
|
+
|
19
|
+
def download(self):
|
20
|
+
self.sleepy_send("DownloadRCMethod DAD1")
|
21
|
+
|
22
|
+
def turn_off(self):
|
23
|
+
self.send(Command.LAMP_OFF_CMD)
|
24
|
+
|
25
|
+
def turn_on(self):
|
26
|
+
self.send(Command.LAMP_ON_CMD)
|
27
|
+
|
28
|
+
def load_wavelengths(self) -> DADChannels:
|
29
|
+
return DADChannels(
|
30
|
+
A=self._read_num_param(RegisterFlag.SIGNAL_A),
|
31
|
+
A_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_A_USED)),
|
32
|
+
B=self._read_num_param(RegisterFlag.SIGNAL_B),
|
33
|
+
B_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_B_USED)),
|
34
|
+
C=self._read_num_param(RegisterFlag.SIGNAL_C),
|
35
|
+
C_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_C_USED)),
|
36
|
+
D=self._read_num_param(RegisterFlag.SIGNAL_D),
|
37
|
+
D_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_D_USED)),
|
38
|
+
E=self._read_num_param(RegisterFlag.SIGNAL_E),
|
39
|
+
E_ON=bool(self._read_num_param(RegisterFlag.SIGNAL_E_USED)),
|
40
|
+
)
|
41
|
+
|
42
|
+
def edit_wavelength(self, signal: int, wavelength: DADChannel):
|
43
|
+
warnings.warn("You may need to check that the wavelength is calibrated.")
|
44
|
+
register = RegisterFlag.SIGNAL_A
|
45
|
+
match wavelength:
|
46
|
+
case DADChannel.A:
|
47
|
+
register = RegisterFlag.SIGNAL_A
|
48
|
+
case DADChannel.B:
|
49
|
+
register = RegisterFlag.SIGNAL_B
|
50
|
+
case DADChannel.C:
|
51
|
+
register = RegisterFlag.SIGNAL_C
|
52
|
+
case DADChannel.D:
|
53
|
+
register = RegisterFlag.SIGNAL_D
|
54
|
+
case DADChannel.E:
|
55
|
+
register = RegisterFlag.SIGNAL_E
|
56
|
+
self._update_param(
|
57
|
+
Param(
|
58
|
+
ptype=PType.NUM,
|
59
|
+
val=signal,
|
60
|
+
chemstation_key=register,
|
61
|
+
)
|
62
|
+
)
|
63
|
+
self.download()
|
64
|
+
|
65
|
+
def set_wavelength_usage(self, wavelength: DADChannel, on: bool):
|
66
|
+
register = RegisterFlag.SIGNAL_A_USED
|
67
|
+
match wavelength:
|
68
|
+
case DADChannel.A:
|
69
|
+
register = RegisterFlag.SIGNAL_A_USED
|
70
|
+
case DADChannel.B:
|
71
|
+
register = RegisterFlag.SIGNAL_B_USED
|
72
|
+
case DADChannel.C:
|
73
|
+
register = RegisterFlag.SIGNAL_C_USED
|
74
|
+
case DADChannel.D:
|
75
|
+
register = RegisterFlag.SIGNAL_D_USED
|
76
|
+
case DADChannel.E:
|
77
|
+
register = RegisterFlag.SIGNAL_E_USED
|
78
|
+
self._update_param(
|
79
|
+
Param(
|
80
|
+
ptype=PType.NUM,
|
81
|
+
val=int(on),
|
82
|
+
chemstation_key=register,
|
83
|
+
)
|
84
|
+
)
|
85
|
+
self.download()
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import warnings
|
4
|
+
|
3
5
|
from ....control.controllers import CommunicationController
|
4
6
|
from ....utils.abc_tables.device import DeviceController
|
5
7
|
from ....utils.injector_types import (
|
@@ -15,6 +17,7 @@ from ....utils.injector_types import (
|
|
15
17
|
DrawDefaultVolume,
|
16
18
|
DrawDefaultLocation,
|
17
19
|
)
|
20
|
+
from ....utils.method_types import Param, PType
|
18
21
|
from ....utils.table_types import RegisterFlag, Table
|
19
22
|
from ....utils.tray_types import Tray, FiftyFourVialPlate, VialBar, LocationPlus
|
20
23
|
|
@@ -25,6 +28,21 @@ class InjectorController(DeviceController):
|
|
25
28
|
):
|
26
29
|
super().__init__(controller, table, offline)
|
27
30
|
|
31
|
+
def turn_off(self):
|
32
|
+
warnings.warn("Injector has no on/off state.")
|
33
|
+
|
34
|
+
def turn_on(self):
|
35
|
+
warnings.warn("Injector has no on/off state.")
|
36
|
+
|
37
|
+
def change_injection_volume(self, new_injection_volume: float):
|
38
|
+
self._update_param(
|
39
|
+
param=Param(
|
40
|
+
ptype=PType.NUM,
|
41
|
+
val=new_injection_volume,
|
42
|
+
chemstation_key=RegisterFlag.INJECTION_VOLUME,
|
43
|
+
)
|
44
|
+
)
|
45
|
+
|
28
46
|
def try_vial_location(self, val: str) -> Tray:
|
29
47
|
try:
|
30
48
|
return FiftyFourVialPlate.from_str(val)
|