pychemstation 0.5.1__py3-none-any.whl → 0.5.3.dev1__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.
@@ -8,10 +8,10 @@ import time
8
8
  from .table_controller import TableController
9
9
  from ...control import CommunicationController
10
10
  from ...utils.chromatogram import SEQUENCE_TIME_FORMAT, AgilentHPLCChromatogram
11
- from ...utils.constants import SEQUENCE_TABLE
12
11
  from ...utils.macro import Command
13
- from ...utils.sequence_types import SequenceTable, SequenceEntry, SequenceDataFiles
14
- from ...utils.table_types import TableOperation, RegisterFlag
12
+ from ...utils.sequence_types import SequenceTable, SequenceEntry, SequenceDataFiles, InjectionSource, SampleType
13
+ from ...utils.table_types import TableOperation, RegisterFlag, Table
14
+ from ...utils.tray_types import TenColumn
15
15
 
16
16
 
17
17
  class SequenceController(TableController):
@@ -19,8 +19,36 @@ class SequenceController(TableController):
19
19
  Class containing sequence related logic
20
20
  """
21
21
 
22
- def __init__(self, controller: CommunicationController, src: str, data_dir: str):
23
- super().__init__(controller, src, data_dir)
22
+ def __init__(self, controller: CommunicationController, src: str, data_dir: str, table: Table, method_dir: str):
23
+ self.method_dir = method_dir
24
+ super().__init__(controller, src, data_dir, table)
25
+
26
+ def load(self) -> SequenceTable:
27
+ rows = self.get_num_rows()
28
+ self.send(Command.GET_SEQUENCE_CMD)
29
+ seq_name = self.receive()
30
+
31
+ if rows.is_ok() and seq_name.is_ok():
32
+ return SequenceTable(
33
+ name=seq_name.ok_value.num_response,
34
+ rows=[self.get_row(r + 1) for r in range(int(rows.ok_value.num_response))])
35
+ raise RuntimeError(rows.err_value)
36
+
37
+ def get_row(self, row: int) -> SequenceEntry:
38
+ sample_name = self.get_text(row, RegisterFlag.NAME)
39
+ vial_location = int(self.get_num(row, RegisterFlag.VIAL_LOCATION))
40
+ method = self.get_text(row, RegisterFlag.METHOD)
41
+ num_inj = int(self.get_num(row, RegisterFlag.NUM_INJ))
42
+ inj_vol = int(self.get_text(row, RegisterFlag.INJ_VOL))
43
+ inj_source = InjectionSource(self.get_text(row, RegisterFlag.INJ_SOR))
44
+ sample_type = SampleType(self.get_num(row, RegisterFlag.SAMPLE_TYPE))
45
+ return SequenceEntry(sample_name=sample_name,
46
+ vial_location=vial_location,
47
+ method=None if len(method) == 0 else method,
48
+ num_inj=num_inj,
49
+ inj_vol=inj_vol,
50
+ inj_source=inj_source,
51
+ sample_type=sample_type, )
24
52
 
25
53
  def switch(self, seq_name: str):
26
54
  """
@@ -34,13 +62,7 @@ class SequenceController(TableController):
34
62
  time.sleep(2)
35
63
  self.send(Command.GET_SEQUENCE_CMD)
36
64
  time.sleep(2)
37
- # check that method switched
38
- for _ in range(10):
39
- try:
40
- parsed_response = self.receive().splitlines()[1].split()[1:][0]
41
- break
42
- except IndexError:
43
- continue
65
+ parsed_response = self.receive().value.string_response
44
66
 
45
67
  assert parsed_response == f"{seq_name}.S", "Switching sequence failed."
46
68
 
