pychemstation 0.4.7.dev3__tar.gz → 0.5.0__tar.gz
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-0.4.7.dev3 → pychemstation-0.5.0}/PKG-INFO +14 -11
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/README.md +13 -10
- pychemstation-0.5.0/pychemstation/control/__init__.py +5 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/control/comm.py +29 -130
- pychemstation-0.5.0/pychemstation/control/hplc.py +150 -0
- {pychemstation-0.4.7.dev3/pychemstation/control → pychemstation-0.5.0/pychemstation/control/table}/__init__.py +1 -4
- {pychemstation-0.4.7.dev3/pychemstation/control → pychemstation-0.5.0/pychemstation/control/table}/method.py +68 -42
- {pychemstation-0.4.7.dev3/pychemstation/control → pychemstation-0.5.0/pychemstation/control/table}/sequence.py +64 -34
- pychemstation-0.5.0/pychemstation/control/table/table_controller.py +137 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/chromatogram.py +6 -5
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/macro.py +1 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/method_types.py +4 -6
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/sequence_types.py +19 -5
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation.egg-info/PKG-INFO +14 -11
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation.egg-info/SOURCES.txt +10 -4
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation.egg-info/top_level.txt +1 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/setup.py +1 -1
- pychemstation-0.5.0/tests/__init__.py +0 -0
- pychemstation-0.5.0/tests/constants.py +12 -0
- pychemstation-0.5.0/tests/test_comm.py +66 -0
- pychemstation-0.5.0/tests/test_method.py +64 -0
- pychemstation-0.5.0/tests/test_sequence.py +102 -0
- pychemstation-0.4.7.dev3/pychemstation/control/table_controller.py +0 -75
- pychemstation-0.4.7.dev3/tests/test_chemstation_integration.py +0 -193
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/LICENSE +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/__init__.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/analysis/__init__.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/analysis/base_spectrum.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/analysis/spec_utils.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/analysis/utils.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/generated/__init__.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/generated/dad_method.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/generated/pump_method.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/__init__.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/constants.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/parsing.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation/utils/table_types.py +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation.egg-info/dependency_links.txt +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pychemstation.egg-info/requires.txt +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/pyproject.toml +0 -0
- {pychemstation-0.4.7.dev3 → pychemstation-0.5.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pychemstation
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.0
|
4
4
|
Summary: Library to interact with Chemstation software, primarily used in Hein lab
|
5
5
|
Home-page: https://gitlab.com/heingroup/pychemstation
|
6
6
|
Author: Lucy Hao
|
@@ -13,6 +13,8 @@ License-File: LICENSE
|
|
13
13
|
Requires-Dist: polling
|
14
14
|
Requires-Dist: seabreeze
|
15
15
|
|
16
|
+
from tests.test_chemstation_integration import SEQUENCE_DIR
|
17
|
+
|
16
18
|
# Agilent HPLC Macro Control
|
17
19
|
|
18
20
|

|
@@ -59,26 +61,27 @@ HPLCTalk_Run
|
|
59
61
|
## Example Usage
|
60
62
|
|
61
63
|
```python
|
62
|
-
from pychemstation.control import HPLCController
|
64
|
+
from pychemstation.control import HPLCController
|
63
65
|
import pandas as pd
|
64
66
|
|
65
67
|
# these paths will be unique to your Chemstation setup
|
68
|
+
DEFAULT_COMMAND_PATH = "C:\\Users\\User\\Desktop\\Lucy\\"
|
69
|
+
DEFAULT_METHOD = "GENERAL-POROSHELL"
|
66
70
|
DEFAULT_METHOD_DIR = "C:\\ChemStation\\1\\Methods\\"
|
67
71
|
DATA_DIR = "C:\\Users\\Public\\Documents\\ChemStation\\2\\Data"
|
68
|
-
|
72
|
+
SEQUENCE_DIR = "C:\\USERS\\PUBLIC\\DOCUMENTS\\CHEMSTATION\\2\\Sequence"
|
69
73
|
|
70
74
|
hplc_controller = HPLCController(data_dir=DATA_DIR,
|
71
|
-
comm_dir=DEFAULT_COMMAND_PATH
|
72
|
-
|
73
|
-
|
75
|
+
comm_dir=DEFAULT_COMMAND_PATH,
|
76
|
+
sequence_dir=SEQUENCE_DIR,
|
77
|
+
method_dir=DEFAULT_METHOD_DIR)
|
74
78
|
|
75
79
|
hplc_controller.preprun()
|
76
|
-
|
77
|
-
|
78
|
-
|
80
|
+
hplc_controller.switch_method(method_name=DEFAULT_METHOD)
|
81
|
+
hplc_controller.run_method(experiment_name="Run 10")
|
82
|
+
data_status_valid, chrom = hplc_controller.get_last_run_method_data()
|
79
83
|
|
80
|
-
if
|
81
|
-
chrom = method_controller.get_data()
|
84
|
+
if data_status_valid:
|
82
85
|
# afterwards, save, analyze or plot the data!
|
83
86
|
values = {"x": chrom.x, "y": chrom.y}
|
84
87
|
chromatogram_data = pd.DataFrame.from_dict(values)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from tests.test_chemstation_integration import SEQUENCE_DIR
|
2
|
+
|
1
3
|
# Agilent HPLC Macro Control
|
2
4
|
|
3
5
|

|
@@ -44,26 +46,27 @@ HPLCTalk_Run
|
|
44
46
|
## Example Usage
|
45
47
|
|
46
48
|
```python
|
47
|
-
from pychemstation.control import HPLCController
|
49
|
+
from pychemstation.control import HPLCController
|
48
50
|
import pandas as pd
|
49
51
|
|
50
52
|
# these paths will be unique to your Chemstation setup
|
53
|
+
DEFAULT_COMMAND_PATH = "C:\\Users\\User\\Desktop\\Lucy\\"
|
54
|
+
DEFAULT_METHOD = "GENERAL-POROSHELL"
|
51
55
|
DEFAULT_METHOD_DIR = "C:\\ChemStation\\1\\Methods\\"
|
52
56
|
DATA_DIR = "C:\\Users\\Public\\Documents\\ChemStation\\2\\Data"
|
53
|
-
|
57
|
+
SEQUENCE_DIR = "C:\\USERS\\PUBLIC\\DOCUMENTS\\CHEMSTATION\\2\\Sequence"
|
54
58
|
|
55
59
|
hplc_controller = HPLCController(data_dir=DATA_DIR,
|
56
|
-
comm_dir=DEFAULT_COMMAND_PATH
|
57
|
-
|
58
|
-
|
60
|
+
comm_dir=DEFAULT_COMMAND_PATH,
|
61
|
+
sequence_dir=SEQUENCE_DIR,
|
62
|
+
method_dir=DEFAULT_METHOD_DIR)
|
59
63
|
|
60
64
|
hplc_controller.preprun()
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
hplc_controller.switch_method(method_name=DEFAULT_METHOD)
|
66
|
+
hplc_controller.run_method(experiment_name="Run 10")
|
67
|
+
data_status_valid, chrom = hplc_controller.get_last_run_method_data()
|
64
68
|
|
65
|
-
if
|
66
|
-
chrom = method_controller.get_data()
|
69
|
+
if data_status_valid:
|
67
70
|
# afterwards, save, analyze or plot the data!
|
68
71
|
values = {"x": chrom.x, "y": chrom.y}
|
69
72
|
chromatogram_data = pd.DataFrame.from_dict(values)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
"""
|
2
|
-
Module to provide API for the
|
2
|
+
Module to provide API for the communication with Agilent HPLC systems.
|
3
3
|
|
4
4
|
HPLCController sends commands to Chemstation software via a command file.
|
5
5
|
Answers are received via reply file. On the Chemstation side, a custom
|
@@ -10,38 +10,29 @@ been processed.
|
|
10
10
|
Authors: Alexander Hammer, Hessam Mehr, Lucy Hao
|
11
11
|
"""
|
12
12
|
|
13
|
-
import logging
|
14
13
|
import os
|
15
14
|
import time
|
16
15
|
|
17
|
-
import polling
|
18
|
-
|
19
|
-
from ..utils.chromatogram import AgilentHPLCChromatogram
|
20
16
|
from ..utils.constants import MAX_CMD_NO
|
21
17
|
from ..utils.macro import *
|
22
18
|
from ..utils.method_types import *
|
23
19
|
|
24
20
|
|
25
|
-
class
|
21
|
+
class CommunicationController:
|
26
22
|
"""
|
27
|
-
Class
|
23
|
+
Class that communicates with Agilent using Macros
|
28
24
|
"""
|
29
25
|
|
30
26
|
def __init__(
|
31
27
|
self,
|
32
28
|
comm_dir: str,
|
33
|
-
data_dir: str,
|
34
29
|
cmd_file: str = "cmd",
|
35
30
|
reply_file: str = "reply",
|
36
31
|
):
|
37
|
-
"""
|
38
|
-
|
39
|
-
|
40
|
-
:param comm_dir: Name of directory for communication, where ChemStation will read and write from. Can be any existing directory.
|
41
|
-
:param data_dir: Name of directory that ChemStation saves run data. Must be accessible by ChemStation.
|
32
|
+
"""
|
33
|
+
:param comm_dir:
|
42
34
|
:param cmd_file: Name of command file
|
43
35
|
:param reply_file: Name of reply file
|
44
|
-
:raises FileNotFoundError: If either `data_dir`, `method_dir` or `comm_dir` is not a valid directory.
|
45
36
|
"""
|
46
37
|
if os.path.isdir(comm_dir):
|
47
38
|
self.cmd_file = os.path.join(comm_dir, cmd_file)
|
@@ -51,75 +42,47 @@ class HPLCController:
|
|
51
42
|
raise FileNotFoundError(f"comm_dir: {comm_dir} not found.")
|
52
43
|
self._most_recent_hplc_status = None
|
53
44
|
|
54
|
-
if os.path.isdir(data_dir):
|
55
|
-
self.data_dir = data_dir
|
56
|
-
else:
|
57
|
-
raise FileNotFoundError(f"data_dir: {data_dir} not found.")
|
58
|
-
|
59
|
-
self.spectra = {
|
60
|
-
"A": AgilentHPLCChromatogram(self.data_dir),
|
61
|
-
"B": AgilentHPLCChromatogram(self.data_dir),
|
62
|
-
"C": AgilentHPLCChromatogram(self.data_dir),
|
63
|
-
"D": AgilentHPLCChromatogram(self.data_dir),
|
64
|
-
}
|
65
|
-
|
66
|
-
self.data_files: list[str] = []
|
67
|
-
self.internal_variables: list[dict[str, str]] = []
|
68
|
-
|
69
45
|
# Create files for Chemstation to communicate with Python
|
70
46
|
open(self.cmd_file, "a").close()
|
71
47
|
open(self.reply_file, "a").close()
|
72
48
|
|
73
|
-
self.logger = logging.getLogger("hplc_logger")
|
74
|
-
self.logger.addHandler(logging.NullHandler())
|
75
|
-
|
76
49
|
self.reset_cmd_counter()
|
77
50
|
|
78
|
-
|
51
|
+
def get_status(self) -> list[Union[HPLCRunningStatus, HPLCAvailStatus, HPLCErrorStatus]]:
|
52
|
+
"""Get device status(es).
|
53
|
+
|
54
|
+
:return: list of ChemStation's current status
|
55
|
+
"""
|
56
|
+
self.send(Command.GET_STATUS_CMD)
|
57
|
+
time.sleep(1)
|
58
|
+
|
59
|
+
try:
|
60
|
+
parsed_response = self.receive().splitlines()[1].split()[1:]
|
61
|
+
recieved_status = [str_to_status(res) for res in parsed_response]
|
62
|
+
self._most_recent_hplc_status = recieved_status[0]
|
63
|
+
return recieved_status
|
64
|
+
except IOError:
|
65
|
+
return [HPLCErrorStatus.NORESPONSE]
|
66
|
+
except IndexError:
|
67
|
+
return [HPLCErrorStatus.MALFORMED]
|
79
68
|
|
80
|
-
def
|
69
|
+
def set_status(self):
|
81
70
|
"""Updates current status of HPLC machine"""
|
82
|
-
self._most_recent_hplc_status = self.
|
71
|
+
self._most_recent_hplc_status = self.get_status()[0]
|
83
72
|
|
84
|
-
def _check_data_status(self) -> bool:
|
73
|
+
def _check_data_status(self, data_path: str) -> bool:
|
85
74
|
"""Checks if HPLC machine is in an available state, meaning a state that data is not being written.
|
86
75
|
|
87
76
|
:return: whether the HPLC machine is in a safe state to retrieve data back."""
|
88
77
|
old_status = self._most_recent_hplc_status
|
89
|
-
self.
|
90
|
-
file_exists = os.path.exists(
|
78
|
+
self.set_status()
|
79
|
+
file_exists = os.path.exists(data_path)
|
91
80
|
done_writing_data = isinstance(self._most_recent_hplc_status,
|
92
81
|
HPLCAvailStatus) and old_status != self._most_recent_hplc_status and file_exists
|
93
82
|
return done_writing_data
|
94
83
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
:param method: if you are running a method and want to read back data, the timeout period will be adjusted to be longer than the method's runtime
|
99
|
-
|
100
|
-
:return: Return True if data can be read back, else False.
|
101
|
-
"""
|
102
|
-
self._set_status()
|
103
|
-
|
104
|
-
timeout = 10 * 60
|
105
|
-
hplc_run_done = polling.poll(
|
106
|
-
lambda: self._check_data_status(),
|
107
|
-
timeout=timeout,
|
108
|
-
step=30
|
109
|
-
)
|
110
|
-
|
111
|
-
return hplc_run_done
|
112
|
-
|
113
|
-
def get_spectrum(self):
|
114
|
-
""" Load last chromatogram for any channel in spectra dictionary."""
|
115
|
-
last_file = self.data_files[-1] if len(self.data_files) > 0 else None
|
116
|
-
|
117
|
-
if last_file is None:
|
118
|
-
raise IndexError
|
119
|
-
|
120
|
-
for channel, spec in self.controller.spectra.items():
|
121
|
-
spec.load_spectrum(data_path=last_file, channel=channel)
|
122
|
-
self.logger.info("%s chromatogram loaded.", channel)
|
84
|
+
def check_data(self, data_path: str) -> bool:
|
85
|
+
return self._check_data_status(data_path)
|
123
86
|
|
124
87
|
def _send(self, cmd: str, cmd_no: int, num_attempts=5) -> None:
|
125
88
|
"""Low-level execution primitive. Sends a command string to HPLC.
|
@@ -137,10 +100,8 @@ class HPLCController:
|
|
137
100
|
cmd_file.write(f"{cmd_no} {cmd}")
|
138
101
|
except IOError as e:
|
139
102
|
err = e
|
140
|
-
self.logger.warning("Failed to send command; trying again.")
|
141
103
|
continue
|
142
104
|
else:
|
143
|
-
self.logger.info("Sent command #%d: %s.", cmd_no, cmd)
|
144
105
|
return
|
145
106
|
else:
|
146
107
|
raise IOError(f"Failed to send command #{cmd_no}: {cmd}.") from err
|
@@ -162,7 +123,6 @@ class HPLCController:
|
|
162
123
|
response = reply_file.read()
|
163
124
|
except OSError as e:
|
164
125
|
err = e
|
165
|
-
self.logger.warning("Failed to read from reply file; trying again.")
|
166
126
|
continue
|
167
127
|
|
168
128
|
try:
|
@@ -170,19 +130,12 @@ class HPLCController:
|
|
170
130
|
response_no = int(first_line.split()[0])
|
171
131
|
except IndexError as e:
|
172
132
|
err = e
|
173
|
-
self.logger.warning("Malformed response %s; trying again.", response)
|
174
133
|
continue
|
175
134
|
|
176
135
|
# check that response corresponds to sent command
|
177
136
|
if response_no == cmd_no:
|
178
|
-
self.logger.info("Reply: \n%s", response)
|
179
137
|
return response
|
180
138
|
else:
|
181
|
-
self.logger.warning(
|
182
|
-
"Response #: %d != command #: %d; trying again.",
|
183
|
-
response_no,
|
184
|
-
cmd_no,
|
185
|
-
)
|
186
139
|
continue
|
187
140
|
else:
|
188
141
|
raise IOError(f"Failed to receive reply to command #{cmd_no}.") from err
|
@@ -217,60 +170,6 @@ class HPLCController:
|
|
217
170
|
self._receive(cmd_no=MAX_CMD_NO + 1)
|
218
171
|
self.cmd_no = 0
|
219
172
|
|
220
|
-
self.logger.debug("Reset command counter")
|
221
|
-
|
222
|
-
def sleep(self, seconds: int):
|
223
|
-
"""Tells the HPLC to wait for a specified number of seconds.
|
224
|
-
|
225
|
-
:param seconds: number of seconds to wait
|
226
|
-
"""
|
227
|
-
self.send(Command.SLEEP_CMD.value.format(seconds=seconds))
|
228
|
-
self.logger.debug("Sleep command sent.")
|
229
|
-
|
230
|
-
def standby(self):
|
231
|
-
"""Switches all modules in standby mode. All lamps and pumps are switched off."""
|
232
|
-
self.send(Command.STANDBY_CMD)
|
233
|
-
self.logger.debug("Standby command sent.")
|
234
|
-
|
235
|
-
def preprun(self):
|
236
|
-
""" Prepares all modules for run. All lamps and pumps are switched on."""
|
237
|
-
self.send(Command.PREPRUN_CMD)
|
238
|
-
self.logger.debug("PrepRun command sent.")
|
239
|
-
|
240
|
-
def status(self) -> list[Union[HPLCRunningStatus, HPLCAvailStatus, HPLCErrorStatus]]:
|
241
|
-
"""Get device status(es).
|
242
|
-
|
243
|
-
:return: list of ChemStation's current status
|
244
|
-
"""
|
245
|
-
self.send(Command.GET_STATUS_CMD)
|
246
|
-
time.sleep(1)
|
247
|
-
|
248
|
-
try:
|
249
|
-
parsed_response = self.receive().splitlines()[1].split()[1:]
|
250
|
-
except IOError:
|
251
|
-
return [HPLCErrorStatus.NORESPONSE]
|
252
|
-
except IndexError:
|
253
|
-
return [HPLCErrorStatus.MALFORMED]
|
254
|
-
recieved_status = [str_to_status(res) for res in parsed_response]
|
255
|
-
self._most_recent_hplc_status = recieved_status[0]
|
256
|
-
return recieved_status
|
257
|
-
|
258
173
|
def stop_macro(self):
|
259
174
|
"""Stops Macro execution. Connection will be lost."""
|
260
175
|
self.send(Command.STOP_MACRO_CMD)
|
261
|
-
|
262
|
-
def lamp_on(self):
|
263
|
-
"""Turns the UV lamp on."""
|
264
|
-
self.send(Command.LAMP_ON_CMD)
|
265
|
-
|
266
|
-
def lamp_off(self):
|
267
|
-
"""Turns the UV lamp off."""
|
268
|
-
self.send(Command.LAMP_OFF_CMD)
|
269
|
-
|
270
|
-
def pump_on(self):
|
271
|
-
"""Turns on the pump on."""
|
272
|
-
self.send(Command.PUMP_ON_CMD)
|
273
|
-
|
274
|
-
def pump_off(self):
|
275
|
-
"""Turns the pump off."""
|
276
|
-
self.send(Command.PUMP_OFF_CMD)
|
@@ -0,0 +1,150 @@
|
|
1
|
+
"""
|
2
|
+
Module to provide API for higher-level HPLC actions.
|
3
|
+
|
4
|
+
Authors: Lucy Hao
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Union, Optional
|
8
|
+
|
9
|
+
from ..control import CommunicationController
|
10
|
+
from ..control.table import MethodController, SequenceController
|
11
|
+
from ..utils.chromatogram import AgilentHPLCChromatogram
|
12
|
+
from ..utils.macro import Command, HPLCRunningStatus, HPLCAvailStatus, HPLCErrorStatus
|
13
|
+
from ..utils.method_types import MethodTimetable
|
14
|
+
from ..utils.sequence_types import SequenceTable, SequenceEntry
|
15
|
+
|
16
|
+
|
17
|
+
class HPLCController:
|
18
|
+
def __init__(self,
|
19
|
+
comm_dir: str,
|
20
|
+
data_dir: str,
|
21
|
+
method_dir: str,
|
22
|
+
sequence_dir: str):
|
23
|
+
"""Initialize HPLC controller. The `hplc_talk.mac` macro file must be loaded in the Chemstation software.
|
24
|
+
`comm_dir` must match the file path in the macro file.
|
25
|
+
|
26
|
+
:param comm_dir: Name of directory for communication, where ChemStation will read and write from. Can be any existing directory.
|
27
|
+
:raises FileNotFoundError: If either `data_dir`, `method_dir` or `comm_dir` is not a valid directory.
|
28
|
+
"""
|
29
|
+
self.comm = CommunicationController(comm_dir=comm_dir)
|
30
|
+
self.method_controller = MethodController(controller=self.comm, src=method_dir, data_dir=data_dir)
|
31
|
+
self.sequence_controller = SequenceController(controller=self.comm, src=sequence_dir, data_dir=data_dir)
|
32
|
+
|
33
|
+
def send(self, cmd: Union[Command, str]):
|
34
|
+
self.comm.send(cmd)
|
35
|
+
|
36
|
+
def receive(self) -> str:
|
37
|
+
return self.comm.receive()
|
38
|
+
|
39
|
+
def status(self) -> list[HPLCRunningStatus | HPLCAvailStatus | HPLCErrorStatus]:
|
40
|
+
return self.comm.get_status()
|
41
|
+
|
42
|
+
def switch_method(self, method_name: str):
|
43
|
+
"""
|
44
|
+
Allows the user to switch between pre-programmed methods. No need to append '.M'
|
45
|
+
to the end of the method name. For example. for the method named 'General-Poroshell.M',
|
46
|
+
only 'General-Poroshell' is needed.
|
47
|
+
|
48
|
+
:param method_name: any available method in Chemstation method directory
|
49
|
+
:raise IndexError: Response did not have expected format. Try again.
|
50
|
+
:raise AssertionError: The desired method is not selected. Try again.
|
51
|
+
"""
|
52
|
+
self.method_controller.switch(method_name)
|
53
|
+
|
54
|
+
def switch_sequence(self, sequence_name: str):
|
55
|
+
"""
|
56
|
+
Allows the user to switch between pre-programmed sequences. The sequence name does not need the '.S' extension.
|
57
|
+
For example. for the method named 'mySeq.S', only 'mySeq' is needed.
|
58
|
+
|
59
|
+
:param seq_name: The name of the sequence file
|
60
|
+
"""
|
61
|
+
self.sequence_controller.switch(sequence_name)
|
62
|
+
|
63
|
+
def run_method(self, experiment_name: str):
|
64
|
+
"""
|
65
|
+
This is the preferred method to trigger a run.
|
66
|
+
Starts the currently selected method, storing data
|
67
|
+
under the <data_dir>/<experiment_name>.D folder.
|
68
|
+
The <experiment_name> will be appended with a timestamp in the '%Y-%m-%d-%H-%M' format.
|
69
|
+
Device must be ready.
|
70
|
+
|
71
|
+
:param experiment_name: Name of the experiment
|
72
|
+
"""
|
73
|
+
self.method_controller.run(experiment_name)
|
74
|
+
|
75
|
+
def run_sequence(self, sequence_table: SequenceTable):
|
76
|
+
"""
|
77
|
+
Starts the currently loaded sequence, storing data
|
78
|
+
under the <data_dir>/<sequence table name> folder.
|
79
|
+
Device must be ready.
|
80
|
+
|
81
|
+
:param sequence_table:
|
82
|
+
"""
|
83
|
+
self.sequence_controller.run(sequence_table)
|
84
|
+
|
85
|
+
def edit_method(self, updated_method: MethodTimetable):
|
86
|
+
"""Updated the currently loaded method in ChemStation with provided values.
|
87
|
+
|
88
|
+
:param updated_method: the method with updated values, to be sent to Chemstation to modify the currently loaded method.
|
89
|
+
"""
|
90
|
+
self.method_controller.edit(updated_method)
|
91
|
+
|
92
|
+
def edit_sequence(self, updated_sequence: SequenceTable):
|
93
|
+
"""
|
94
|
+
Updates the currently loaded sequence table with the provided table. This method will delete the existing sequence table and remake it.
|
95
|
+
If you would only like to edit a single row of a sequence table, use `edit_sequence_row` instead.
|
96
|
+
|
97
|
+
:param sequence_table:
|
98
|
+
"""
|
99
|
+
self.sequence_controller.edit(updated_sequence)
|
100
|
+
|
101
|
+
def edit_sequence_row(self, row: SequenceEntry, num: int):
|
102
|
+
"""
|
103
|
+
Edits a row in the sequence table. Assumes the row already exists.
|
104
|
+
|
105
|
+
:param row: sequence row entry with updated information
|
106
|
+
:param row_num: the row to edit, based on -1-based indexing
|
107
|
+
"""
|
108
|
+
self.sequence_controller.edit_row(row, num)
|
109
|
+
|
110
|
+
def get_last_run_method_data(self) -> Optional[dict[str, AgilentHPLCChromatogram]]:
|
111
|
+
"""
|
112
|
+
Returns the last run method data.
|
113
|
+
"""
|
114
|
+
data_valid, data = self.method_controller.get_data()
|
115
|
+
if data_valid:
|
116
|
+
return data
|
117
|
+
return None
|
118
|
+
|
119
|
+
def get_last_run_sequence_data(self) -> Optional[list[dict[str, AgilentHPLCChromatogram]]]:
|
120
|
+
"""
|
121
|
+
Returns data for all rows in the last run sequence data.
|
122
|
+
"""
|
123
|
+
data_valid, data = self.sequence_controller.get_data()
|
124
|
+
if data_valid:
|
125
|
+
return data
|
126
|
+
return None
|
127
|
+
|
128
|
+
def standby(self):
|
129
|
+
"""Switches all modules in standby mode. All lamps and pumps are switched off."""
|
130
|
+
self.send(Command.STANDBY_CMD)
|
131
|
+
|
132
|
+
def preprun(self):
|
133
|
+
""" Prepares all modules for run. All lamps and pumps are switched on."""
|
134
|
+
self.send(Command.PREPRUN_CMD)
|
135
|
+
|
136
|
+
def lamp_on(self):
|
137
|
+
"""Turns the UV lamp on."""
|
138
|
+
self.send(Command.LAMP_ON_CMD)
|
139
|
+
|
140
|
+
def lamp_off(self):
|
141
|
+
"""Turns the UV lamp off."""
|
142
|
+
self.send(Command.LAMP_OFF_CMD)
|
143
|
+
|
144
|
+
def pump_on(self):
|
145
|
+
"""Turns on the pump on."""
|
146
|
+
self.send(Command.PUMP_ON_CMD)
|
147
|
+
|
148
|
+
def pump_off(self):
|
149
|
+
"""Turns the pump off."""
|
150
|
+
self.send(Command.PUMP_OFF_CMD)
|