pychemstation 0.10.10__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 +128 -211
- pychemstation/control/controllers/data_aq/sequence.py +74 -51
- pychemstation/control/controllers/devices/column.py +61 -0
- pychemstation/control/controllers/devices/dad.py +85 -0
- pychemstation/control/controllers/devices/injector.py +20 -12
- 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 +166 -75
- pychemstation/utils/device_types.py +66 -0
- pychemstation/utils/macro.py +2 -0
- pychemstation/utils/table_types.py +65 -8
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/METADATA +2 -2
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/RECORD +18 -14
- {pychemstation-0.10.10.dist-info → pychemstation-0.10.12.dist-info}/WHEEL +0 -0
- {pychemstation-0.10.10.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
|
|
@@ -114,23 +120,20 @@ class MethodController(RunController):
|
|
114
120
|
return entries
|
115
121
|
|
116
122
|
def load(self) -> MethodDetails:
|
117
|
-
rows = self.
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
return self.table_state
|
132
|
-
else:
|
133
|
-
raise RuntimeError(rows.err_value)
|
123
|
+
rows = self.get_row_count_safely()
|
124
|
+
method_name = self.get_method_name()
|
125
|
+
timetable_rows = self.get_timetable(rows)
|
126
|
+
params = self.get_method_params()
|
127
|
+
stop_time = self.get_stop_time()
|
128
|
+
post_time = self.get_post_time()
|
129
|
+
self.table_state = MethodDetails(
|
130
|
+
name=method_name,
|
131
|
+
timetable=timetable_rows,
|
132
|
+
stop_time=stop_time,
|
133
|
+
post_time=post_time,
|
134
|
+
params=params,
|
135
|
+
)
|
136
|
+
return self.table_state
|
134
137
|
|
135
138
|
def get_method_name(self):
|
136
139
|
self.send(Command.GET_METHOD_CMD)
|
@@ -138,26 +141,6 @@ class MethodController(RunController):
|
|
138
141
|
method_name = res.ok_value.string_response
|
139
142
|
return method_name
|
140
143
|
|
141
|
-
def get_post_time(self) -> Union[int, float]:
|
142
|
-
if self.controller:
|
143
|
-
return self.controller.get_num_val(
|
144
|
-
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
145
|
-
register=self.table_locator.register,
|
146
|
-
register_flag=RegisterFlag.POST_TIME,
|
147
|
-
)
|
148
|
-
)
|
149
|
-
raise ValueError("Communication controller is not online!")
|
150
|
-
|
151
|
-
def get_stop_time(self) -> Union[int, float]:
|
152
|
-
if self.controller:
|
153
|
-
return self.controller.get_num_val(
|
154
|
-
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
155
|
-
register=self.table_locator.register,
|
156
|
-
register_flag=RegisterFlag.MAX_TIME,
|
157
|
-
)
|
158
|
-
)
|
159
|
-
raise ValueError("Communication controller is not online!")
|
160
|
-
|
161
144
|
def get_total_runtime(self) -> Union[int, float]:
|
162
145
|
"""Returns total method runtime in minutes."""
|
163
146
|
return self.get_post_time() + self.get_stop_time()
|
@@ -217,20 +200,14 @@ class MethodController(RunController):
|
|
217
200
|
self.edit_method_timetable(updated_method.timetable)
|
218
201
|
|
219
202
|
if save:
|
220
|
-
self.
|
221
|
-
Command.SAVE_METHOD_CMD.value.format(
|
222
|
-
commit_msg=f"saved method at {str(time.time())}"
|
223
|
-
)
|
224
|
-
)
|
203
|
+
self.save_method()
|
225
204
|
|
226
|
-
def
|
227
|
-
self.
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
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
|
+
)
|
232
210
|
)
|
233
|
-
self._update_param(initial_organic_modifier)
|
234
211
|
|
235
212
|
def _validate_organic_modifier(self, new_om):
|
236
213
|
if not (isinstance(new_om, int) or isinstance(new_om, float)):
|
@@ -240,13 +217,6 @@ class MethodController(RunController):
|
|
240
217
|
if new_om > 100:
|
241
218
|
raise ValueError("Organic modifer must be less than 100.")
|
242
219
|
|
243
|
-
def edit_flow(self, new_flow: Union[int, float]):
|
244
|
-
self._validate_flow(new_flow)
|
245
|
-
flow: Param = Param(
|
246
|
-
val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
|
247
|
-
)
|
248
|
-
self._update_param(flow)
|
249
|
-
|
250
220
|
def _validate_flow(self, new_flow):
|
251
221
|
if not (isinstance(new_flow, int) or isinstance(new_flow, float)):
|
252
222
|
raise ValueError("Flow must be int or float")
|
@@ -255,38 +225,12 @@ class MethodController(RunController):
|
|
255
225
|
if new_flow >= 5.0:
|
256
226
|
raise ValueError("Flow must be less than 5.0")
|
257
227
|
|
258
|
-
def edit_stop_time(self, new_stop_time: Union[int, float]):
|
259
|
-
self.validate_stop_time(new_stop_time)
|
260
|
-
stop_time: Param = Param(
|
261
|
-
val=new_stop_time,
|
262
|
-
chemstation_key=RegisterFlag.MAX_TIME,
|
263
|
-
ptype=PType.NUM,
|
264
|
-
)
|
265
|
-
self._update_param(
|
266
|
-
Param(
|
267
|
-
val="Set", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR
|
268
|
-
)
|
269
|
-
)
|
270
|
-
self._update_param(stop_time)
|
271
|
-
|
272
228
|
def validate_stop_time(self, new_stop_time):
|
273
229
|
if not (isinstance(new_stop_time, int) or isinstance(new_stop_time, float)):
|
274
230
|
raise ValueError("Stop time must be int or float")
|
275
231
|
if new_stop_time < 0:
|
276
232
|
raise ValueError("Stop time must be positive")
|
277
233
|
|
278
|
-
def edit_post_time(self, new_post_time: Union[int, float]):
|
279
|
-
self.validate_post_time(new_post_time)
|
280
|
-
post_time: Param = Param(
|
281
|
-
val=new_post_time,
|
282
|
-
chemstation_key=RegisterFlag.POST_TIME,
|
283
|
-
ptype=PType.NUM,
|
284
|
-
)
|
285
|
-
self._update_param(
|
286
|
-
Param(val="Set", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR)
|
287
|
-
)
|
288
|
-
self._update_param(post_time)
|
289
|
-
|
290
234
|
def validate_post_time(self, new_post_time):
|
291
235
|
if not (isinstance(new_post_time, int) or isinstance(new_post_time, float)):
|
292
236
|
raise ValueError("Post time must be int or float")
|
@@ -301,59 +245,14 @@ class MethodController(RunController):
|
|
301
245
|
new_post_time: Union[int, float] | None,
|
302
246
|
):
|
303
247
|
self.delete_table()
|
304
|
-
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)
|
305
252
|
self.edit_flow(new_flow)
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
self._update_param(
|
310
|
-
Param(
|
311
|
-
val="Off",
|
312
|
-
chemstation_key=RegisterFlag.STOPTIME_MODE,
|
313
|
-
ptype=PType.STR,
|
314
|
-
)
|
315
|
-
)
|
316
|
-
if new_post_time:
|
317
|
-
self.edit_post_time(new_post_time)
|
318
|
-
else:
|
319
|
-
self._update_param(
|
320
|
-
Param(
|
321
|
-
val="Off",
|
322
|
-
chemstation_key=RegisterFlag.POSTIME_MODE,
|
323
|
-
ptype=PType.STR,
|
324
|
-
)
|
325
|
-
)
|
326
|
-
|
327
|
-
def _update_param(self, method_param: Param):
|
328
|
-
"""Change a method parameter, changes what is visibly seen in Chemstation GUI.
|
329
|
-
(changes the first row in the timetable)
|
330
|
-
|
331
|
-
:param method_param: a parameter to update for currently loaded method.
|
332
|
-
"""
|
333
|
-
register = self.table_locator.register
|
334
|
-
setting_command = (
|
335
|
-
TableOperation.UPDATE_OBJ_HDR_VAL
|
336
|
-
if method_param.ptype == PType.NUM
|
337
|
-
else TableOperation.UPDATE_OBJ_HDR_TEXT
|
338
|
-
)
|
339
|
-
if isinstance(method_param.chemstation_key, list):
|
340
|
-
for register_flag in method_param.chemstation_key:
|
341
|
-
self.sleepy_send(
|
342
|
-
setting_command.value.format(
|
343
|
-
register=register,
|
344
|
-
register_flag=register_flag,
|
345
|
-
val=method_param.val,
|
346
|
-
)
|
347
|
-
)
|
348
|
-
else:
|
349
|
-
self.sleepy_send(
|
350
|
-
setting_command.value.format(
|
351
|
-
register=register,
|
352
|
-
register_flag=method_param.chemstation_key,
|
353
|
-
val=method_param.val,
|
354
|
-
)
|
355
|
-
)
|
356
|
-
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)
|
357
256
|
|
358
257
|
def download(self):
|
359
258
|
self.sleepy_send("DownloadRCMethod PMP1")
|
@@ -443,62 +342,6 @@ class MethodController(RunController):
|
|
443
342
|
self.download()
|
444
343
|
return time_added, flow_added, om_added, function_added
|
445
344
|
|
446
|
-
# if first_row:
|
447
|
-
# time_added = False
|
448
|
-
# flow_row_method: Callable = (
|
449
|
-
# self.add_new_col_text
|
450
|
-
# if row.flow and not row.organic_modifer
|
451
|
-
# else self._edit_row_text
|
452
|
-
# )
|
453
|
-
# if row.organic_modifer:
|
454
|
-
# self.add_row()
|
455
|
-
# self.add_new_col_text(
|
456
|
-
# col_name=RegisterFlag.FUNCTION,
|
457
|
-
# val=RegisterFlag.SOLVENT_COMPOSITION.value,
|
458
|
-
# )
|
459
|
-
# if not time_added:
|
460
|
-
# time_added = True
|
461
|
-
# self.add_new_col_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
462
|
-
# self.add_new_col_num(
|
463
|
-
# col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION,
|
464
|
-
# val=row.organic_modifer,
|
465
|
-
# )
|
466
|
-
# if row.flow:
|
467
|
-
# self.add_row()
|
468
|
-
# self.get_num_rows()
|
469
|
-
# flow_row_method(
|
470
|
-
# col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value
|
471
|
-
# )
|
472
|
-
# if not time_added:
|
473
|
-
# time_added = True
|
474
|
-
# self.add_new_col_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
475
|
-
# self.add_new_col_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
|
476
|
-
# self._edit_row_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
|
477
|
-
# self.download()
|
478
|
-
# else:
|
479
|
-
# if row.organic_modifer:
|
480
|
-
# self.add_row()
|
481
|
-
# self.get_num_rows()
|
482
|
-
# self._edit_row_text(
|
483
|
-
# col_name=RegisterFlag.FUNCTION,
|
484
|
-
# val=RegisterFlag.SOLVENT_COMPOSITION.value,
|
485
|
-
# )
|
486
|
-
# self._edit_row_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
487
|
-
# self._edit_row_num(
|
488
|
-
# col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION,
|
489
|
-
# val=row.organic_modifer,
|
490
|
-
# )
|
491
|
-
# self.download()
|
492
|
-
# if row.flow:
|
493
|
-
# self.add_row()
|
494
|
-
# self.get_num_rows()
|
495
|
-
# self._edit_row_text(
|
496
|
-
# col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value
|
497
|
-
# )
|
498
|
-
# self._edit_row_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
|
499
|
-
# self._edit_row_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
500
|
-
# self.download()
|
501
|
-
|
502
345
|
def edit_method_timetable(self, timetable_rows: List[TimeTableEntry]):
|
503
346
|
self.get_num_rows()
|
504
347
|
self.delete_table()
|
@@ -508,8 +351,8 @@ class MethodController(RunController):
|
|
508
351
|
res = self.get_num_rows()
|
509
352
|
|
510
353
|
self.new_table()
|
511
|
-
num_rows = self.
|
512
|
-
if num_rows
|
354
|
+
num_rows = self.get_row_count_safely()
|
355
|
+
if num_rows != 0:
|
513
356
|
raise ValueError("Should be zero rows!")
|
514
357
|
|
515
358
|
time_added = False
|
@@ -644,3 +487,77 @@ class MethodController(RunController):
|
|
644
487
|
Row {i + 1} ({timetable[i].start_time}) has a smaller or equal starttime than row {i} ({start_time})"""
|
645
488
|
)
|
646
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)
|
@@ -55,19 +55,20 @@ class SequenceController(RunController):
|
|
55
55
|
)
|
56
56
|
|
57
57
|
def load(self) -> SequenceTable:
|
58
|
-
rows = self.
|
58
|
+
rows = self.get_row_count_safely()
|
59
59
|
self.send(Command.GET_SEQUENCE_CMD)
|
60
60
|
seq_name = self.receive()
|
61
61
|
|
62
|
-
if
|
62
|
+
if seq_name.is_ok():
|
63
63
|
self.table_state: SequenceTable = SequenceTable(
|
64
64
|
name=seq_name.ok_value.string_response.partition(".S")[0],
|
65
|
-
rows=[
|
66
|
-
self.get_row(r + 1) for r in range(int(rows.ok_value.num_response))
|
67
|
-
],
|
65
|
+
rows=[self.get_row(r + 1) for r in range(int(rows))],
|
68
66
|
)
|
69
67
|
return self.table_state
|
70
|
-
|
68
|
+
else:
|
69
|
+
raise RuntimeError(
|
70
|
+
f"couldn't read rows or sequence name: {seq_name.err_value}"
|
71
|
+
)
|
71
72
|
|
72
73
|
def try_int(self, val: Any) -> Optional[int]:
|
73
74
|
try:
|
@@ -88,18 +89,17 @@ class SequenceController(RunController):
|
|
88
89
|
raise ValueError("Expected vial location, is empty.")
|
89
90
|
|
90
91
|
def get_row(self, row: int) -> SequenceEntry:
|
91
|
-
sample_name = self.
|
92
|
-
vial_location = self.
|
93
|
-
data_file = self.
|
94
|
-
method = self.
|
95
|
-
num_inj = self.
|
96
|
-
inj_vol = self.
|
97
|
-
inj_source =
|
98
|
-
sample_type =
|
99
|
-
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)
|
100
100
|
return SequenceEntry(
|
101
101
|
sample_name=sample_name,
|
102
|
-
vial_location=
|
102
|
+
vial_location=vial_location,
|
103
103
|
method=None if len(method) == 0 else method,
|
104
104
|
num_inj=num_inj,
|
105
105
|
inj_vol=inj_vol,
|
@@ -108,6 +108,32 @@ class SequenceController(RunController):
|
|
108
108
|
data_file=data_file,
|
109
109
|
)
|
110
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
|
+
|
111
137
|
def switch(self, seq_name: str):
|
112
138
|
"""
|
113
139
|
Switch to the specified sequence. The sequence name does not need the '.S' extension.
|
@@ -136,23 +162,21 @@ class SequenceController(RunController):
|
|
136
162
|
:param sequence_table:
|
137
163
|
"""
|
138
164
|
self.table_state = sequence_table
|
139
|
-
rows = self.
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
self.save()
|
155
|
-
self.send(Command.SWITCH_SEQUENCE_CMD)
|
165
|
+
rows = self.get_row_count_safely()
|
166
|
+
existing_row_num = rows
|
167
|
+
wanted_row_num = len(sequence_table.rows)
|
168
|
+
for i in range(int(existing_row_num)):
|
169
|
+
self.delete_row(int(existing_row_num - i))
|
170
|
+
self.send(Command.SAVE_SEQUENCE_CMD)
|
171
|
+
for i in range(int(wanted_row_num)):
|
172
|
+
self.add_row()
|
173
|
+
self.download()
|
174
|
+
self.send(Command.SWITCH_SEQUENCE_CMD)
|
175
|
+
for i, row in enumerate(sequence_table.rows):
|
176
|
+
self._edit_row(row=row, row_num=i + 1)
|
177
|
+
self.sleep(1)
|
178
|
+
self.download()
|
179
|
+
self.send(Command.SWITCH_SEQUENCE_CMD)
|
156
180
|
|
157
181
|
def _edit_row(self, row: SequenceEntry, row_num: int):
|
158
182
|
"""
|
@@ -161,12 +185,11 @@ class SequenceController(RunController):
|
|
161
185
|
:param row: sequence row entry with updated information
|
162
186
|
:param row_num: the row to edit, based on 1-based indexing
|
163
187
|
"""
|
164
|
-
num_rows = self.
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
num_rows = self.get_num_rows()
|
188
|
+
num_rows = self.get_row_count_safely()
|
189
|
+
while num_rows < row_num:
|
190
|
+
self.add_row()
|
191
|
+
self.download()
|
192
|
+
num_rows = self.get_row_count_safely()
|
170
193
|
if row.vial_location:
|
171
194
|
self.edit_vial_location(row.vial_location, row_num, save=False)
|
172
195
|
if row.method:
|
@@ -183,7 +206,7 @@ class SequenceController(RunController):
|
|
183
206
|
self.edit_data_file(row.data_file, row_num, save=False)
|
184
207
|
if row.sample_type:
|
185
208
|
self.edit_sample_type(row.sample_type, row_num, save=False)
|
186
|
-
self.
|
209
|
+
self.download()
|
187
210
|
|
188
211
|
def edit_sample_type(
|
189
212
|
self, sample_type: SampleType, row_num: int, save: bool = True
|
@@ -196,17 +219,17 @@ class SequenceController(RunController):
|
|
196
219
|
val=sample_type.value,
|
197
220
|
)
|
198
221
|
if save:
|
199
|
-
self.
|
222
|
+
self.download()
|
200
223
|
|
201
224
|
def edit_data_file(self, data_file: str, row_num: int, save: bool = True):
|
202
225
|
self._edit_row_text(row=row_num, col_name=RegisterFlag.DATA_FILE, val=data_file)
|
203
226
|
if save:
|
204
|
-
self.
|
227
|
+
self.download()
|
205
228
|
|
206
229
|
def edit_sample_name(self, sample_name: str, row_num: int, save: bool = True):
|
207
230
|
self._edit_row_text(row=row_num, col_name=RegisterFlag.NAME, val=sample_name)
|
208
231
|
if save:
|
209
|
-
self.
|
232
|
+
self.download()
|
210
233
|
|
211
234
|
def edit_injection_source(
|
212
235
|
self, inj_source: InjectionSource, row_num: int, save: bool = True
|
@@ -217,7 +240,7 @@ class SequenceController(RunController):
|
|
217
240
|
row=row_num, col_name=RegisterFlag.INJ_SOR, val=inj_source.value
|
218
241
|
)
|
219
242
|
if save:
|
220
|
-
self.
|
243
|
+
self.download()
|
221
244
|
|
222
245
|
def edit_injection_volume(
|
223
246
|
self, inj_vol: Union[int, float], row_num: int, save: bool = True
|
@@ -226,12 +249,12 @@ class SequenceController(RunController):
|
|
226
249
|
row=row_num, col_name=RegisterFlag.INJ_VOL, val=str(inj_vol)
|
227
250
|
)
|
228
251
|
if save:
|
229
|
-
self.
|
252
|
+
self.download()
|
230
253
|
|
231
254
|
def edit_num_injections(self, num_inj: int, row_num: int, save: bool = True):
|
232
255
|
self._edit_row_num(row=row_num, col_name=RegisterFlag.NUM_INJ, val=num_inj)
|
233
256
|
if save:
|
234
|
-
self.
|
257
|
+
self.download()
|
235
258
|
|
236
259
|
def edit_method_name(
|
237
260
|
self, method: str, row_num: int, save: bool = True, override_check: bool = False
|
@@ -246,7 +269,7 @@ class SequenceController(RunController):
|
|
246
269
|
)
|
247
270
|
self._edit_row_text(row=row_num, col_name=RegisterFlag.METHOD, val=method)
|
248
271
|
if save:
|
249
|
-
self.
|
272
|
+
self.download()
|
250
273
|
|
251
274
|
def edit_vial_location(self, loc: Tray, row_num: int, save: bool = True):
|
252
275
|
loc_num = -1
|
@@ -268,11 +291,11 @@ class SequenceController(RunController):
|
|
268
291
|
elif isinstance(loc, VialBar) or isinstance(loc, FiftyFourVialPlate):
|
269
292
|
self.add_row()
|
270
293
|
previous_contents.vial_location = loc
|
271
|
-
num_rows = self.
|
294
|
+
num_rows = self.get_row_count_safely()
|
272
295
|
self._edit_row(previous_contents, num_rows)
|
273
296
|
self.move_row(int(num_rows), row_num)
|
274
297
|
self.delete_row(row_num + 1)
|
275
|
-
self.
|
298
|
+
self.download()
|
276
299
|
else:
|
277
300
|
raise ValueError(
|
278
301
|
"`loc` should be of type `VialBar`, `FiftyFourVialPlate`"
|
@@ -290,9 +313,9 @@ class SequenceController(RunController):
|
|
290
313
|
row=row_num, col_name=RegisterFlag.VIAL_LOCATION, val=loc_num
|
291
314
|
)
|
292
315
|
if save:
|
293
|
-
self.
|
316
|
+
self.download()
|
294
317
|
|
295
|
-
def
|
318
|
+
def download(self):
|
296
319
|
self.send(Command.SAVE_SEQUENCE_CMD)
|
297
320
|
|
298
321
|
def run(self, stall_while_running: bool = True):
|