@@ -53,85 +75,108 @@ class SequenceController(TableController):
53
75
  """
54
76
  self.send("Local Rows")
55
77
  self.sleep(1)
56
- self.delete_table(SEQUENCE_TABLE)
78
+ self.delete_table()
57
79
  self.sleep(1)
58
- self.new_table(SEQUENCE_TABLE)
80
+ self.new_table()
59
81
  self.sleep(1)
60
- self._get_table_rows(SEQUENCE_TABLE)
61
-
62
- for _ in sequence_table.rows:
63
- self.add_table_row(SEQUENCE_TABLE)
64
- self.sleep(1)
82
+ self.get_num_rows()
83
+
84
+ if True:
85
+ for _ in sequence_table.rows:
86
+ self.add_row()
87
+ self.sleep(1)
88
+ self.send(Command.SAVE_SEQUENCE_CMD)
89
+ self.get_num_rows()
65
90
  self.send(Command.SAVE_SEQUENCE_CMD)
66
- self._get_table_rows(SEQUENCE_TABLE)
67
- self.send(Command.SAVE_SEQUENCE_CMD)
68
- self.send(Command.SWITCH_SEQUENCE_CMD)
69
-
70
- for i, row in enumerate(sequence_table.rows):
71
- self.edit_row(row=row, row_num=i + 1)
72
- self.sleep(1)
73
- self.send(Command.SAVE_SEQUENCE_CMD)
74
-
91
+ for i, row in enumerate(sequence_table.rows):
92
+ self.edit_row(row=row, row_num=i + 1)
93
+ self.sleep(1)
94
+ self.send(Command.SAVE_SEQUENCE_CMD)
95
+ else:
96
+ for i, row in enumerate(sequence_table.rows):
97
+ self.add_row()
98
+ self.sleep(0.1)
99
+ self.edit_row(row=row, row_num=i + 1)
100
+ self.sleep(0.1)
101
+ rows = self.get_num_rows()
102
+ self.send(Command.SAVE_SEQUENCE_CMD)
103
+ self.send(Command.SWITCH_SEQUENCE_CMD)
75
104
 
76
105
  def edit_row(self, row: SequenceEntry, row_num: int):
77
106
  """
78
- Edits a row in the sequence table. Assumes the row already exists.
107
+ Edits a row in the sequence table. If a row does NOT exist, a new one will be created.
79
108
 
80
109
  :param row: sequence row entry with updated information
81
- :param row_num: the row to edit, based on -1-based indexing
110
+ :param row_num: the row to edit, based on 1-based indexing
82
111
  """
112
+ num_rows = self.get_num_rows()
113
+ if num_rows.is_ok():
114
+ while num_rows.ok_value.num_response < row_num:
115
+ self.add_row()
116
+ self.send(Command.SAVE_SEQUENCE_CMD)
117
+ num_rows = self.get_num_rows()
118
+
119
+ table_register = self.table.register
120
+ table_name = self.table.name
121
+
83
122
  if row.vial_location:
84
- self.sleepy_send(TableOperation.EDIT_ROW_VAL.value.format(register=SEQUENCE_TABLE.register,
85
- table_name=SEQUENCE_TABLE.name,
123
+ self.sleepy_send(TableOperation.EDIT_ROW_VAL.value.format(register=table_register,
124
+ table_name=table_name,
86
125
  row=row_num,
87
126
  col_name=RegisterFlag.VIAL_LOCATION,
88
- val=row.vial_location))
127
+ val=row.vial_location.value))
89
128
  if row.method:
90
- self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=SEQUENCE_TABLE.register,
91
- table_name=SEQUENCE_TABLE.name,
129
+ possible_path = os.path.join(self.method_dir, row.method)
130
+ method = row.method
131
+ if os.path.exists(possible_path):
132
+ method = os.path.join(self.method_dir, row.method)
133
+ self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=table_register,
134
+ table_name=table_name,
92
135
  row=row_num,
93
136
  col_name=RegisterFlag.METHOD,
94
- val=row.method))
137
+ val=method))
95
138
 
96
139
  if row.num_inj:
97
- self.sleepy_send(TableOperation.EDIT_ROW_VAL.value.format(register=SEQUENCE_TABLE.register,
98
- table_name=SEQUENCE_TABLE.name,
140
+ self.sleepy_send(TableOperation.EDIT_ROW_VAL.value.format(register=table_register,
141
+ table_name=table_name,
99
142
  row=row_num,
100
143
  col_name=RegisterFlag.NUM_INJ,
101
144
  val=row.num_inj))
102
145
 
103
146
  if row.inj_vol:
104
- self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=SEQUENCE_TABLE.register,
105
- table_name=SEQUENCE_TABLE.name,
147
+ self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=table_register,
148
+ table_name=table_name,
106
149
  row=row_num,
107
150
  col_name=RegisterFlag.INJ_VOL,
108
151
  val=row.inj_vol))
109
152
 
110
153
  if row.inj_source:
111
- self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=SEQUENCE_TABLE.register,
112
- table_name=SEQUENCE_TABLE.name,
154
+ self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=table_register,
155
+ table_name=table_name,
113
156
  row=row_num,
114
157
  col_name=RegisterFlag.INJ_SOR,
115
158
  val=row.inj_source.value))
116
159
 
117
160
  if row.sample_name:
118
- self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=SEQUENCE_TABLE.register,
119
- table_name=SEQUENCE_TABLE.name,
161
+ self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=table_register,
162
+ table_name=table_name,
120
163
  row=row_num,
121
164
  col_name=RegisterFlag.NAME,
122
165
  val=row.sample_name))
123
- self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=SEQUENCE_TABLE.register,
124
- table_name=SEQUENCE_TABLE.name,
166
+ self.sleepy_send(TableOperation.EDIT_ROW_TEXT.value.format(register=table_register,
167
+ table_name=table_name,
125
168
  row=row_num,
126
169
  col_name=RegisterFlag.DATA_FILE,
127
170
  val=row.sample_name))
128
171
  if row.sample_type:
129
- self.sleepy_send(TableOperation.EDIT_ROW_VAL.value.format(register=SEQUENCE_TABLE.register,
130
- table_name=SEQUENCE_TABLE.name,
172
+ self.sleepy_send(TableOperation.EDIT_ROW_VAL.value.format(register=table_register,
173
+ table_name=table_name,
131
174
  row=row_num,
132
175
  col_name=RegisterFlag.SAMPLE_TYPE,
133
176
  val=row.sample_type.value))
134
177
 
178
+ self.send(Command.SAVE_SEQUENCE_CMD)
179
+
135
180
  def run(self, sequence_table: SequenceTable):
136
181
  """
