pychemstation 0.10.2__py3-none-any.whl → 0.10.4__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/__init__.py +1 -1
- pychemstation/analysis/__init__.py +3 -4
- pychemstation/analysis/base_spectrum.py +7 -7
- pychemstation/{utils → analysis}/chromatogram.py +4 -4
- pychemstation/analysis/process_report.py +106 -70
- pychemstation/control/README.md +21 -53
- pychemstation/control/__init__.py +3 -2
- pychemstation/control/controllers/__init__.py +1 -5
- pychemstation/control/controllers/comm.py +20 -11
- pychemstation/control/controllers/devices/device.py +22 -12
- pychemstation/control/controllers/devices/injector.py +24 -14
- pychemstation/control/controllers/tables/method.py +233 -100
- pychemstation/control/controllers/tables/ms.py +7 -4
- pychemstation/control/controllers/tables/sequence.py +134 -54
- pychemstation/control/controllers/tables/table.py +152 -92
- pychemstation/control/hplc.py +96 -78
- pychemstation/generated/__init__.py +0 -2
- pychemstation/generated/pump_method.py +15 -19
- pychemstation/utils/macro.py +10 -9
- pychemstation/utils/method_types.py +1 -0
- pychemstation/utils/num_utils.py +2 -2
- pychemstation/utils/parsing.py +0 -11
- pychemstation/utils/sequence_types.py +2 -3
- pychemstation/utils/spec_utils.py +2 -3
- pychemstation/utils/table_types.py +10 -9
- pychemstation/utils/tray_types.py +48 -38
- {pychemstation-0.10.2.dist-info → pychemstation-0.10.4.dist-info}/METADATA +46 -20
- pychemstation-0.10.4.dist-info/RECORD +37 -0
- pychemstation-0.10.2.dist-info/RECORD +0 -37
- {pychemstation-0.10.2.dist-info → pychemstation-0.10.4.dist-info}/WHEEL +0 -0
- {pychemstation-0.10.2.dist-info → pychemstation-0.10.4.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,8 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
from .device import DeviceController
|
4
1
|
from ....control.controllers import CommunicationController
|
5
2
|
from ....utils.injector_types import (
|
6
3
|
Draw,
|
7
4
|
Inject,
|
5
|
+
InjectorFunction,
|
8
6
|
InjectorTable,
|
9
7
|
Mode,
|
10
8
|
Remote,
|
@@ -14,14 +12,16 @@ from ....utils.injector_types import (
|
|
14
12
|
)
|
15
13
|
from ....utils.table_types import RegisterFlag, Table
|
16
14
|
from ....utils.tray_types import Tray
|
15
|
+
from .device import DeviceController
|
17
16
|
|
18
17
|
|
19
18
|
class InjectorController(DeviceController):
|
20
|
-
|
21
|
-
|
19
|
+
def __init__(
|
20
|
+
self, controller: CommunicationController, table: Table, offline: bool
|
21
|
+
):
|
22
22
|
super().__init__(controller, table, offline)
|
23
23
|
|
24
|
-
def get_row(self, row: int) ->
|
24
|
+
def get_row(self, row: int) -> InjectorFunction:
|
25
25
|
def return_tray_loc() -> Tray:
|
26
26
|
pass
|
27
27
|
|
@@ -34,18 +34,28 @@ class InjectorController(DeviceController):
|
|
34
34
|
# TODO: better error handling
|
35
35
|
is_source = SourceType(self.get_text(row, RegisterFlag.DRAW_SOURCE))
|
36
36
|
is_volume = Mode(self.get_text(row, RegisterFlag.DRAW_VOLUME))
|
37
|
-
vol =
|
37
|
+
vol = (
|
38
|
+
self.get_num(row, RegisterFlag.DRAW_VOLUME_VALUE)
|
39
|
+
if is_volume == Mode.SET
|
40
|
+
else None
|
41
|
+
)
|
38
42
|
if is_source is SourceType.SPECIFIC_LOCATION:
|
39
43
|
return Draw(amount=vol, source=return_tray_loc())
|
40
44
|
elif is_source is SourceType.LOCATION:
|
41
|
-
return Draw(
|
45
|
+
return Draw(
|
46
|
+
amount=vol, location=self.get_text(row, RegisterFlag.DRAW_LOCATION)
|
47
|
+
)
|
42
48
|
elif function == "Remote":
|
43
|
-
return Remote(
|
44
|
-
|
49
|
+
return Remote(
|
50
|
+
command=RemoteCommand(self.get_text(row, RegisterFlag.REMOTE)),
|
51
|
+
duration=self.get_num(row, RegisterFlag.REMOTE_DUR),
|
52
|
+
)
|
45
53
|
|
46
|
-
def load(self) -> InjectorTable
|
54
|
+
def load(self) -> InjectorTable:
|
47
55
|
rows = self.get_num_rows()
|
48
56
|
if rows.is_ok():
|
49
|
-
return InjectorTable(
|
50
|
-
|
51
|
-
|
57
|
+
return InjectorTable(
|
58
|
+
functions=[
|
59
|
+
self.get_row(i) for i in range(int(rows.ok_value.num_response))
|
60
|
+
]
|
61
|
+
)
|
@@ -9,7 +9,7 @@ from xsdata.formats.dataclass.parsers import XmlParser
|
|
9
9
|
from ....analysis.process_report import AgilentReport, ReportType
|
10
10
|
from ....control.controllers import CommunicationController
|
11
11
|
from ....generated import DadMethod, PumpMethod, SolventElement
|
12
|
-
from
|
12
|
+
from pychemstation.analysis.chromatogram import (
|
13
13
|
TIME_FORMAT,
|
14
14
|
AgilentChannelChromatogramData,
|
15
15
|
AgilentHPLCChromatogram,
|
@@ -32,15 +32,24 @@ class MethodController(TableController):
|
|
32
32
|
Class containing method related logic
|
33
33
|
"""
|
34
34
|
|
35
|
-
def __init__(
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
35
|
+
def __init__(
|
36
|
+
self,
|
37
|
+
controller: CommunicationController,
|
38
|
+
src: str,
|
39
|
+
data_dirs: List[str],
|
40
|
+
table: Table,
|
41
|
+
offline: bool,
|
42
|
+
injector_controller: InjectorController,
|
43
|
+
):
|
41
44
|
self.injector_controller = injector_controller
|
42
45
|
self.data_files: List[str] = []
|
43
|
-
super().__init__(
|
46
|
+
super().__init__(
|
47
|
+
controller=controller,
|
48
|
+
src=src,
|
49
|
+
data_dirs=data_dirs,
|
50
|
+
table=table,
|
51
|
+
offline=offline,
|
52
|
+
)
|
44
53
|
|
45
54
|
def check(self) -> str:
|
46
55
|
time.sleep(2)
|
@@ -52,16 +61,17 @@ class MethodController(TableController):
|
|
52
61
|
return "ERROR"
|
53
62
|
|
54
63
|
def get_method_params(self) -> HPLCMethodParams:
|
55
|
-
return HPLCMethodParams(
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
64
|
+
return HPLCMethodParams(
|
65
|
+
organic_modifier=self.controller.get_num_val(
|
66
|
+
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
67
|
+
register=self.table_locator.register,
|
68
|
+
register_flag=RegisterFlag.SOLVENT_B_COMPOSITION,
|
69
|
+
)
|
70
|
+
),
|
61
71
|
flow=self.controller.get_num_val(
|
62
72
|
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
63
73
|
register=self.table_locator.register,
|
64
|
-
register_flag=RegisterFlag.FLOW
|
74
|
+
register_flag=RegisterFlag.FLOW,
|
65
75
|
)
|
66
76
|
),
|
67
77
|
)
|
@@ -79,9 +89,11 @@ class MethodController(TableController):
|
|
79
89
|
except RuntimeError:
|
80
90
|
pass
|
81
91
|
|
82
|
-
return TimeTableEntry(
|
83
|
-
|
84
|
-
|
92
|
+
return TimeTableEntry(
|
93
|
+
start_time=self.get_num(row, RegisterFlag.TIME),
|
94
|
+
organic_modifer=om,
|
95
|
+
flow=flow,
|
96
|
+
)
|
85
97
|
|
86
98
|
def get_timetable(self, rows: int):
|
87
99
|
uncoalesced_timetable_rows = [self.get_row(r + 1) for r in range(rows)]
|
@@ -89,9 +101,11 @@ class MethodController(TableController):
|
|
89
101
|
for row in uncoalesced_timetable_rows:
|
90
102
|
time_key = str(row.start_time)
|
91
103
|
if time_key not in timetable_rows.keys():
|
92
|
-
timetable_rows[time_key] = TimeTableEntry(
|
93
|
-
|
94
|
-
|
104
|
+
timetable_rows[time_key] = TimeTableEntry(
|
105
|
+
start_time=row.start_time,
|
106
|
+
flow=row.flow,
|
107
|
+
organic_modifer=row.organic_modifer,
|
108
|
+
)
|
95
109
|
else:
|
96
110
|
if row.flow:
|
97
111
|
timetable_rows[time_key].flow = row.flow
|
@@ -109,11 +123,13 @@ class MethodController(TableController):
|
|
109
123
|
params = self.get_method_params()
|
110
124
|
stop_time = self.get_stop_time()
|
111
125
|
post_time = self.get_post_time()
|
112
|
-
self.table_state = MethodDetails(
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
126
|
+
self.table_state = MethodDetails(
|
127
|
+
name=method_name,
|
128
|
+
timetable=timetable_rows,
|
129
|
+
stop_time=stop_time,
|
130
|
+
post_time=post_time,
|
131
|
+
params=params,
|
132
|
+
)
|
117
133
|
return self.table_state
|
118
134
|
else:
|
119
135
|
raise RuntimeError(rows.err_value)
|
@@ -128,13 +144,17 @@ class MethodController(TableController):
|
|
128
144
|
return self.controller.get_num_val(
|
129
145
|
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
130
146
|
register=self.table_locator.register,
|
131
|
-
register_flag=RegisterFlag.POST_TIME
|
147
|
+
register_flag=RegisterFlag.POST_TIME,
|
148
|
+
)
|
149
|
+
)
|
132
150
|
|
133
151
|
def get_stop_time(self) -> Union[int, float]:
|
134
152
|
return self.controller.get_num_val(
|
135
153
|
cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
|
136
154
|
register=self.table_locator.register,
|
137
|
-
register_flag=RegisterFlag.MAX_TIME
|
155
|
+
register_flag=RegisterFlag.MAX_TIME,
|
156
|
+
)
|
157
|
+
)
|
138
158
|
|
139
159
|
def get_total_runtime(self) -> Union[int, float]:
|
140
160
|
"""Returns total method runtime in minutes."""
|
@@ -163,7 +183,11 @@ class MethodController(TableController):
|
|
163
183
|
:raise AssertionError: The desired method is not selected. Try again.
|
164
184
|
"""
|
165
185
|
method_dir = self.src if not alt_method_dir else alt_method_dir
|
166
|
-
self.send(
|
186
|
+
self.send(
|
187
|
+
Command.SWITCH_METHOD_CMD_SPECIFIC.value.format(
|
188
|
+
method_dir=method_dir, method_name=method_name
|
189
|
+
)
|
190
|
+
)
|
167
191
|
|
168
192
|
time.sleep(2)
|
169
193
|
self.send(Command.GET_METHOD_CMD)
|
@@ -186,8 +210,14 @@ class MethodController(TableController):
|
|
186
210
|
"""
|
187
211
|
warnings.warn("This method is not actively maintained.")
|
188
212
|
method_folder = f"{method_name}.M"
|
189
|
-
method_path = os.path.join(
|
190
|
-
|
213
|
+
method_path = os.path.join(
|
214
|
+
self.src, method_folder, "AgilentPumpDriver1.RapidControl.MethodXML.xml"
|
215
|
+
)
|
216
|
+
dad_path = os.path.join(
|
217
|
+
self.src,
|
218
|
+
method_folder,
|
219
|
+
"Agilent1200erDadDriver1.RapidControl.MethodXML.xml",
|
220
|
+
)
|
191
221
|
|
192
222
|
if os.path.exists(os.path.join(self.src, f"{method_name}.M")):
|
193
223
|
parser = XmlParser()
|
@@ -195,25 +225,29 @@ class MethodController(TableController):
|
|
195
225
|
dad = parser.parse(dad_path, DadMethod)
|
196
226
|
|
197
227
|
organic_modifier: Optional[SolventElement] = None
|
198
|
-
aq_modifier: Optional[SolventElement] = None
|
199
228
|
|
200
229
|
if len(method.solvent_composition.solvent_element) == 2:
|
201
230
|
for solvent in method.solvent_composition.solvent_element:
|
202
|
-
if solvent.channel == "
|
203
|
-
aq_modifier = solvent
|
204
|
-
elif solvent.channel == "Channel_B":
|
231
|
+
if solvent.channel == "Channel_B":
|
205
232
|
organic_modifier = solvent
|
206
233
|
|
207
|
-
self.table_state = MethodDetails(
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
234
|
+
self.table_state = MethodDetails(
|
235
|
+
name=method_name,
|
236
|
+
params=HPLCMethodParams(
|
237
|
+
organic_modifier=organic_modifier.percentage, flow=method.flow
|
238
|
+
),
|
239
|
+
stop_time=method.stop_time.stop_time_value,
|
240
|
+
post_time=method.post_time.post_time_value,
|
241
|
+
timetable=[
|
242
|
+
TimeTableEntry(
|
243
|
+
start_time=tte.time,
|
244
|
+
organic_modifer=tte.percent_b,
|
245
|
+
flow=method.flow,
|
246
|
+
)
|
247
|
+
for tte in method.timetable.timetable_entry
|
248
|
+
],
|
249
|
+
dad_wavelengthes=dad.signals.signal,
|
250
|
+
)
|
217
251
|
return self.table_state
|
218
252
|
else:
|
219
253
|
raise FileNotFoundError
|
@@ -225,43 +259,90 @@ class MethodController(TableController):
|
|
225
259
|
:param save: if false only modifies the method, otherwise saves to disk
|
226
260
|
"""
|
227
261
|
self.table_state = updated_method
|
228
|
-
initial_organic_modifier: Param = Param(val=updated_method.params.organic_modifier,
|
229
|
-
chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
|
230
|
-
ptype=PType.NUM)
|
231
|
-
max_time: Param = Param(val=updated_method.stop_time,
|
232
|
-
chemstation_key=RegisterFlag.MAX_TIME,
|
233
|
-
ptype=PType.NUM)
|
234
|
-
post_time: Param = Param(val=updated_method.post_time,
|
235
|
-
chemstation_key=RegisterFlag.POST_TIME,
|
236
|
-
ptype=PType.NUM)
|
237
|
-
flow: Param = Param(val=updated_method.params.flow,
|
238
|
-
chemstation_key=RegisterFlag.FLOW,
|
239
|
-
ptype=PType.NUM)
|
240
|
-
|
241
262
|
# Method settings required for all runs
|
242
|
-
self.update_method_params(
|
243
|
-
|
263
|
+
self.update_method_params(
|
264
|
+
new_flow=updated_method.params.flow,
|
265
|
+
new_initial_om=updated_method.params.organic_modifier,
|
266
|
+
new_stop_time=updated_method.stop_time,
|
267
|
+
new_post_time=updated_method.post_time,
|
268
|
+
)
|
269
|
+
self.edit_method_timetable(updated_method.timetable)
|
244
270
|
|
245
271
|
if save:
|
246
|
-
self.send(
|
247
|
-
|
248
|
-
|
272
|
+
self.send(
|
273
|
+
Command.SAVE_METHOD_CMD.value.format(
|
274
|
+
commit_msg=f"saved method at {str(time.time())}"
|
275
|
+
)
|
276
|
+
)
|
249
277
|
|
250
|
-
def
|
251
|
-
|
278
|
+
def edit_initial_om(self, new_om: Union[int, float]):
|
279
|
+
initial_organic_modifier: Param = Param(
|
280
|
+
val=new_om,
|
281
|
+
chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
|
282
|
+
ptype=PType.NUM,
|
283
|
+
)
|
252
284
|
self._update_param(initial_organic_modifier)
|
285
|
+
|
286
|
+
def edit_flow(self, new_flow: Union[int, float]):
|
287
|
+
flow: Param = Param(
|
288
|
+
val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
|
289
|
+
)
|
253
290
|
self._update_param(flow)
|
291
|
+
|
292
|
+
def edit_stop_time(self, new_stop_time: Union[int, float]):
|
293
|
+
stop_time: Param = Param(
|
294
|
+
val=new_stop_time,
|
295
|
+
chemstation_key=RegisterFlag.MAX_TIME,
|
296
|
+
ptype=PType.NUM,
|
297
|
+
)
|
298
|
+
self._update_param(
|
299
|
+
Param(
|
300
|
+
val="Set", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR
|
301
|
+
)
|
302
|
+
)
|
303
|
+
self._update_param(stop_time)
|
304
|
+
|
305
|
+
def edit_post_time(self, new_post_time: Union[int, float]):
|
306
|
+
post_time: Param = Param(
|
307
|
+
val=new_post_time,
|
308
|
+
chemstation_key=RegisterFlag.POST_TIME,
|
309
|
+
ptype=PType.NUM,
|
310
|
+
)
|
311
|
+
self._update_param(
|
312
|
+
Param(val="Set", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR)
|
313
|
+
)
|
314
|
+
self._update_param(post_time)
|
315
|
+
|
316
|
+
def update_method_params(
|
317
|
+
self,
|
318
|
+
new_flow: Union[int, float],
|
319
|
+
new_initial_om: Union[int, float],
|
320
|
+
new_stop_time: Union[int, float],
|
321
|
+
new_post_time: Union[int, float],
|
322
|
+
):
|
323
|
+
self.delete_table()
|
324
|
+
self.edit_initial_om(new_initial_om)
|
325
|
+
self.edit_flow(new_flow)
|
254
326
|
if self.table_state.stop_time:
|
255
|
-
self.
|
256
|
-
self._update_param(max_time)
|
327
|
+
self.edit_stop_time(new_stop_time)
|
257
328
|
else:
|
258
|
-
self._update_param(
|
329
|
+
self._update_param(
|
330
|
+
Param(
|
331
|
+
val="Off",
|
332
|
+
chemstation_key=RegisterFlag.STOPTIME_MODE,
|
333
|
+
ptype=PType.STR,
|
334
|
+
)
|
335
|
+
)
|
259
336
|
if self.table_state.post_time:
|
260
|
-
self.
|
261
|
-
self._update_param(post_time)
|
337
|
+
self.edit_post_time(new_post_time)
|
262
338
|
else:
|
263
|
-
self._update_param(
|
264
|
-
|
339
|
+
self._update_param(
|
340
|
+
Param(
|
341
|
+
val="Off",
|
342
|
+
chemstation_key=RegisterFlag.POSTIME_MODE,
|
343
|
+
ptype=PType.STR,
|
344
|
+
)
|
345
|
+
)
|
265
346
|
|
266
347
|
def _update_param(self, method_param: Param):
|
267
348
|
"""Change a method parameter, changes what is visibly seen in Chemstation GUI.
|
@@ -270,34 +351,55 @@ class MethodController(TableController):
|
|
270
351
|
:param method_param: a parameter to update for currently loaded method.
|
271
352
|
"""
|
272
353
|
register = self.table_locator.register
|
273
|
-
setting_command =
|
354
|
+
setting_command = (
|
355
|
+
TableOperation.UPDATE_OBJ_HDR_VAL
|
356
|
+
if method_param.ptype == PType.NUM
|
357
|
+
else TableOperation.UPDATE_OBJ_HDR_TEXT
|
358
|
+
)
|
274
359
|
if isinstance(method_param.chemstation_key, list):
|
275
360
|
for register_flag in method_param.chemstation_key:
|
276
|
-
self.send(
|
277
|
-
|
278
|
-
|
361
|
+
self.send(
|
362
|
+
setting_command.value.format(
|
363
|
+
register=register,
|
364
|
+
register_flag=register_flag,
|
365
|
+
val=method_param.val,
|
366
|
+
)
|
367
|
+
)
|
279
368
|
else:
|
280
|
-
self.send(
|
281
|
-
|
282
|
-
|
369
|
+
self.send(
|
370
|
+
setting_command.value.format(
|
371
|
+
register=register,
|
372
|
+
register_flag=method_param.chemstation_key,
|
373
|
+
val=method_param.val,
|
374
|
+
)
|
375
|
+
)
|
283
376
|
time.sleep(2)
|
377
|
+
self.download()
|
284
378
|
|
285
379
|
def download(self):
|
286
|
-
self.send(
|
380
|
+
self.send("Sleep 1")
|
287
381
|
self.sleepy_send("DownloadRCMethod PMP1")
|
288
|
-
self.send(
|
382
|
+
self.send("Sleep 1")
|
289
383
|
|
290
|
-
def
|
384
|
+
def _edit_row(self, row: TimeTableEntry, first_row: bool = False):
|
291
385
|
if first_row:
|
292
386
|
if row.organic_modifer:
|
293
387
|
self.add_row()
|
294
|
-
self.add_new_col_text(
|
388
|
+
self.add_new_col_text(
|
389
|
+
col_name=RegisterFlag.FUNCTION,
|
390
|
+
val=RegisterFlag.SOLVENT_COMPOSITION.value,
|
391
|
+
)
|
295
392
|
self.add_new_col_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
296
|
-
self.add_new_col_num(
|
393
|
+
self.add_new_col_num(
|
394
|
+
col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION,
|
395
|
+
val=row.organic_modifer,
|
396
|
+
)
|
297
397
|
if row.flow:
|
298
398
|
self.add_row()
|
299
399
|
self.get_num_rows()
|
300
|
-
self._edit_row_text(
|
400
|
+
self._edit_row_text(
|
401
|
+
col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value
|
402
|
+
)
|
301
403
|
self.add_new_col_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
|
302
404
|
self._edit_row_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
|
303
405
|
self.download()
|
@@ -305,19 +407,27 @@ class MethodController(TableController):
|
|
305
407
|
if row.organic_modifer:
|
306
408
|
self.add_row()
|
307
409
|
self.get_num_rows()
|
308
|
-
self._edit_row_text(
|
410
|
+
self._edit_row_text(
|
411
|
+
col_name=RegisterFlag.FUNCTION,
|
412
|
+
val=RegisterFlag.SOLVENT_COMPOSITION.value,
|
413
|
+
)
|
309
414
|
self._edit_row_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
310
|
-
self._edit_row_num(
|
415
|
+
self._edit_row_num(
|
416
|
+
col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION,
|
417
|
+
val=row.organic_modifer,
|
418
|
+
)
|
311
419
|
self.download()
|
312
420
|
if row.flow:
|
313
421
|
self.add_row()
|
314
422
|
self.get_num_rows()
|
315
|
-
self._edit_row_text(
|
423
|
+
self._edit_row_text(
|
424
|
+
col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value
|
425
|
+
)
|
316
426
|
self._edit_row_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
|
317
427
|
self._edit_row_num(col_name=RegisterFlag.TIME, val=row.start_time)
|
318
428
|
self.download()
|
319
429
|
|
320
|
-
def
|
430
|
+
def edit_method_timetable(self, timetable_rows: List[TimeTableEntry]):
|
321
431
|
self.get_num_rows()
|
322
432
|
self.delete_table()
|
323
433
|
res = self.get_num_rows()
|
@@ -329,7 +439,7 @@ class MethodController(TableController):
|
|
329
439
|
self.get_num_rows()
|
330
440
|
|
331
441
|
for i, row in enumerate(timetable_rows):
|
332
|
-
self.
|
442
|
+
self._edit_row(row=row, first_row=i == 0)
|
333
443
|
|
334
444
|
def stop(self):
|
335
445
|
"""
|
@@ -337,7 +447,12 @@ class MethodController(TableController):
|
|
337
447
|
"""
|
338
448
|
self.send(Command.STOP_METHOD_CMD)
|
339
449
|
|
340
|
-
def run(
|
450
|
+
def run(
|
451
|
+
self,
|
452
|
+
experiment_name: str,
|
453
|
+
add_timestamp: bool = True,
|
454
|
+
stall_while_running: bool = True,
|
455
|
+
):
|
341
456
|
"""
|
342
457
|
:param experiment_name: Name of the experiment
|
343
458
|
:param stall_while_running: whether to stall or immediately return
|
@@ -349,9 +464,19 @@ class MethodController(TableController):
|
|
349
464
|
tries = 0
|
350
465
|
while tries < 10 and not hplc_is_running:
|
351
466
|
timestamp = time.strftime(TIME_FORMAT)
|
352
|
-
self.send(
|
353
|
-
|
354
|
-
|
467
|
+
self.send(
|
468
|
+
Command.RUN_METHOD_CMD.value.format(
|
469
|
+
data_dir=self.data_dirs[0],
|
470
|
+
experiment_name=f"{experiment_name}_{timestamp}"
|
471
|
+
if add_timestamp
|
472
|
+
else experiment_name,
|
473
|
+
)
|
474
|
+
)
|
475
|
+
folder_name = (
|
476
|
+
f"{experiment_name}_{timestamp}.D"
|
477
|
+
if add_timestamp
|
478
|
+
else f"{experiment_name}.D"
|
479
|
+
)
|
355
480
|
hplc_is_running = self.check_hplc_is_running()
|
356
481
|
tries += 1
|
357
482
|
|
@@ -377,27 +502,35 @@ class MethodController(TableController):
|
|
377
502
|
warning = f"Data folder {self.data_files[-1]} may not exist, returning and will check again after run is done."
|
378
503
|
warnings.warn(warning)
|
379
504
|
|
380
|
-
|
381
505
|
def fuzzy_match_most_recent_folder(self, most_recent_folder: T) -> Result[T, str]:
|
382
506
|
if os.path.exists(most_recent_folder):
|
383
507
|
return Ok(most_recent_folder)
|
384
508
|
return Err("Folder not found!")
|
385
509
|
|
386
|
-
def get_data(
|
510
|
+
def get_data(
|
511
|
+
self, custom_path: Optional[str] = None
|
512
|
+
) -> AgilentChannelChromatogramData:
|
387
513
|
custom_path = custom_path if custom_path else self.data_files[-1]
|
388
514
|
self.get_spectrum_at_channels(custom_path)
|
389
515
|
return AgilentChannelChromatogramData(**self.spectra)
|
390
516
|
|
391
|
-
def get_data_uv(
|
517
|
+
def get_data_uv(
|
518
|
+
self, custom_path: Optional[str] = None
|
519
|
+
) -> Dict[str, AgilentHPLCChromatogram]:
|
392
520
|
custom_path = custom_path if custom_path else self.data_files[-1]
|
393
521
|
self.get_uv_spectrum(custom_path)
|
394
522
|
return self.uv
|
395
523
|
|
396
|
-
def get_report(
|
397
|
-
|
524
|
+
def get_report(
|
525
|
+
self,
|
526
|
+
custom_path: Optional[str] = None,
|
527
|
+
report_type: ReportType = ReportType.TXT,
|
528
|
+
) -> List[AgilentReport]:
|
398
529
|
custom_path = self.data_files[-1] if not custom_path else custom_path
|
399
530
|
metd_report = self.get_report_details(custom_path, report_type)
|
400
|
-
chrom_data: List[AgilentHPLCChromatogram] = list(
|
531
|
+
chrom_data: List[AgilentHPLCChromatogram] = list(
|
532
|
+
self.get_data(custom_path).__dict__.values()
|
533
|
+
)
|
401
534
|
for i, signal in enumerate(metd_report.signals):
|
402
535
|
possible_data = chrom_data[i]
|
403
536
|
if len(possible_data.x) > 0:
|
@@ -2,13 +2,14 @@ from typing import Union
|
|
2
2
|
|
3
3
|
from ....control.controllers import CommunicationController
|
4
4
|
from ....control.controllers.tables.table import TableController
|
5
|
-
from
|
5
|
+
from pychemstation.analysis.chromatogram import AgilentChannelChromatogramData
|
6
6
|
from ....utils.table_types import Table
|
7
7
|
|
8
8
|
|
9
9
|
class MassSpecController(TableController):
|
10
|
-
|
11
|
-
|
10
|
+
def __init__(
|
11
|
+
self, controller: CommunicationController, src: str, data_dir: str, table: Table
|
12
|
+
):
|
12
13
|
super().__init__(controller, src, data_dir, table)
|
13
14
|
|
14
15
|
def get_row(self, row: int):
|
@@ -17,5 +18,7 @@ class MassSpecController(TableController):
|
|
17
18
|
def retrieve_recent_data_files(self):
|
18
19
|
pass
|
19
20
|
|
20
|
-
def get_data(
|
21
|
+
def get_data(
|
22
|
+
self,
|
23
|
+
) -> Union[list[AgilentChannelChromatogramData], AgilentChannelChromatogramData]:
|
21
24
|
pass
|