137
182
  Starts the currently loaded sequence, storing data
@@ -142,29 +187,31 @@ class SequenceController(TableController):
142
187
  """
143
188
  timestamp = time.strftime(SEQUENCE_TIME_FORMAT)
144
189
  self.send(Command.RUN_SEQUENCE_CMD.value)
145
- folder_name = f"{sequence_table.name} {timestamp}"
146
- subdirs = [x[0] for x in os.walk(self.data_dir)]
147
- time.sleep(10)
148
- potential_folders = sorted(list(filter(lambda d: folder_name in d, subdirs)))
149
- parent_folder = potential_folders[0]
150
- self.data_files.append(SequenceDataFiles(
151
- sequence_name=sequence_table.name,
152
- dir=parent_folder,
153
- child_dirs=[r.sample_name + ".D" for r in sequence_table.rows]))
190
+
191
+ if self.check_hplc_is_running():
192
+ folder_name = f"{sequence_table.name} {timestamp}"
193
+ self.data_files.append(SequenceDataFiles(dir=folder_name,
194
+ sequence_name=sequence_table.name, ))
195
+
196
+ run_completed = self.check_hplc_done_running()
197
+
198
+ if run_completed.is_ok():
199
+ self.data_files[-1].dir = run_completed.value
200
+ else:
201
+ raise RuntimeError("Run error has occured.")
154
202
 
155
203
  def retrieve_recent_data_files(self):
156
204
  sequence_data_files: SequenceDataFiles = self.data_files[-1]
157
205
  return os.path.join(sequence_data_files.dir, sequence_data_files.child_dirs[-1])
158
206
 
159
- def get_data(self) -> tuple[bool, Any]:
160
- data_ready = self.data_ready()
207
+ def get_data(self) -> list[dict[str, AgilentHPLCChromatogram]]:
161
208
  sequence_data_files: SequenceDataFiles = self.data_files[-1]
209
+ subdirs = [x[0] for x in os.walk(self.data_dir)]
210
+ potential_folders = sorted(list(filter(lambda d: sequence_data_files.dir in d, subdirs)))
211
+ self.data_files[-1].child_dirs = potential_folders
162
212
  spectra: list[dict[str, AgilentHPLCChromatogram]] = []
163
- if data_ready:
164
- for row in sequence_data_files.child_dirs:
165
- data_path = os.path.join(sequence_data_files.dir, row)
166
- self.get_spectrum(data_path)
167
- spectra.append(deepcopy(self.spectra))
168
- return data_ready, spectra
169
- else:
170
- return False, None
213
+ for row in sequence_data_files.child_dirs:
214
+ data_path = os.path.join(sequence_data_files.dir, row)
215
+ self.get_spectrum(data_path)
216
+ spectra.append(deepcopy(self.spectra))
217
+ return spectra
@@ -9,10 +9,11 @@ import os
9
9
  from typing import Union, Optional
10
10
 
11
11
  import polling
12
+ from result import Result, Ok, Err
12
13
 
13
14
  from ...control import CommunicationController
14
15
  from ...utils.chromatogram import AgilentHPLCChromatogram
15
- from ...utils.macro import Command
16
+ from ...utils.macro import Command, HPLCRunningStatus, Response
16
17
  from ...utils.method_types import MethodTimetable
17
18
  from ...utils.sequence_types import SequenceDataFiles
18
19
  from ...utils.table_types import Table, TableOperation, RegisterFlag
@@ -20,8 +21,10 @@ from ...utils.table_types import Table, TableOperation, RegisterFlag
20
21
 
21
22
  class TableController(abc.ABC):
22
23
 
23
- def __init__(self, controller: CommunicationController, src: str, data_dir: str):
24
+ def __init__(self, controller: CommunicationController, src: str, data_dir: str, table: Table):
24
25
  self.controller = controller
26
+ self.table = table
27
+
25
28
  if os.path.isdir(src):
26
29
  self.src: str = src
27
30
  else:
@@ -32,7 +35,7 @@ class TableController(abc.ABC):
32
35
  else:
33
36
  raise FileNotFoundError(f"dir: {data_dir} not found.")
34
37
 
35
- self.spectra = {
38
+ self.spectra: dict[str, AgilentHPLCChromatogram] = {
36
39
  "A": AgilentHPLCChromatogram(self.data_dir),
37
40
  "B": AgilentHPLCChromatogram(self.data_dir),
38
41
  "C": AgilentHPLCChromatogram(self.data_dir),
@@ -41,8 +44,13 @@ class TableController(abc.ABC):
41
44
 
42
45
  self.data_files: Union[list[SequenceDataFiles], list[str]] = []
43
46
 
44
- def receive(self):
45
- return self.controller.receive()
47
+ def receive(self) -> Result[Response, str]:
48
+ for _ in range(10):
49
+ try:
50
+ return self.controller.receive()
51
+ except IndexError:
52
+ continue
53
+ return Err("Could not parse response")
46
54
 
47
55
  def send(self, cmd: Union[Command, str]):
48
56
  self.controller.send(cmd)
@@ -58,7 +66,23 @@ class TableController(abc.ABC):
58
66
  """
59
67
  self.send(Command.SLEEP_CMD.value.format(seconds=seconds))
60
68
 
61
- def add_table_row(self, table: Table):
69
+ def get_num(self, row: int, col_name: RegisterFlag) -> float:
70
+ return self.controller.get_num_val(TableOperation.GET_ROW_VAL.value.format(register=self.table.register,
71
+ table_name=self.table.name,
72
+ row=row,
73
+ col_name=col_name.value))
74
+
75
+ def get_text(self, row: int, col_name: RegisterFlag) -> str:
76
+ return self.controller.get_text_val(TableOperation.GET_ROW_TEXT.value.format(register=self.table.register,
77
+ table_name=self.table.name,
78
+ row=row,
79
+ col_name=col_name.value))
80
+
81
+ @abc.abstractmethod
82
+ def get_row(self, row: int):
83
+ pass
84
+
85
+ def add_row(self):
62
86
  """
63
87
  Adds a row to the provided table for currently loaded method or sequence.
64
88
  Import either the SEQUENCE_TABLE or METHOD_TIMETABLE from hein_analytical_control.constants.
@@ -66,10 +90,10 @@ class TableController(abc.ABC):
66
90
 
67
91
  :param table: the table to add a new row to
68
92
  """
69
- self.sleepy_send(TableOperation.NEW_ROW.value.format(register=table.register,
70
- table_name=table.name))
93
+ self.sleepy_send(TableOperation.NEW_ROW.value.format(register=self.table.register,
94
+ table_name=self.table.name))
71
95
 
72
- def delete_table(self, table: Table):
96
+ def delete_table(self):
73
97
  """
74
98
  Deletes the table for the current loaded method or sequence.
75
99
  Import either the SEQUENCE_TABLE or METHOD_TIMETABLE from hein_analytical_control.constants.
@@ -77,46 +101,62 @@ class TableController(abc.ABC):
77
101
 
78
102
  :param table: the table to delete
79
103
  """
80
- self.sleepy_send(TableOperation.DELETE_TABLE.value.format(register=table.register,
81
- table_name=table.name))
104
+ self.sleepy_send(TableOperation.DELETE_TABLE.value.format(register=self.table.register,
105
+ table_name=self.table.name))
82
106
 
83
- def new_table(self, table: Table):
107
+ def new_table(self):
84
108
  """
85
109
  Creates the table for the currently loaded method or sequence. Import either the SEQUENCE_TABLE or
86
110
  METHOD_TIMETABLE from hein_analytical_control.constants. You can also provide your own table.
87
111
 
88
112
  :param table: the table to create
89
113
  """
90
- self.send(TableOperation.CREATE_TABLE.value.format(register=table.register,
91
- table_name=table.name))
92
-
93
- def _get_table_rows(self, table: Table) -> str:
94
- self.send(TableOperation.GET_OBJ_HDR_VAL.value.format(internal_val="Rows",
95
- register=table.register,
96
- table_name=table.name,
97
- col_name=RegisterFlag.NUM_ROWS, ))
114
+ self.send(TableOperation.CREATE_TABLE.value.format(register=self.table.register,
115
+ table_name=self.table.name))
116
+
117
+ def get_num_rows(self) -> Result[int, str]:
118
+ self.send(TableOperation.GET_NUM_ROWS.value.format(register=self.table.register,
119
+ table_name=self.table.name,
120
+ col_name=RegisterFlag.NUM_ROWS))
121
+ self.send(Command.GET_ROWS_CMD.value.format(register=self.table.register,
122
+ table_name=self.table.name,
123
+ col_name=RegisterFlag.NUM_ROWS))
98
124
  res = self.controller.receive()
99
- self.send("Sleep 1")
100
- self.send('Print Rows')
101
- return res
102
125
 
103
- def check_hplc_ready_with_data(self, method: Optional[MethodTimetable] = None) -> bool:
126
+ if res.is_ok():
127
+ self.send("Sleep 1")
128
+ self.send('Print Rows')
129
+ return res
130
+ else:
131
+ return Err("No rows could be read.")
132
+
133
+ def check_hplc_is_running(self) -> bool:
134
+ started_running = polling.poll(
135
+ lambda: isinstance(self.controller.get_status(), HPLCRunningStatus),
136
+ step=30,
137
+ max_tries=10)
138
+ return started_running
139
+
140
+ def check_hplc_done_running(self, method: Optional[MethodTimetable] = None) -> Result[str, str]:
104
141
  """
105
- Checks if ChemStation has finished writing data and can be read back.
142
+ Checks if ChemStation has finished running and can read data back
106
143
 
107
144
  :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
108
145
  :return: Return True if data can be read back, else False.
109
146
  """
110
- self.controller.set_status()
111
-
112
- timeout = 10 * 60
113
- hplc_run_done = polling.poll(
114
- lambda: self.controller.check_data(self.retrieve_recent_data_files()),
147
+ timeout = 10 * 60 if method is None else (method.first_row.maximum_run_time + 2) * 60
148
+ most_recent_folder = self.retrieve_recent_data_files()
149
+ finished_run = polling.poll(
150
+ lambda: self.controller.check_if_running(most_recent_folder),
115
151
  timeout=timeout,
116
152
  step=30
117
153
  )
118
-
119
- return hplc_run_done
154
+ if finished_run:
155
+ subdirs = [x[0] for x in os.walk(self.data_dir)]
156
+ potential_folders = sorted(list(filter(lambda d: most_recent_folder in d, subdirs)))
157
+ return Ok(potential_folders[0])
158
+ else:
159
+ return Err("Run did not complete as expected")
120
160
 
121
161
  @abc.abstractmethod
122
162
  def retrieve_recent_data_files(self):
@@ -132,6 +172,3 @@ class TableController(abc.ABC):
132
172
  """
133
173
  for channel, spec in self.spectra.items():
134
174
  spec.load_spectrum(data_path=data_file, channel=channel)
135
-
136
- def data_ready(self) -> bool:
137
- return self.check_hplc_ready_with_data()
@@ -1,5 +1,12 @@
1
1
  from enum import Enum
2
2
  from typing import Union
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass
7
+ class Response:
8
+ string_response: str
9
+ num_response: Union[int, float]
3
10
 
4
11
 
5
12
  # Commands sent to the Chemstation Macro
@@ -8,6 +15,8 @@ class Command(Enum):
8
15
  def __str__(self):
9
16
  return '%s' % self.value
10
17
 
18
+ GET_NUM_VAL_CMD = "response_num = {cmd}"
19
+ GET_TEXT_VAL_CMD = "response$ = {cmd}"
11
20
  RESET_COUNTER_CMD = "last_cmd_no = 0"
12
21
  GET_STATUS_CMD = "response$ = AcqStatus$"
13
22
  SLEEP_CMD = "Sleep {seconds}"
@@ -19,6 +28,7 @@ class Command(Enum):
19
28
  PUMP_ON_CMD = "PumpAll ON"
20
29
  PUMP_OFF_CMD = "PumpAll OFF"
21
30
  GET_METHOD_CMD = "response$ = _MethFile$"
31
+ GET_ROWS_CMD = 'response_num = TabHdrVal({register}, "{table_name}", "{col_name}")'
22
32
  SWITCH_METHOD_CMD = 'LoadMethod "{method_dir}", "{method_name}.M"'
23
33
  START_METHOD_CMD = "StartMethod"
24
34
  RUN_METHOD_CMD = 'RunMethod "{data_dir}",, "{experiment_name}_{timestamp}"'
@@ -26,7 +36,7 @@ class Command(Enum):
26
36
  UPDATE_METHOD_CMD = 'UpdateMethod'
27
37
  SWITCH_SEQUENCE_CMD = 'LoadSequence _SeqPath$, _SeqFile$'
28
38
  SAVE_SEQUENCE_CMD = 'SaveSequence _SeqPath$, _SeqFile$'
29
- SAVE_METHOD_CMD = 'SaveMethod _MethPath$, _MethFile$, {commit_msg}'
39
+ SAVE_METHOD_CMD = 'SaveMethod _MethPath$, _MethFile$, "{commit_msg}"'
30
40
  GET_SEQUENCE_CMD = 'response$ = _SeqFile$'
31
41
  RUN_SEQUENCE_CMD = 'RunSequence'
32
42
 
@@ -22,7 +22,6 @@ class Param:
22
22
  class HPLCMethodParams:
23
23
  organic_modifier: int
24
24
  flow: float
25
- temperature: float
26
25
  maximum_run_time: int
27
26
 
28
27
 
@@ -30,7 +29,7 @@ class HPLCMethodParams:
30
29
  class TimeTableEntry:
31
30
  start_time: float
32
31
  organic_modifer: float
33
- flow: float
32
+ flow: Optional[float] = None
34
33
 
35
34
 
36
35
  @dataclass
@@ -1,19 +1,17 @@
1
+ from __future__ import annotations
2
+
1
3
  from dataclasses import dataclass
2
4
  from enum import Enum
3
- from typing import Optional
4
-
5
+ from typing import Optional, Union
5
6
 
6
- @dataclass
7
- class TrayLocation:
8
- row: str
9
- col: int
7
+ from pychemstation.utils.tray_types import TenColumn
10
8
 
11
9
 
12
10
  @dataclass
13
11
  class SequenceDataFiles:
14
12
  sequence_name: str
15
13
  dir: str
16
- child_dirs: list[str]
14
+ child_dirs: Optional[list[str]] = None
17
15
 
18
16
 
19
17
  class SampleType(Enum):
@@ -22,6 +20,10 @@ class SampleType(Enum):
22
20
  CALIBRATION = 3
23
21
  CONTROL = 4
24
22
 
23
+ @classmethod
24
+ def _missing_(cls, value):
25
+ return cls.SAMPLE
26
+
25
27
 
26
28
  class InjectionSource(Enum):
27
29
  AS_METHOD = "As Method"
@@ -29,11 +31,15 @@ class InjectionSource(Enum):
29
31
  MSD = "MSD"
30
32
  HIP_ALS = "HipAls"
31
33
 
34
+ @classmethod
35
+ def _missing_(cls, value):
36
+ return cls.HIP_ALS
37
+
32
38
 
33
39
  @dataclass
34
40
  class SequenceEntry:
35
41
  sample_name: str
36
- vial_location: int
42
+ vial_location: Union[TenColumn, int]
37
43
  method: Optional[str] = None
38
44
  num_inj: Optional[int] = 1
39
45
  inj_vol: Optional[int] = 2
@@ -11,10 +11,11 @@ class TableOperation(Enum):
11
11
  NEW_ROW = 'InsTabRow {register}, "{table_name}"'
12
12
  EDIT_ROW_VAL = 'SetTabVal "{register}", "{table_name}", {row}, "{col_name}", {val}'
13
13
  EDIT_ROW_TEXT = 'SetTabText "{register}", "{table_name}", {row}, "{col_name}", "{val}"'
14
- GET_ROW_VAL = 'TabVal ("{register}", "{table_name}", {row}, "{col_name}")'
15
- GET_ROW_TEXT = 'TabText ("{register}", "{table_name}", {row}, "{col_name}")'
16
- GET_OBJ_HDR_VAL = '{internal_val} = TabHdrVal({register}, "{table_name}", "{col_name}")'
17
- GET_OBJ_HDR_TEXT = ''
14
+ GET_ROW_VAL = 'TabVal("{register}", "{table_name}", {row}, "{col_name}")'
15
+ GET_ROW_TEXT = 'TabText$("{register}", "{table_name}", {row}, "{col_name}")'
16
+ GET_NUM_ROWS = 'Rows = TabHdrVal({register}, "{table_name}", "{col_name}")'
17
+ GET_OBJ_HDR_VAL = 'ObjHdrVal("{register}", "{register_flag}")'
18
+ GET_OBJ_HDR_TEXT = 'ObjHdrText$("{register}", "{register_flag}")'
18
19
  UPDATE_OBJ_HDR_VAL = 'SetObjHdrVal {register}, {register_flag}, {val}'
19
20
  UPDATE_OBJ_HDR_TEXT = 'SetObjHdrText {register}, {register_flag}, {val}'
20
21
  NEW_COL_TEXT = 'NewColText {register}, "{table_name}", "{col_name}", "{val}"'
@@ -39,6 +40,8 @@ class RegisterFlag(Enum):
39
40
  COLUMN_OVEN_TEMP2 = "TemperatureControl2_Temperature"
40
41
  STOPTIME_MODE = "StopTime_Mode"
41
42
  POSTIME_MODE = "PostTime_Mode"
43
+ TIME = "Time"
44
+ TIMETABLE_SOLVENT_B_COMPOSITION = "SolventCompositionPumpChannel2_Percentage"
42
45
 
43
46
  # for Method Timetable
44
47
  SOLVENT_COMPOSITION = "SolventComposition"
@@ -0,0 +1,14 @@
1
+ from enum import Enum
2
+
3
+
4
+ class TenColumn(Enum):
5
+ ONE = 1
6
+ TWO = 2
7
+ THREE = 3
8
+ FOUR = 4
9
+ FIVE = 5
10
+ SIX = 6
11
+ SEVEN = 7
12
+ EIGHT = 8
13
+ NINE = 9
14
+ TEN = 10
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pychemstation
3
- Version: 0.5.1
3
+ Version: 0.5.3.dev1
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
@@ -0,0 +1,34 @@
1
+ pychemstation/__init__.py,sha256=SpTl-Tg1B1HTyjNOE-8ue-N2wGnXN_2zl7RFUSxlkiM,33
2
+ pychemstation/analysis/__init__.py,sha256=EWoU47iyn9xGS-b44zK9eq50bSjOV4AC5dvt420YMI4,44
3
+ pychemstation/analysis/base_spectrum.py,sha256=FBvwzLtF9mdqW7f8ETY9G4cpfJ-SzbiSkZq9EtXcSXo,17045
4
+ pychemstation/analysis/spec_utils.py,sha256=8NZMV0dtfxZLARjWzM5ks0tgEYQv_SKUiZzba2IoKgw,10505
5
+ pychemstation/analysis/utils.py,sha256=ISupAOb_yqA4_DZRK9v18UL-XjUQccAicIJKb1VMnGg,2055
6
+ pychemstation/control/__init__.py,sha256=aH9cPf-ljrVeVhN0K3cyEcAavmPXCjhhOnpLNf8qLqE,106
7
+ pychemstation/control/comm.py,sha256=19RaKugJ7TbBfW-OM8fHxf90cfXCiDnNnZWPAOiWpGQ,7266
8
+ pychemstation/control/hplc.py,sha256=r1N8kf5o1kAoY1taALvLJoIxNEbuOYsjwZ8eljrMZRM,6763
9
+ pychemstation/control/table/__init__.py,sha256=RgMN4uIWHdNUHpGRBWdzmzAbk7XEKl6Y-qtqWCxzSZU,124
10
+ pychemstation/control/table/method.py,sha256=THVoGomSXff_CTU3eAYme0BYwkPzab5UgZKsiZ29QSk,12196
11
+ pychemstation/control/table/sequence.py,sha256=iTpk1oiGByut7MSFDHKpTlKUCYzXENOB6EMSKaWJWVY,10651
12
+ pychemstation/control/table/table_controller.py,sha256=eq9P213Jslr1gJnjZEuvyQ4TpgrxdIXFXHwtQbJkrg0,7131
13
+ pychemstation/generated/__init__.py,sha256=GAoZFAYbPVEJDkcOw3e1rgOqd7TCW0HyKNPM8OMehMg,1005
14
+ pychemstation/generated/dad_method.py,sha256=0W8Z5WDtF5jpIcudMqb7XrkTnR2EGg_QOCsHRFQ0rmM,8402
15
+ pychemstation/generated/pump_method.py,sha256=sUhE2Oo00nzVcoONtq3EMWsN4wLSryXbG8f3EeViWKg,12174
16
+ pychemstation/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ pychemstation/utils/chromatogram.py,sha256=35nvEh6prVsWO6lMHYgGuidUOFHv954_7MNf0Az3Fz4,3759
18
+ pychemstation/utils/macro.py,sha256=BAIcE_dppNffwrSqGq8gh0ccE9YAJfQFQZHXJgA1WtA,2586
19
+ pychemstation/utils/method_types.py,sha256=YngbyHg96JSFnvhm5Zd7wJvLTQPPQsLbvbyz3HlGLYY,862
20
+ pychemstation/utils/parsing.py,sha256=bnFIsZZwFy9NKzVUf517yN-ogzQbm0hp_aho3KUD6Is,9317
21
+ pychemstation/utils/sequence_types.py,sha256=3VqiUHsfFEdynAxfR-z8JIWBCo7PdnGwTvsk7sm7Ij8,1055
22
+ pychemstation/utils/table_types.py,sha256=HAxAsqmyWsCqGwhg4LadGlX6ubacsd8tjXXz-6DL2nI,2287
23
+ pychemstation/utils/tray_types.py,sha256=UUDED-IAf-8FmPVZezuWSiIQE_HgiZQMV2sTqu4oZw8,177
24
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ tests/constants.py,sha256=CqahQtWK0NSGIpoCOY_uoN4BwR6TFtaX9wPAkPkG9BE,2074
26
+ tests/test_comb.py,sha256=IrCqsGEBdrAqoGBQuKiJiaGRW9Ym9UNlVjPA9gc2UrA,5431
27
+ tests/test_comm.py,sha256=1ZZd0UrIBOKe91wzA-XI-gSRgXmId9mLWYSMeche82Y,2973
28
+ tests/test_method.py,sha256=uCPpZVYKPz1CNWwhmBo_8TH0ku2V0ZpDZJj3f8iINB4,2440
29
+ tests/test_sequence.py,sha256=w_WQj97hlaZtcW1Zibzlrq0p179c-4-otM-ik_1EXME,2937
30
+ pychemstation-0.5.3.dev1.dist-info/LICENSE,sha256=9bdF75gIf1MecZ7oymqWgJREVz7McXPG-mjqrTmzzD8,18658
31
+ pychemstation-0.5.3.dev1.dist-info/METADATA,sha256=YIbggvShXX-YxNtMFlMXfJIIB0LanjwtYBLz7O5Ttdw,3964
32
+ pychemstation-0.5.3.dev1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
33
+ pychemstation-0.5.3.dev1.dist-info/top_level.txt,sha256=zXfKu_4nYWwPHo3OsuhshMNC3SPkcoTGCyODjURaghY,20
34
+ pychemstation-0.5.3.dev1.dist-info/RECORD,,